Skip to content

Aquapath

Christian edited this page Sep 29, 2026 · 4 revisions

The Aquapath V1 keeps two independent water reservoirs (left and right) at a target temperature, each with its own pump, heating element, fan cooler and AS006 flow/temperature probe.

Machine ID 9
Schema aquapath_v1.yaml
Code aquapath/

In the tables below, <side> stands for left or right: every reservoir setting exists once per side.

Hardware

Role Terminal Purpose
0 EK1100 Bus coupler
1 EL2008 Pump, heating and cooling relays (DO1–4 left, DO5–8 right; DO3 and DO7 unused)
2 EL4002 Fan speed, 0–10 V (AO1 left, AO2 right)
3 EL3024 AS006 flow and temperature probes (AI1–2 left, AI3–4 right)

The AS006 maps 4–20 mA to 0–15 l/min and −25–125 °C. Roles are assigned in Identification.

How it works

Each reservoir runs the same controller. The rule it exists to enforce: never heat without proven flow, and keep the water moving until the heat has been carried away.

flowchart LR
  subgraph TEMP["Temperature"]
    TS["AS006 temperature<br/>EL3024"]:::hardware
    D["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/mod.rs'>Demand</a><br/>target vs. actual"]:::control
    H["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/heater.rs'>Heater</a><br/><a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control_core/src/controllers/pid.rs'>PID</a> duty, 12 s PWM<br/>only with proven flow"]:::control
    C["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/cooling.rs'>Cooling</a><br/>fan ramp: Low, Ramp, Max<br/>only with flow"]:::control
    HR["Heating relay EL2008"]:::hardware
    CR["Cooling relay EL2008<br/>fan speed EL4002"]:::hardware
    TS --> D
    D -- "too cold" --> H
    D -- "too warm" --> C
    H --> HR
    C --> CR
  end
  subgraph FLOW["Flow"]
    FS["AS006 flow<br/>EL3024"]:::hardware
    P["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/pump.rs'>Pump controller</a><br/>priming, low-flow trip,<br/>after-run"]:::control
    PR["Pump relay EL2008"]:::hardware
    FS --> P --> PR
  end
  FLOW -- "flow state" --> TEMP

  classDef frontend fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  classDef control fill:#dcfce7,stroke:#15803d,color:#14532d
  classDef framework fill:#fef3c7,stroke:#b45309,color:#78350f
  classDef lib fill:#ede9fe,stroke:#6d28d9,color:#4c1d95
  classDef hardware fill:#f1f5f9,stroke:#475569,color:#0f172a
Loading

Controllers

Defaults marked fixed are constants in controller/config.rs and can't be changed at runtime. The other parameters are config properties. Config writes outside the listed range are rejected; the controller additionally clamps some values, as noted.

Reservoir controller

Controller (controller/mod.rs) computes the error target − actual and picks the demand:

  • Heat if the error is above the heating tolerance,
  • Cool if the water is warmer than target plus the cooling tolerance,
  • Hold otherwise (deadband).

The minimum settable target is the ambient calibration, limited to 10–80 °C: the loop can't cool below ambient. Changing the ambient calibration raises any target below the new minimum.

Parameter Unit Default Description
Target temperature
<side>_target_temperature
°C 25 Control tab, Set Target Temperature. Config accepts 0–80; the controller clamps the value to the minimum settable target…80 °C.
Ambient temperature calibration
ambient_temperature_calibration
°C 22 Config tab, Ambient Calibration. Shared by both sides, clamped to 10–80 °C (the UI offers 10–40). Use Current Sensor Temp takes the lower of the two reservoir temperatures and is only enabled below 30 °C.
Heating tolerance
<side>_tolerance_config.heating
°C 0.4 Heat when the water is more than this below target. Clamped to 0–10.
Cooling tolerance
<side>_tolerance_config.cooling
°C 0.8 Cool when the water is more than this above target. Clamped to 0–10.
Minimum temperature °C 10 Fixed. Below it, running cooling is cut. Also the lower limit of the settable target.
Maximum temperature °C 80 Fixed. Above it, a running heater is cut. Also the upper limit of the target.

Writing a target temperature, a tolerance or a PID gain resets that side's PID state and PWM window and queues a Thermal Control Reset notice.

Heater

HeaterController (controller/heater.rs) drives the heating relay:

  • The PID (pid.rs, plain update without anti-windup) turns the error into a duty cycle, clamped to 0–1.
  • The heater is on for duty × 12 s at the start of each 12 s PWM window.
  • If the error is 4 °C or more, the heater skips the duty cycle and runs continuously.
  • In the deadband the heater is switched off and the PID is reset, so the integral can't wind up.
  • The heater only runs with proven flow (see Pump); losing it cuts the heater in the same cycle.
  • Power is reported as 700 W while the relay is closed, 0 W otherwise. The energy is integrated in Wh (<side>_total_energy); the Control tab shows the sum of both sides in kWh. Both reset when the backend restarts.
Parameter Unit Default Description
Kp
<side>_pid_config.kp
– 0.16 Proportional gain (duty per °C of error). Clamped to 0–5.
Ki
<side>_pid_config.ki
– 0.02 Integral gain. Clamped to 0–5.
Kd
<side>_pid_config.kd
– 0.0 Derivative gain. Clamped to 0–5.
PWM period s 12 Fixed. Length of the duty-cycle window.
Full-power error °C 4 Fixed. From this error on, the heater runs continuously.
Heating element power W 700 Fixed. Nominal power used for the power and energy values; not measured.

The Reset to Default buttons on the Config tab write 0.16 / 0.02 / 0.0 for the PID and 0.4 / 0.8 for the tolerances.

Cooling

CoolingController (controller/cooling.rs) switches the cooling relay and sets the fan speed. It only runs when the demand is Cool, the machine is in Auto and flow is present (at least 0.2 l/min with the pump on). The fan is only driven once the relay has really closed; the relay dwell can delay that.

The fan speed follows how far the water is above target (actual − target):

Offset Mode Fan speed
below 2 °C Low Linear from the minimum fan speed (20) at 0.8 °C to 60 % of max at 2 °C
2–4 °C Ramp Linear from 60 % to 100 % of max
4 °C or more Max 100 % of max

When cooling stops, the fan is set to 0 and the mode becomes empty (null).

Parameter Unit Default Description
Max revolution speed
<side>_fan_max_revolutions
% 100 Config tab. Upper limit of the fan ramp, 0–100 (100 = 10 V at the EL4002). The Control tab shows the fan speed as a percentage of this value.
Ramp start °C 0.8 Fixed. Offset at which the Low segment starts from the minimum speed. It doesn't follow the configurable cooling tolerance.
Near band °C 2 Fixed. End of the Low segment.
Full band °C 4 Fixed. From here on, the fan runs at max.
Minimum fan speed % 20 Fixed. Start of the Low segment (limited to the max).

Pump

PumpController (controller/pump.rs) owns the pump relay, the flow probe and the flow timers:

  • Request: the Control tab's Pump switch sends pump.start_<side>_pump or pump.stop_<side>_pump. A change of the request resets the PID and PWM window.
  • Permission: the relay only closes when the pump is allowed. Entering Auto grants the permission; nothing withdraws it again.
  • Priming: the low-flow trip is armed 15 s after the pump relay closes.
  • Low-flow trip: if the flow then stays below 0.2 l/min for 5 s, the pump request is cleared (the switch falls back to Off) and a Pump Turned Off notice is queued.
  • Flow proven: once the flow is at least 0.2 l/min with the pump on, a timer starts. After the settle duration the flow counts as proven and the heater may run. Until then <side>_heating_startup_wait_active is true while the loop wants heat, and the Control tab shows Thermal Delay with the remaining time.
  • After-run: if the pump request is withdrawn (pump Off, or Standby) while the heater is on or was on within the settle duration, the pump keeps running for the settle duration (<side>_pump_cooldown_active, <side>_pump_cooldown_remaining).
Parameter Unit Default Description
Thermal safety delay
<side>_thermal_flow_settle_duration
s 10 Config tab, Thermal Safety Delay. How long flow must be present before heating, and how long the pump runs on after heating. 0–30. Only applied when written in Standby. The controller starts with 10 s; the config property itself defaults to 0 until it's written. The Config tab shows the value in effect.
Pump cooldown min temperature
<side>_pump_cooldown_min_temperature
°C 45 Config tab. 10–80, only applied when written in Standby. The controller starts with 45 °C; the config property defaults to 32. The value is stored and published, but the control loop doesn't evaluate it.
Minimum flow for thermal interlocks l/min 0.2 Fixed. Less flow counts as no flow.
Pump startup grace period s 15 Fixed. Priming time before the low-flow trip is armed.
Low-flow grace period s 5 Fixed. How long the flow may stay too low before the pump is stopped.

Dwell relays and I/O

controller/io.rs wraps the terminals:

  • Relay: one EL2008 output that remembers its last command. The pump uses a plain relay.
  • DwellRelay: the heating and cooling relays. After a switch, the relay holds its state for a minimum time, so the contacts don't chatter. Safety cut-offs (flow interlock, hard limits, Standby) use force_off, which ignores the dwell.
  • FanOutput: writes the fan value ÷ 10 to the EL4002.
  • FlowSensor and TemperatureSensor: one AS006 channel each on the EL3024; errors read as 0.
Parameter Unit Default Description
Relay minimum on time s 5 Fixed. A closed heating or cooling relay stays closed at least this long (except for safety cut-offs).
Relay minimum off time s 5 Fixed. An open relay stays open at least this long.

Timers

Timer (controller/timing.rs) is a restartable one-shot timer. The durations are passed in on every call, so settings changed at runtime apply immediately.

Timer Owner Starts Used for
running_since Pump Pump relay closes 15 s priming before the low-flow trip
low_flow_since Pump Flow drops below 0.2 l/min after priming 5 s low-flow grace period
flow_valid_since Pump Flow present with the pump on Flow proven after the settle duration
cooldown Pump Request withdrawn while the heater is recently active After-run for the settle duration
last_active Heater Every cycle the heater is on "Recently active" check for the after-run

Clone this wiki locally