{
 "manufacturer": "Wilo",
 "manufacturer_slug": "wilo",
 "model": "Para MAXO (built-in Modbus RTU)",
 "model_slug": "para-maxo-modbus",
 "short_model": "Para MAXO",
 "aliases": [
  "Para MAXO",
  "Wilo-Para MAXO",
  "Para MAXO Modbus"
 ],
 "equipment_type": "Pump (high-efficiency circulator)",
 "applies_to": "Wilo-Para MAXO OEM circulators with the built-in Modbus RTU interface (module versions 1.00-99.99).",
 "summary": "The Wilo Para MAXO is a high-efficiency OEM circulator (used inside boilers and heat pumps) with Modbus RTU on its signal cable. A master switches the pump on/off, picks constant speed or constant/variable differential pressure, and writes a relative duty point in 0.5 % steps; a bus command timer can drop the pump to preset fallback values on comm loss. Read-only data covers pressure, calculated flow, power, energy, run hours, speed, status bits and the Wilo error code.",
 "transport": [
  "RTU"
 ],
 "defaults": {
  "unit_id": 101,
  "baud": 19200,
  "parity": "Even",
  "data_bits": 8,
  "stop_bits": 1,
  "tcp_port": null
 },
 "addressing": {
  "convention": "0-based",
  "note": "Wilo register numbers start at zero and equal the request address (Wilo's Para MAXO Modbus technical guide states this explicitly), so Flow 'I 2' is input register address 2 on the wire."
 },
 "default_word_order": null,
 "firmware": "Para MAXO Modbus module 1.00-99.99",
 "source": {
  "title": "WILO datapoint list MODBUS - Para MAXO (Modbus list of registers)",
  "doc_number": "wilo458422",
  "revision_date": null,
  "url": "https://cms.media.wilo.com/cdndoc/wilo458422/9310881/wilo458422.html",
  "pages": "Sections 3.3 (holding registers) and 3.4 (input registers) of the HTML datapoint list (current version, linked from qr.wilo.com/para-maxo-Modbus-registers)"
 },
 "notes": [
  "The register list is Wilo's public HTML datapoint list (Wilo's media CDN, reached from the short link qr.wilo.com/para-maxo-Modbus-registers printed in Wilo's own guide). Addressing, communication defaults (address 101, 19200 baud, 8E1), the duty-point worked examples and the fallback procedure come from Wilo's 'OEM Technical guide Wilo-Para MAXO Modbus Communication Protocol' V01.01 (2025-02-13), https://cms.media.wilo.com/cdndoc/wilo698135/9854564/wilo698135.pdf, pp. 5, 8, 11, 17-25. That PDF carries a notice that it is Wilo property and may not be copied or extracted without Wilo's written acceptance; only re-keyed facts are used here and the PDF is linked, not re-hosted.",
  "Scale: physical value = raw x scale as listed in the datapoint list (e.g. 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 = %).",
  "Duty point is relative: the engineering value at 100 % is published in input register 206 ('duty point 100 % value', a 32-bit REAL). Head or speed = duty point % x that value / 100.",
  "Left out because the 32-bit word order is not stated: duty point 100 % value (I 206, REAL), Heartbeat Count (I 500, UDINT), Vendor ID (I 702, DWORD) and parameter block acknowledge (61694, DWORD).",
  "Flow error value: the datapoint list gives 9999, the technical guide's warning cites 65535; treat both as invalid.",
  "Removed where Wilo's documents disagree: Bus Command Timer Time remain (I 504: UINT, scale 1 in the datapoint list but UDINT, scale 2 in the guide); Application Version (I 700: WORD in the guide and older list, UDINT in the current list); Control Function preset (H 403: the list codes the modes 1/3/4 but the guide's fallback section codes them 1/2/3). Flow min-pres-value (I 25) is left out because the current list's support reference does not include Para MAXO.",
  "Speed (I 7) is INT in the current datapoint list and UINT in the guide and the older list; it is typed INT16 here. Real pump speeds are far below 32768 rpm, so both readings agree.",
  "The control-mode lists (H 42, I 10) also include 140 = Gen_UsrDfd for Para MAXO in the current datapoint list; the guide only describes 1, 3 and 4."
 ],
 "registers": [
  {
   "table": "input_register",
   "address": 1,
   "documented": "1",
   "name": "Pressure",
   "description": "Actual (differential) pressure; 65535 = error/not available.",
   "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 (calculated)",
   "description": "Calculated estimate, not for closed-loop control; error value 9999 (list) or 65535 (guide).",
   "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": "Energy Consumption",
   "description": "Total consumed electrical energy; 65535 = error.",
   "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": "power input",
   "description": "Actual electrical input power; 65535 = error.",
   "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": "Operation Time",
   "description": "Total running time (motor turning); 65535 = error.",
   "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; 65535 = error.",
   "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": 10,
   "documented": "10",
   "name": "Control Function (active)",
   "description": "Active control mode.",
   "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)",
    "140": "Gen_UsrDfd (user-configurable PID)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 18,
   "documented": "18",
   "name": "Speed max-pres-value",
   "description": "Maximum speed value.",
   "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 value.",
   "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": 24,
   "documented": "24",
   "name": "Flow (calculated) max-pres-value",
   "description": "",
   "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": 200,
   "documented": "200",
   "name": "duty point (rel.) (active)",
   "description": "Setpoint currently in effect.",
   "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": "duty point (rel.) maximum-output",
   "description": "Highest duty point the pump accepts in this mode.",
   "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": "duty point (rel.) minimum-output",
   "description": "Lowest duty point the pump accepts; lower writes are clamped.",
   "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": 208,
   "documented": "208",
   "name": "duty point (rel.) units",
   "description": "Unit code of the duty-point reference.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "19": "kWh",
    "47": "W",
    "73": "s",
    "104": "rpm (min-1)",
    "135": "m³/h"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 400,
   "documented": "400",
   "name": "duty point (rel.) (output)",
   "description": "Actual operating point as % of the duty-point range.",
   "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",
    "3": "TRUE (static 1)"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 404,
   "documented": "404",
   "name": "Operation Status",
   "description": "Pump operating state 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": "Pump on",
    "3": "Warning Present",
    "4": "Error Present (will retry)",
    "5": "Final Error present (no retry)"
   },
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 940,
   "documented": "940",
   "name": "Warning/Error Message",
   "description": "Current Wilo warning/error code (E000-E255).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "No error",
    "4": "Mains undervoltage",
    "7": "Generator operation",
    "10": "Blocked rotor",
    "11": "Dry running",
    "19": "Pump flow error",
    "21": "Motor overload (torque)",
    "23": "Short circuit",
    "25": "Motor/winding contact missing",
    "30": "Module overtemperature",
    "31": "Power bridge/component overtemperature",
    "32": "DC link undervoltage",
    "33": "DC link overvoltage",
    "38": "Fluid temperature sensor defect",
    "50": "BMS communication timeout",
    "111": "Overcurrent",
    "112": "Speed above synchronous value",
    "119": "Turbine operation",
    "252": "Extended code"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1,
   "documented": "1",
   "name": "duty point (rel.)",
   "description": "Setpoint as % of the duty-point range (200 = 100 %); 32767 = error.",
   "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": "Pump 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"
   },
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 42,
   "documented": "42",
   "name": "Control Function",
   "description": "Control mode; an unsupported value leaves the previous mode active.",
   "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)",
    "140": "Gen_UsrDfd (user-configurable PID)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 300,
   "documented": "300",
   "name": "Bus Command Timer",
   "description": "Local-lockout / fallback timer state machine (write SET or SET_PRESET periodically).",
   "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"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 400,
   "documented": "400",
   "name": "Bus Command Timer Timeout",
   "description": "Fallback timeout, 20-65534 s (factory 300 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": 402,
   "documented": "402",
   "name": "duty point (rel.) preset",
   "description": "Fallback setpoint used after the bus command timer elapses.",
   "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": 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": 61440,
   "documented": "61440",
   "name": "interface device identifier",
   "description": "Modbus slave address, 1-247 (default 101).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 61441,
   "documented": "61441",
   "name": "transmission serial speed",
   "description": "Baud rate (default 19200).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "0": "300",
    "1": "600",
    "2": "1200",
    "3": "2400",
    "4": "4800",
    "5": "9600",
    "6": "19200",
    "7": "38400",
    "8": "57600",
    "9": "115200",
    "10": "76800",
    "12": "Invalid"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 61442,
   "documented": "61442",
   "name": "transmission serial frame",
   "description": "Data bits / parity / stop bits (default 8E1).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "2": "8N1",
    "3": "8N2",
    "6": "8E1",
    "10": "8O1",
    "15": "Invalid"
   },
   "bits": null,
   "offset": 0
  }
 ],
 "integration": {
  "summary": "Talk to address 101 at 19200 8E1 by default. Write H 42 (control mode), then H 1 (duty point, 200 = 100 %) and H 40 = 1 to run; read I 200/I 400 for set and actual duty point, I 1/I 2/I 4 for pressure, flow and power, and I 404/I 940 for status and errors.",
  "minimum_registers": [
   {
    "table": "holding_register",
    "address": 40,
    "why": "Pump on/off"
   },
   {
    "table": "holding_register",
    "address": 42,
    "why": "Control mode"
   },
   {
    "table": "holding_register",
    "address": 1,
    "why": "Duty point (setpoint), 0.5 % steps"
   },
   {
    "table": "input_register",
    "address": 404,
    "why": "Operation status bits"
   },
   {
    "table": "input_register",
    "address": 940,
    "why": "Wilo error code"
   },
   {
    "table": "input_register",
    "address": 4,
    "why": "Electrical power"
   },
   {
    "table": "input_register",
    "address": 7,
    "why": "Speed"
   },
   {
    "table": "input_register",
    "address": 2,
    "why": "Calculated flow"
   }
  ],
  "enable": "No enable step is documented: the pump accepts Modbus writes directly. Use Bus Command Timer (H 300) = MANUAL to allow both local and bus operation (last write wins).",
  "watchdog": "Fallback emulation (guide p. 23): set H 400 (20-65534 s, default 300 s), the fallback on/off H 404 and the fallback duty point H 402, then write H 300 = 6 (SET_PRESET) and keep rewriting it before the timeout. If it lapses the pump runs on the preset values. The fallback control mode register H 403 is not listed here because Wilo's documents give conflicting codes for it.",
  "quirks": [
   "Register numbers are already wire addresses (0-based); do not subtract 1.",
   "Duty point is in 0.5 % steps: 200 = 100 % of the mode's reference (max head or max speed from I 206).",
   "After changing the control mode (H 42), write H 1 = 0 first and then the new duty point so the active duty point refreshes.",
   "Writes below the minimum output (I 204) are clamped to it.",
   "Input register I 402 (Pump Command active) shows bit 3 as a static 1 described as needed 'for write access', while the guide's examples write H 40 = 1 (bit 0 only). Follow the guide's values and confirm with I 402."
  ],
  "setup": [
   "Signal cable: core 1 (brown) = Data+ / D1 / B(+), core 3 (black) = Data- / D0 / A(-), core 2 (blue/grey) = common.",
   "Terminate both bus ends with 120-150 ohm; no line polarization is needed on the Wilo side.",
   "Change address, baud and frame via H 61440, H 61441 and H 61442 (default 101, 19200, 8E1)."
  ],
  "gotchas": [
   "Wilo numbers registers from zero, unlike the usual 1-based Modbus register numbering; a tool that adds or subtracts 1 will hit the wrong register.",
   "Calculated flow is an estimate; do not use it for closed-loop control."
  ]
 },
 "page": "https://easymodbus.com/modbus-register-maps/wilo/para-maxo-modbus",
 "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."
}
