{
 "manufacturer": "Wilo",
 "manufacturer_slug": "wilo",
 "model": "Stratos MAXO with CIF module Modbus RTU",
 "model_slug": "stratos-maxo",
 "short_model": "Stratos MAXO",
 "aliases": [
  "Wilo-Stratos MAXO",
  "Stratos MAXO-D",
  "Stratos MAXO-Z",
  "CIF-Module Modbus RTU",
  "CIF Modbus RTU 2190368",
  "CIF Modbus RTU UL 2237080"
 ],
 "equipment_type": "Pump (smart circulator)",
 "applies_to": "Wilo-Stratos MAXO single and twin-head circulators fitted with the plug-in CIF module Modbus RTU (article 2190368, UL 2237080), module firmware 1.00-99.99; some registers need a newer module version as noted.",
 "summary": "The Wilo Stratos MAXO is a smart wet-rotor circulator for heating, cooling and domestic hot water. Modbus RTU comes from a plug-in CIF module on RS-485. A master picks the setpoint source and control mode, writes a relative duty point in 0.5 % steps and switches the pump on, off or to MIN/MAX overrides; a bus command timer can lock the local menu and load fallback values if the bus goes quiet. Readings cover head, calculated flow, power, energy, speed, run hours, fluid temperatures, the heat/cold meter, status flags and the Wilo error code.",
 "transport": [
  "RTU"
 ],
 "defaults": {
  "unit_id": null,
  "baud": null,
  "parity": null,
  "data_bits": 8,
  "stop_bits": null,
  "tcp_port": null
 },
 "addressing": {
  "convention": "0-based",
  "note": "Wilo states that all register addresses are raw addresses as sent on the bus, so input register 700 is requested at address 700. Its example frame confirms it: 01 04 02 BC 00 01 reads input register 0x02BC = 700. Masters that number registers from 1 must use 701 (or 30701)."
 },
 "default_word_order": "ABCD",
 "firmware": "CIF module Modbus RTU 1.00-99.99 (individual registers from 3.00, 3.01, 3.02 or 5.01 as noted)",
 "source": {
  "title": "WILO Modbus RTU - CIF-Module installation and operating instructions with functional description and datapoint list",
  "doc_number": "wilo194406",
  "revision_date": "2026-07-15",
  "url": "https://cms.media.wilo.com/cdndoc/wilo194406/11516106/wilo194406.html",
  "pages": "HTML sections 6.1.4 (data types, 32-bit word order), 6.1.5 (error values), 6.1.7 (input selector), 6.2.6 (function codes, raw addressing), 6.2.7.3 holding registers, 6.2.7.4 input registers, 8.2.3-8.2.4 (baud and frame codes), 8.3 (Modbus functional test and example frame); linked from wilo.com > Building automation > Data points > Modbus"
 },
 "notes": [
  "Source is Wilo's public HTML document for all CIF modules, which marks every register and every enum/bit value with the pumps that support it. Only registers and values listed as supported by the Stratos MAXO are kept. Second, related Wilo document: Wilo-CIF-Module installation and operating instructions 2193854 Ed.02/2020-11, https://cms.media.wilo.com/cdndoc/wilo182202/5025204/wilo182202.pdf (wiring and terminators; no datapoint list). Facts are re-keyed in our own words and the documents are linked, not re-hosted.",
  "32-bit values (REAL and UDINT) are high word first (ABCD): Wilo puts the most significant 16 bits at the base address.",
  "Scale: physical value = raw x scale as in Wilo's list (pressure raw x 10 = cm H2O, operation time raw x 10 = h, flow raw x 0.1 = m³/h, duty point raw x 0.5 = %, temperatures raw x 0.1 = K).",
  "Temperatures are in kelvin, not °C: 2931 means 293.1 K = 20.0 °C.",
  "Error values: Wilo marks an unavailable or invalid reading with the largest positive value of the data type (e.g. 65535 for UINT, 32767 for INT).",
  "controlFunction lists every mode Wilo marks as supported on a Stratos MAXO; which modes a given pump accepts depends on its firmware and CPU variant (Wilo lists CPU_F4 and CPU_H5), and unsupported values are ignored. Values 69 and 70 are marked reserved and are left out.",
  "warning/errorMessage (I 940) lists only the codes Wilo marks as supported on the Stratos MAXO. The user trouble code (I 901, 74 Stratos MAXO codes) and the second error register I 950 are left out.",
  "Left out: aux parameter set H 412-415 and its readbacks I 222-262; PID tuning H 408-410; flow limits H 420-427 / I 270-281; temperature references H 302/H 304 and sensor signal H 306; analog input readings I 324-332; heat-meter start times I 306/I 310 (REAL seconds since 1970); system time I 502; identification I 700-718 (BCD-coded firmware, vendor/UUID words); double-pump total run time I 9; legacy Stratos registers H 44-47 and the partner-pump block I 65-102 (not marked for Stratos MAXO).",
  "Bits shown for the bit-field registers are those Wilo marks as supported on Stratos MAXO; bits not listed are static 0 (or unused) on this pump.",
  "Left out: I 212. Wilo names it 'pressure max-pres-value' (REAL, bar, module 5.01+) but describes it as the live pressure, so it is unclear whether it is the actual or the maximum pressure.",
  "Flow (I 2): for module versions up to 6.00 Wilo gives 9999 as its error value, not 65535."
 ],
 "registers": [
  {
   "table": "input_register",
   "address": 1,
   "documented": "1",
   "name": "pressure",
   "description": "Actual (differential) pressure; may be calculated.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 10,
   "scale_factor_ref": null,
   "units": "cm H2O",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 2,
   "documented": "2",
   "name": "flow",
   "description": "Calculated flow; not for closed-loop control.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "m³/h",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3,
   "documented": "3",
   "name": "energyConsumption",
   "description": "Total electrical energy consumed.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 4,
   "documented": "4",
   "name": "powerInput",
   "description": "Electrical input power.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 5,
   "documented": "5",
   "name": "operationTime",
   "description": "Total motor running time.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 10,
   "scale_factor_ref": null,
   "units": "h",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 7,
   "documented": "7",
   "name": "speed",
   "description": "Rotational speed.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "rpm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 8,
   "documented": "8",
   "name": "temperatureFluid@Device",
   "description": "Fluid temperature in kelvin (subtract 273.15 for °C).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "K",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 10,
   "documented": "10",
   "name": "controlFunction (active)",
   "description": "Control mode in use.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "1": "Gen_Spd (constant speed)",
    "3": "Gen_PHdConst (constant differential pressure)",
    "4": "Gen_PHdVar (variable differential pressure)",
    "9": "Gen_T (constant temperature)",
    "10": "Gen_TDiff (constant differential temperature)",
    "15": "INVALID",
    "16": "HeatRadiator_PHd",
    "17": "HeatRadiator_DA",
    "18": "HeatRadiator_T",
    "19": "HeatFloor_PHd",
    "20": "HeatFloor_DA",
    "21": "HeatFloor_T",
    "22": "HeatCeiling_PHd",
    "23": "HeatCeiling_DA",
    "24": "HeatCeiling_T",
    "25": "HeatFan_PHd",
    "26": "HeatFan_DA",
    "27": "HeatFan_T",
    "28": "HeatB._T",
    "29": "HeatB._TDiff",
    "30": "HeatB._Acc.Flow",
    "31": "HeatE._T",
    "32": "HeatE._TDiff",
    "33": "HeatE._Acc.Flow",
    "34": "Heat_PHdConst",
    "35": "Heat_PHdVar",
    "36": "Heat_PHdExt",
    "37": "Heat_DA",
    "38": "Heat_VolFlow",
    "39": "Heat_Acc.Flow",
    "40": "Heat_T",
    "41": "Heat_TDiff",
    "42": "Heat_Spd",
    "43": "CoolCeiling_PHd",
    "44": "CoolCeiling_DA",
    "45": "CoolCeiling_T",
    "46": "CoolFloor_PHd",
    "47": "CoolFloor_DA",
    "48": "CoolFloor_T",
    "49": "CoolFan_PHd",
    "50": "CoolFan_DA",
    "51": "CoolFan_T",
    "52": "CoolB._T",
    "53": "CoolB._TDiff",
    "54": "CoolB._Acc.Flow",
    "55": "CoolE._T",
    "56": "CoolE._TDiff",
    "57": "CoolE._Acc.Flow",
    "58": "Cool_PHdConst",
    "59": "Cool_PHdVar",
    "60": "Cool_PHdExt",
    "61": "Cool_DA",
    "62": "Cool_VolFlow",
    "63": "Cool_Acc.Flow",
    "64": "Cool_T",
    "65": "Cool_TDiff",
    "66": "Cool_Spd",
    "67": "San_Circ._T",
    "68": "SanW.Heat._TDiff",
    "71": "San_PHdConst",
    "72": "San_PHdVar",
    "73": "San_PHdExternal",
    "74": "San_VolFlow",
    "75": "San_Acc.Flow",
    "76": "San_T",
    "77": "San_TDiff",
    "78": "San_Spd",
    "79": "Gen_PHdExt",
    "80": "Gen_DA (Dynamic Adapt)",
    "81": "Gen_VolFlow (constant flow)",
    "82": "Gen_Acc.Flow",
    "83": "ScndPHdConst",
    "84": "ScndPHdVar",
    "85": "ScndFlow",
    "86": "ScndSpd",
    "140": "Gen_UsrDfd (user-defined PID)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 18,
   "documented": "18",
   "name": "speed max-pres-value",
   "description": "Maximum speed.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "rpm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 19,
   "documented": "19",
   "name": "speed min-pres-value",
   "description": "Minimum speed.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "rpm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 20,
   "documented": "20",
   "name": "pressureMaxPHdConst",
   "description": "Max pressure setpoint in dp-c; scales % back to head.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 10,
   "scale_factor_ref": null,
   "units": "cm H2O",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 21,
   "documented": "21",
   "name": "pressureMinPHdConst",
   "description": "Min pressure setpoint in dp-c.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 10,
   "scale_factor_ref": null,
   "units": "cm H2O",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 22,
   "documented": "22",
   "name": "pressureMaxPHdVar",
   "description": "Max pressure setpoint in dp-v.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 10,
   "scale_factor_ref": null,
   "units": "cm H2O",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 23,
   "documented": "23",
   "name": "pressureMinPHdVar",
   "description": "Min pressure setpoint in dp-v.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 10,
   "scale_factor_ref": null,
   "units": "cm H2O",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 24,
   "documented": "24",
   "name": "flow max-pres-value",
   "description": "Maximum (calculated) flow.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "m³/h",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 25,
   "documented": "25",
   "name": "flow min-pres-value",
   "description": "Minimum (calculated) flow.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "m³/h",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 28,
   "documented": "28",
   "name": "powerInput max-pres-value",
   "description": "Maximum electrical input power.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 35,
   "documented": "35",
   "name": "Service Message",
   "description": "Legacy register.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "Service required"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 36,
   "documented": "36",
   "name": "Error Type",
   "description": "Legacy register; prefer I 940 for new work.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "Electronic module error",
    "1": "Motor error",
    "3": "Error present (restart will be retried)",
    "4": "Supply voltage error"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 37,
   "documented": "37",
   "name": "Error Message",
   "description": "Legacy detailed error flags.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "Undervoltage",
    "1": "Overvoltage",
    "2": "Supply phase fault",
    "3": "Idle running (e.g. air in system)",
    "8": "Motor overheated",
    "9": "Motor error",
    "10": "Pump blocked",
    "11": "Module overheated",
    "12": "Module warning",
    "13": "Module error",
    "14": "Sensor malfunction"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 38,
   "documented": "38",
   "name": "Pump Status",
   "description": "Legacy controller status flags.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "On command",
    "2": "Setpoint not reached",
    "3": "Override OFF",
    "4": "Configured as double pump",
    "5": "Local operation overrides bus",
    "6": "Flow / head values invalid",
    "7": "Override MIN",
    "12": "Setpoint comes from outside, not this bus (module 5.00+)"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 39,
   "documented": "39",
   "name": "State Diagnostics",
   "description": "Legacy diagnostic flags.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "Error present",
    "1": "Supply voltage error",
    "3": "Speed at low regulation limit",
    "4": "Speed at high regulation limit",
    "6": "Setpoint out of range",
    "8": "Local operation overrides bus",
    "10": "On command"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 200,
   "documented": "200",
   "name": "dutyPointRel (active)",
   "description": "Setpoint the pump is actually using (200 = 100 %).",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.5,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 202,
   "documented": "202",
   "name": "dutyPointRel maximum-output",
   "description": "Upper limit of the active setpoint.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.5,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 204,
   "documented": "204",
   "name": "dutyPointRel minimum-output",
   "description": "Lower limit; lower writes are limited to it.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.5,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 206,
   "documented": "206",
   "name": "dutyPoint100%Val",
   "description": "Engineering value at 100 % in the current mode; unit in I 208.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 208,
   "documented": "208",
   "name": "dutyPointRel units",
   "description": "Unit code for I 206.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "5": "V",
    "19": "kWh",
    "47": "W",
    "55": "bar",
    "62": "Cel",
    "63": "K",
    "73": "s",
    "80": "m3",
    "95": "{noUnit}",
    "104": "min-1",
    "135": "m3/h"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 210,
   "documented": "210",
   "name": "setpointSignalSource (active)",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "1": "CIF module (bus)",
    "6": "Internal",
    "7": "EXT 1",
    "8": "EXT 2",
    "9": "INVALID"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 211,
   "documented": "211",
   "name": "parameterSetSelector (active)",
   "description": "Parameter set in use (module 3.01+).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "1": "norm (normal set)",
    "2": "aux (auxiliary set)",
    "3": "preset (fallback set)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 300,
   "documented": "300",
   "name": "powerHeating",
   "description": "Heating power in the measured circuit.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 302,
   "documented": "302",
   "name": "powerRefrigeration",
   "description": "Cooling power in the measured circuit.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 304,
   "documented": "304",
   "name": "energyHeatRrst.able",
   "description": "Resettable heating energy (reset may not be possible via bus).",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 308,
   "documented": "308",
   "name": "energyRefrigRrst.able",
   "description": "Resettable cooling energy.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 312,
   "documented": "312",
   "name": "energyHeat.Total",
   "description": "Total heating energy, not resettable.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 314,
   "documented": "314",
   "name": "energyRefrig.Total",
   "description": "Total cooling energy, not resettable.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 316,
   "documented": "316",
   "name": "temperat.FluidFwd",
   "description": "Forward (supply) temperature in kelvin.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "K",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 318,
   "documented": "318",
   "name": "temperat.FluidRet",
   "description": "Return temperature in kelvin.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "K",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 320,
   "documented": "320",
   "name": "voltageInput",
   "description": "Mains input voltage.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 400,
   "documented": "400",
   "name": "dutyPointRel (output)",
   "description": "Actual duty point reached (200 = 100 %).",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.5,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 402,
   "documented": "402",
   "name": "Pump Command active",
   "description": "Command currently in effect.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "Pump on",
    "1": "Override MIN",
    "2": "Override MAX",
    "3": "Static 1",
    "4": "Override OFF",
    "5": "Override ON",
    "8": "Auto setback / night mode"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 403,
   "documented": "403",
   "name": "Pump Command out",
   "description": "",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "8": "Auto setback / night mode active"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 404,
   "documented": "404",
   "name": "Operation Status",
   "description": "Main run / warning / error flags.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": {
    "0": "Ready for operation",
    "1": "On command",
    "2": "Service required",
    "3": "Warning present",
    "4": "Error present (restart will be retried)",
    "5": "Final error (no restart)"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 500,
   "documented": "500",
   "name": "heartbeatCount",
   "description": "Counts pump-to-module heartbeats; resets on restart.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 504,
   "documented": "504",
   "name": "busCmd.TimerTimeRemain.",
   "description": "Seconds left before the bus command timer elapses (module 3.02+).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "s",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 940,
   "documented": "940",
   "name": "warning/errorMessage",
   "description": "Current Wilo warning/error code (E000-E255); 0 = none.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "E000 NO_ERROR - no error",
    "3": "E003 FLUID_TEMP_HI - fluid temperature too high",
    "4": "E004 MAINS_VOLT_LO - mains undervoltage",
    "5": "E005 MAINS_VOLT_HI - mains overvoltage",
    "6": "E006 MAINS_PHASE - mains phase missing",
    "7": "E007 PUMP_GENERATOR - generator operation (flow in pumping direction)",
    "9": "E009 PUMP_TURBINE - turbine operation",
    "10": "E010 PUMP_BLOCKED - rotor blocked",
    "11": "E011 PUMP_DRY_RUN - dry running",
    "25": "E025 MOT_OPEN_CIRC - motor / winding contact missing",
    "26": "E026 MOT_TEMP_SENS - winding temperature sensor open",
    "30": "E030 MOD_TEMP_HI - module overtemperature",
    "33": "E033 MOD_VOLT_DC_HI - DC link overvoltage",
    "42": "E042 SENS_IN1 - In1 signal open or shorted (2-10 V / 4-20 mA)",
    "43": "E043 SENS_IN2 - In2 signal open or shorted (2-10 V / 4-20 mA)",
    "50": "E050 COM_LOC_BIND - local interface / bus communication timeout",
    "51": "E051 COM_MP - invalid twin/multi-pump combination",
    "52": "E052 COM_MP_TIMEOUT - twin/multi-pump communication timeout",
    "54": "E054 COM_REM_BIND - binding partner missing on bus",
    "72": "E072 ELECT_POW - power section / converter",
    "77": "E077 ELECT_SUPP_24_I - 24 V supply for inputs faulty",
    "89": "E089 MOT_MOD_FAULT - motor or module fault",
    "97": "E097 SET_DATA_MISS - pump type data set missing",
    "100": "E100 CTRL_BATT - battery low",
    "104": "E104 CTRL_FAN_EXT - external motor fan faulty",
    "119": "E119 MCTL_TURBINE - turbine operation (flow against pumping direction)",
    "251": "E251 EXTENDED_WARN - extended code, warning bit set",
    "252": "E252 EXTENDED_ERR - extended code, error bit set",
    "255": "E255 INVALID - invalid"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1,
   "documented": "1",
   "name": "dutyPointRel",
   "description": "Setpoint in % of the mode's 100 % value (200 = 100 %).",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.5,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40,
   "documented": "40",
   "name": "Pump Command in",
   "description": "On/off and override command; bit 3 must be 1 on every write.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": null,
   "bits": {
    "0": "Pump on",
    "1": "Override MIN",
    "2": "Override MAX",
    "3": "Always 1 when writing",
    "4": "Override OFF (module 3.00+)",
    "5": "Override ON (module 3.00+)",
    "8": "Auto setback / night mode (module 3.02+)"
   },
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 42,
   "documented": "42",
   "name": "controlFunction",
   "description": "Control mode; unsupported values are ignored.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Gen_Spd (constant speed)",
    "3": "Gen_PHdConst (constant differential pressure)",
    "4": "Gen_PHdVar (variable differential pressure)",
    "9": "Gen_T (constant temperature)",
    "10": "Gen_TDiff (constant differential temperature)",
    "15": "INVALID",
    "16": "HeatRadiator_PHd",
    "17": "HeatRadiator_DA",
    "18": "HeatRadiator_T",
    "19": "HeatFloor_PHd",
    "20": "HeatFloor_DA",
    "21": "HeatFloor_T",
    "22": "HeatCeiling_PHd",
    "23": "HeatCeiling_DA",
    "24": "HeatCeiling_T",
    "25": "HeatFan_PHd",
    "26": "HeatFan_DA",
    "27": "HeatFan_T",
    "28": "HeatB._T",
    "29": "HeatB._TDiff",
    "30": "HeatB._Acc.Flow",
    "31": "HeatE._T",
    "32": "HeatE._TDiff",
    "33": "HeatE._Acc.Flow",
    "34": "Heat_PHdConst",
    "35": "Heat_PHdVar",
    "36": "Heat_PHdExt",
    "37": "Heat_DA",
    "38": "Heat_VolFlow",
    "39": "Heat_Acc.Flow",
    "40": "Heat_T",
    "41": "Heat_TDiff",
    "42": "Heat_Spd",
    "43": "CoolCeiling_PHd",
    "44": "CoolCeiling_DA",
    "45": "CoolCeiling_T",
    "46": "CoolFloor_PHd",
    "47": "CoolFloor_DA",
    "48": "CoolFloor_T",
    "49": "CoolFan_PHd",
    "50": "CoolFan_DA",
    "51": "CoolFan_T",
    "52": "CoolB._T",
    "53": "CoolB._TDiff",
    "54": "CoolB._Acc.Flow",
    "55": "CoolE._T",
    "56": "CoolE._TDiff",
    "57": "CoolE._Acc.Flow",
    "58": "Cool_PHdConst",
    "59": "Cool_PHdVar",
    "60": "Cool_PHdExt",
    "61": "Cool_DA",
    "62": "Cool_VolFlow",
    "63": "Cool_Acc.Flow",
    "64": "Cool_T",
    "65": "Cool_TDiff",
    "66": "Cool_Spd",
    "67": "San_Circ._T",
    "68": "SanW.Heat._TDiff",
    "71": "San_PHdConst",
    "72": "San_PHdVar",
    "73": "San_PHdExternal",
    "74": "San_VolFlow",
    "75": "San_Acc.Flow",
    "76": "San_T",
    "77": "San_TDiff",
    "78": "San_Spd",
    "79": "Gen_PHdExt",
    "80": "Gen_DA (Dynamic Adapt)",
    "81": "Gen_VolFlow (constant flow)",
    "82": "Gen_Acc.Flow",
    "83": "ScndPHdConst",
    "84": "ScndPHdVar",
    "85": "ScndFlow",
    "86": "ScndSpd",
    "140": "Gen_UsrDfd (user-defined PID)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 300,
   "documented": "300",
   "name": "busCmd.Timer",
   "description": "Local-lockout / fallback timer state machine.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "1": "OFF",
    "2": "SET",
    "3": "ACTIVE",
    "4": "RESET",
    "5": "MANUAL",
    "6": "SET_PRESET",
    "7": "ACTIVE_PRESET",
    "8": "RESET_PRESET",
    "9": "MANUAL_PRESET",
    "10": "INVALID"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 400,
   "documented": "400",
   "name": "busCmd.TimerTimeout",
   "description": "Bus command timer timeout, minimum 20 s.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "s",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 401,
   "documented": "401",
   "name": "setpointSignalSource",
   "description": "Where the setpoint comes from; write 1 for bus control.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "1": "CIF module (bus)",
    "6": "Internal",
    "7": "EXT 1",
    "8": "EXT 2",
    "9": "INVALID"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 402,
   "documented": "402",
   "name": "dutyPointRel preset",
   "description": "Fallback setpoint used by the bus command timer.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.5,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 403,
   "documented": "403",
   "name": "controlFunction preset",
   "description": "Fallback control mode.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Gen_Spd (constant speed)",
    "3": "Gen_PHdConst (constant differential pressure)",
    "4": "Gen_PHdVar (variable differential pressure)",
    "9": "Gen_T (constant temperature)",
    "10": "Gen_TDiff (constant differential temperature)",
    "15": "INVALID",
    "16": "HeatRadiator_PHd",
    "17": "HeatRadiator_DA",
    "18": "HeatRadiator_T",
    "19": "HeatFloor_PHd",
    "20": "HeatFloor_DA",
    "21": "HeatFloor_T",
    "22": "HeatCeiling_PHd",
    "23": "HeatCeiling_DA",
    "24": "HeatCeiling_T",
    "25": "HeatFan_PHd",
    "26": "HeatFan_DA",
    "27": "HeatFan_T",
    "28": "HeatB._T",
    "29": "HeatB._TDiff",
    "30": "HeatB._Acc.Flow",
    "31": "HeatE._T",
    "32": "HeatE._TDiff",
    "33": "HeatE._Acc.Flow",
    "34": "Heat_PHdConst",
    "35": "Heat_PHdVar",
    "36": "Heat_PHdExt",
    "37": "Heat_DA",
    "38": "Heat_VolFlow",
    "39": "Heat_Acc.Flow",
    "40": "Heat_T",
    "41": "Heat_TDiff",
    "42": "Heat_Spd",
    "43": "CoolCeiling_PHd",
    "44": "CoolCeiling_DA",
    "45": "CoolCeiling_T",
    "46": "CoolFloor_PHd",
    "47": "CoolFloor_DA",
    "48": "CoolFloor_T",
    "49": "CoolFan_PHd",
    "50": "CoolFan_DA",
    "51": "CoolFan_T",
    "52": "CoolB._T",
    "53": "CoolB._TDiff",
    "54": "CoolB._Acc.Flow",
    "55": "CoolE._T",
    "56": "CoolE._TDiff",
    "57": "CoolE._Acc.Flow",
    "58": "Cool_PHdConst",
    "59": "Cool_PHdVar",
    "60": "Cool_PHdExt",
    "61": "Cool_DA",
    "62": "Cool_VolFlow",
    "63": "Cool_Acc.Flow",
    "64": "Cool_T",
    "65": "Cool_TDiff",
    "66": "Cool_Spd",
    "67": "San_Circ._T",
    "68": "SanW.Heat._TDiff",
    "71": "San_PHdConst",
    "72": "San_PHdVar",
    "73": "San_PHdExternal",
    "74": "San_VolFlow",
    "75": "San_Acc.Flow",
    "76": "San_T",
    "77": "San_TDiff",
    "78": "San_Spd",
    "79": "Gen_PHdExt",
    "80": "Gen_DA (Dynamic Adapt)",
    "81": "Gen_VolFlow (constant flow)",
    "82": "Gen_Acc.Flow",
    "83": "ScndPHdConst",
    "84": "ScndPHdVar",
    "85": "ScndFlow",
    "86": "ScndSpd",
    "140": "Gen_UsrDfd (user-defined PID)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 404,
   "documented": "404",
   "name": "Pump Command preset",
   "description": "Fallback on/off command.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": null,
   "bits": {
    "0": "Pump on (preset)"
   },
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 405,
   "documented": "405",
   "name": "setpointSignalSource preset",
   "description": "Fallback setpoint source.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "1": "CIF module (bus)",
    "6": "Internal",
    "7": "EXT 1",
    "8": "EXT 2",
    "9": "INVALID"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 416,
   "documented": "416",
   "name": "parameterSetSelector",
   "description": "Which parameter set drives the pump (module 3.01+).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "1": "norm (normal set)",
    "2": "aux (auxiliary set)",
    "3": "preset (fallback set)"
   },
   "bits": null,
   "offset": 0
  }
 ],
 "integration": {
  "summary": "Set the Modbus address, baud and frame in the pump menu, then write H 300 = 5 (MANUAL), H 401 = 1 (bus setpoint), H 42 = control mode, H 1 = duty point (200 = 100 %) and H 40 = 9 (on, with the required bit 3), as in Wilo's basic example. Check I 211 (parameter set 1 = normal), I 210, I 10, I 200 and I 402, then poll I 404, I 940, I 1, I 2, I 4 and I 7.",
  "minimum_registers": [
   {
    "table": "holding_register",
    "address": 40,
    "why": "On/off command (write 9 = on)"
   },
   {
    "table": "holding_register",
    "address": 42,
    "why": "Control mode"
   },
   {
    "table": "holding_register",
    "address": 1,
    "why": "Duty point, 0.5 % steps"
   },
   {
    "table": "holding_register",
    "address": 401,
    "why": "Setpoint source = bus"
   },
   {
    "table": "holding_register",
    "address": 300,
    "why": "Bus command timer / local lockout"
   },
   {
    "table": "input_register",
    "address": 404,
    "why": "Ready / warning / error flags"
   },
   {
    "table": "input_register",
    "address": 940,
    "why": "Wilo error code"
   },
   {
    "table": "input_register",
    "address": 4,
    "why": "Electrical power"
   },
   {
    "table": "input_register",
    "address": 2,
    "why": "Calculated flow"
   },
   {
    "table": "input_register",
    "address": 7,
    "why": "Speed"
   }
  ],
  "enable": "In the pump menu go to Settings > External interfaces and set up the Modbus RTU interface (address, baud rate, data frame); OFF for the bus address deactivates it. Over the bus, write H 401 = 1 so the setpoint comes from the CIF module. On module 3.01+, H 416 picks the parameter set; if I 211 does not read 1 (normal set), the normal registers are not the ones in effect. Wilo's basic example then writes H 300 = 5 (MANUAL) so both the local menu and the bus are allowed, last write wins. By factory setting the local menu and control input IN2 are locked while a CIF module is fitted.",
  "watchdog": "Bus command timer: write H 300 = 2 (SET) or 6 (SET_PRESET) and repeat the write before the timeout in H 400 elapses (minimum 20 s; Wilo describes 300 s as the default or fixed value). If the writes stop, the local menu is released and, with SET_PRESET, the pump runs on the preset values in H 402-405; the pump may show E50 (bus timeout). I 504 shows the seconds remaining. The activation survives a power cycle; write H 300 = 1 (OFF) to return to factory behaviour.",
  "quirks": [
   "Register numbers are wire addresses (0-based). Wilo's own test: read input register 700 and expect a value of 256 or more; if that fails, try 699/701 to find your master's offset.",
   "Every write to H 40 must have bit 3 set (value 9 = on, 8 = off); bit 3 is a static 1 kept for compatibility.",
   "Duty point is in 0.5 % steps: 200 = 100 % of the mode's reference, which is published as a float in I 206 with its unit code in I 208.",
   "Values are forwarded to the pump only when they change. If a write seems ignored, write a different value and then the one you want.",
   "Several sources (HMI, app, bus) can write the same settings; normally the last write wins. Read the active registers (I 10, I 200, I 210, I 402) to see what is really in effect.",
   "32-bit floats (I 206, I 300-314) are high word first; read both registers in one request.",
   "Function codes 03, 04, 06 and 16 are supported."
  ],
  "setup": [
   "Bus terminals on the CIF module: A(-), B(+) and GND, two sets for incoming and outgoing lines. Some masters label A and B the other way round; swap if nothing answers.",
   "Switch on the built-in 120 ohm terminator (both switches S1/S2 ON) only at the module that ends the line; factory setting is off.",
   "Use shielded cable with the EMC cable gland and earth the shield at both ends; daisy-chain only, no stubs, stars or loops.",
   "Baud codes (Parameter A): 0=300, 1=600, 2=1200, 3=2400, 4=4800, 5=9600, 6=19200, 7=38400, 9=115200, 10=76800. Frame codes (Parameter C): 2=8N1, 3=8N2, 6=8E1, 10=8O1.",
   "Twin-head pumps: fit the CIF module in the master pump; control writes act on the pump system as a whole."
  ],
  "gotchas": [
   "Temperatures are in kelvin x 10, not °C.",
   "Calculated flow (I 2) is an estimate; Wilo says not to use it for closed-loop control.",
   "Writes below the minimum duty point (I 204) are limited to it, and modes the pump does not support are silently ignored - always read back I 10 and I 200.",
   "With the timer in OFF the local menu stays locked permanently; MANUAL keeps both local and bus control."
  ]
 },
 "page": "https://easymodbus.com/modbus-register-maps/wilo/stratos-maxo",
 "address_note": "address = 0-based Modbus wire (PDU) address; documented = as printed in the source.",
 "note": "Re-typed from the manufacturer's public documentation (see source) and verified against it. Registers vary by firmware and options; verify against the live device before writing."
}
