{
 "manufacturer": "Lochinvar",
 "manufacturer_slug": "lochinvar",
 "model": "Knight / Armor / Wall Mount boilers (ModBus communication board)",
 "model_slug": "knight-armor-modbus",
 "short_model": "Knight & Armor",
 "aliases": [
  "Knight",
  "Knight XL",
  "Outdoor Knight",
  "Outdoor Knight XL",
  "Armor",
  "Outdoor Armor",
  "Wall Mount Armor",
  "Knight Wall Mount",
  "Knight Wall Hung",
  "AQUAS",
  "FTXL",
  "Shield"
 ],
 "equipment_type": "Boiler / water heater",
 "applies_to": "Knight 81-286, Knight XL 400-1000, Armor 151-1000, Outdoor Knight/Knight XL/Armor, AQUAS 400-801, FTXL 400-1000, Wall Mount 51-211, Wall Hung 55-399, Wall Mount Armor 125-200 and Shield 125-500 with the Lochinvar ModBus communication board.",
 "summary": "Lochinvar's Knight, Armor, Wall Mount, FTXL, Shield and related boilers and water heaters speak Modbus RTU through an optional RS-485 communication board configured with DIP switches. A BAS can enable the unit, send a modulation rate or setpoint command, and supply tank, outdoor and system temperatures, with a configuration word telling the appliance which values to take from the BAS. Read-only data covers outlet/inlet/flue temperatures, firing rate, pump speeds, cascade power and status, blocking and lockout codes.",
 "transport": [
  "RTU"
 ],
 "defaults": {
  "unit_id": null,
  "baud": null,
  "parity": null,
  "data_bits": null,
  "stop_bits": null,
  "tcp_port": null
 },
 "addressing": {
  "convention": "Modicon",
  "note": "Addresses are printed Modicon-style (00001 coils, 10001 discrete inputs, 30001 input registers, 40001 holding registers). Subtract the table base and 1 for the wire address, e.g. Outlet Temperature 30009 is input register 8."
 },
 "default_word_order": null,
 "firmware": null,
 "source": {
  "title": "ModBus and BACnet Communication Instructions (Knight, Knight XL, Armor, Outdoor Knight, AQUAS, FTXL, Wall Mount, Wall Hung, Shield)",
  "doc_number": "MODB-I-O_100161545_2000014822 Rev T",
  "revision_date": null,
  "url": "https://assets.lochinvar.com/damroot/Original/10014/MODB-I-O_100161545_2000014822_Rev_T_(54850).pdf",
  "pages": "pp. 9-12 (Modbus configuration), 13-14 (memory map), 25-29 (control modes, rate/temperature conversion), 34-35 (status, blocking, lockout codes)"
 },
 "notes": [
  "Temperatures: the manual's conversion section says the appliance passes temperatures in degrees C multiplied by 10 (worked examples: outdoor 26.7 C sent as 267; outlet 683 read as 68.3 C). Scale 0.1 is applied to every temperature register.",
  "Removed: System/Cascade Setpoint (30004), Outlet Setpoint (30008) and Tank Setpoint (40004). The memory map gives these a 0.5 C resolution while the conversion section says all temperature data is degrees C x 10, and the worked examples only cover other registers (outdoor temperature and outlet temperature). Because the scaling of these three is not settled by the document, they are left out.",
  "Signed types: registers whose published minimum is negative (inlet, flue, tank, outdoor, supply/return temperatures) are listed as INT16; the manual itself only says '16-bit word'.",
  "Dip switch 8 on the communication board selects degrees C (OFF) or F (ON) for the display/data; units here assume C (switch OFF), matching the manual's tables and conversion examples.",
  "Holding register 40002 'Coils' has no bit list: the manual's tables write 0x0001 to enable the unit but 0x0008 for the tank thermostat, which does not match the tank thermostat being coil 00005. Write only the exact values from the manual's control-mode tables.",
  "Input registers 30001-30003 are packed copies of the discrete inputs; the bit-to-input order is not stated, so they are listed as UINT16. Use the discrete inputs instead.",
  "The same manual also covers AWH and KBX appliances (pp. 30-33) with similar holding-register use; this map follows the main memory map on pp. 13-14."
 ],
 "registers": [
  {
   "table": "coil",
   "address": 0,
   "documented": "00001",
   "name": "Room Thermostat 1",
   "description": "Enable/heat demand input 1 written by the BAS.",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "coil",
   "address": 1,
   "documented": "00002",
   "name": "Room Thermostat 2",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "coil",
   "address": 2,
   "documented": "00003",
   "name": "Room Thermostat 3",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "coil",
   "address": 4,
   "documented": "00005",
   "name": "Tank Thermostat",
   "description": "DHW tank thermostat demand written by the BAS.",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 1,
   "documented": "10002",
   "name": "Flow Switch",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 2,
   "documented": "10003",
   "name": "Gas Pressure Switch",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 3,
   "documented": "10004",
   "name": "Louver Proving Switch",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 4,
   "documented": "10005",
   "name": "Air Pressure Switch",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 5,
   "documented": "10006",
   "name": "Blocked Drain Switch",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 6,
   "documented": "10007",
   "name": "Auto Reset High Limit",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 7,
   "documented": "10008",
   "name": "Flame",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 8,
   "documented": "10009",
   "name": "Room Thermostat 1",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 9,
   "documented": "10010",
   "name": "Tank Thermostat",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 23,
   "documented": "10024",
   "name": "Room Thermostat 2",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 32,
   "documented": "10033",
   "name": "Run-time Contacts",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 33,
   "documented": "10034",
   "name": "Alarm Contacts",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 34,
   "documented": "10035",
   "name": "CH Pump",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 35,
   "documented": "10036",
   "name": "DHW Pump",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 36,
   "documented": "10037",
   "name": "Louver Relay",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 37,
   "documented": "10038",
   "name": "Gas Valve",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 38,
   "documented": "10039",
   "name": "System Pump",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "discrete_input",
   "address": 43,
   "documented": "10044",
   "name": "DHW Recirculation Pump",
   "description": "",
   "data_type": "BIT",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "Off",
    "1": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 0,
   "documented": "30001",
   "name": "Discrete Inputs 1-16",
   "description": "Packed copy of discrete inputs 1-16.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1,
   "documented": "30002",
   "name": "Discrete Inputs 17-32",
   "description": "Packed copy of discrete inputs 17-32.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 2,
   "documented": "30003",
   "name": "Discrete Inputs 33-48",
   "description": "Packed copy of discrete inputs 33-48.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 4,
   "documented": "30005",
   "name": "System Pump Speed",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 5,
   "documented": "30006",
   "name": "Cascade Total Power",
   "description": "Total cascade capacity (100-800 %).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 6,
   "documented": "30007",
   "name": "Cascade Current Power",
   "description": "Current cascade output (0-800 %).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 8,
   "documented": "30009",
   "name": "Outlet Temperature",
   "description": "Raw is degrees C x 10 (manual example: 683 = 68.3 C).",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 9,
   "documented": "30010",
   "name": "Inlet Temperature",
   "description": "",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 10,
   "documented": "30011",
   "name": "Flue Temperature",
   "description": "",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 11,
   "documented": "30012",
   "name": "Firing Rate",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 12,
   "documented": "30013",
   "name": "Boiler Pump Speed",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 13,
   "documented": "30014",
   "name": "Boiler Status Code",
   "description": "What the appliance is doing; 40 = lockout.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "2": "Heat demand blocked: high absolute outlet temperature",
    "3": "Heat demand blocked: high absolute flue temperature",
    "4": "Heat demand blocked: high absolute delta T",
    "8": "Heat demand blocked: low 24 VAC",
    "9": "Outdoor shutdown",
    "10": "Blocked: boiler switched off at display",
    "12": "Blocked: no correct cascade communication",
    "16": "Service function",
    "19": "DHW function storage tank",
    "21": "SH heat demand from room thermostat",
    "22": "SH heat demand from BMS",
    "23": "SH heat demand from cascade",
    "30": "Heat demand from freeze protection",
    "32": "DHW pump delay",
    "33": "SH pump delay",
    "34": "No heat function (after pump delay)",
    "40": "Lockout",
    "32764": "Busy updating status",
    "32765": "DHW blocked: no tank sensor",
    "32766": "Burner control(s) manually shut down",
    "32767": "Code not present"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 14,
   "documented": "30015",
   "name": "Boiler Blocking Code",
   "description": "Reason heat demand is blocked or limited.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "0": "No blocking",
    "1": "SH blocking",
    "2": "Low 24 VAC supply",
    "3": "General block",
    "4": "MRHL open",
    "5": "Boiler switched off (display)",
    "6": "Wrong cascade communication",
    "7": "High delta T",
    "8": "High flue temperature",
    "9": "High outlet temperature",
    "10": "Service blocking",
    "12": "DHW blocking, high outlet temperature",
    "13": "Anti-cycling time",
    "14": "Storage tank demand blocked, fan problem",
    "15": "No system sensor with leader control present",
    "16": "Fan speed limited, high outlet temperature",
    "17": "Fan min decreased, low flame current",
    "18": "Max fan speed limited, high delta T",
    "19": "Max fan speed limited, high flue temperature",
    "32767": "Code not present"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 15,
   "documented": "30016",
   "name": "Boiler Lockout Code",
   "description": "Lockout reason; only valid while status code is 40.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "161": "Parameters not re-programmed by Lochinvar",
    "164": "No reset allowed (> 15 minutes)",
    "166": "Auto reset high limit",
    "167": "Blocked drain",
    "168": "Louver proving",
    "169": "Gas pressure switch",
    "170": "Flow switch",
    "177": "Flue sensor short",
    "178": "Flue sensor open",
    "179": "Inlet sensor short",
    "180": "Inlet sensor open",
    "192": "Outlet sensor short",
    "193": "Outlet sensor open",
    "204": "CRC EEPROM failed",
    "205": "EEPROM programmed",
    "206": "EEPROM programming error",
    "207": "EEPROM write error",
    "229": "Watchdog",
    "230": "Fan low (should be high)",
    "231": "Fan high (should be low)",
    "232": "No flame when running",
    "233": "No flame after ignition",
    "234": "Simultaneous output APS and fan",
    "235": "APS active not closed",
    "236": "APS active not open",
    "237": "Flame out of sequence",
    "239": "Gas valve relay test failed",
    "240": "MRHL",
    "32767": "Code not present"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 0,
   "documented": "40001",
   "name": "Configuration",
   "description": "Selects which values the BAS supplies instead of the boiler's own inputs.",
   "data_type": "BITMAP16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": null,
   "bits": {
    "0": "Boiler Enable from BAS",
    "1": "Tank Thermostat from BAS",
    "2": "Rate Command / 0-10V Input / Setpoint Command from BAS",
    "3": "Tank Setpoint from BAS",
    "4": "System Supply Temperature from BAS",
    "5": "Outdoor Temperature from BAS",
    "6": "Tank Temperature from BAS",
    "7": "System Return Temperature from BAS"
   },
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1,
   "documented": "40002",
   "name": "Coils",
   "description": "Command word written by the BAS; write the values given in the manual's control-mode tables.",
   "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": 2,
   "documented": "40003",
   "name": "0-10 Volt Input / Rate Command / Setpoint Command",
   "description": "Modulation % or setpoint, per the BMS Type setting (0-100).",
   "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": 4,
   "documented": "40005",
   "name": "Tank Temperature",
   "description": "Tank temperature supplied by the BAS.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 5,
   "documented": "40006",
   "name": "Outdoor Temperature",
   "description": "Outdoor temperature supplied by the BAS (-40 to 60 C).",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 6,
   "documented": "40007",
   "name": "System Supply Temperature",
   "description": "System supply temperature supplied by the BAS.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 7,
   "documented": "40008",
   "name": "DHW Recirculation Temperature",
   "description": "DHW recirculation temperature supplied by the BAS.",
   "data_type": "INT16",
   "length": 1,
   "word_order": null,
   "scale": 0.1,
   "scale_factor_ref": null,
   "units": "°C",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  }
 ],
 "integration": {
  "summary": "Set the board address, baud and parity on its DIP switches, put the boiler control in ModBus mode, then write the configuration word 40001 followed by the command registers. For a simple enable, write 40001 = 0x0001 and 40002 = 0x0001; for a modulation or setpoint command also set bit 2 (40001 = 0x0005) and write 40003. Monitor 30009-30016.",
  "minimum_registers": [
   {
    "table": "holding_register",
    "address": 0,
    "why": "Configuration bits: which values come from the BAS"
   },
   {
    "table": "holding_register",
    "address": 1,
    "why": "Enable / thermostat command word"
   },
   {
    "table": "holding_register",
    "address": 2,
    "why": "Rate (%) or setpoint command"
   },
   {
    "table": "input_register",
    "address": 8,
    "why": "Outlet temperature"
   },
   {
    "table": "input_register",
    "address": 9,
    "why": "Inlet temperature"
   },
   {
    "table": "input_register",
    "address": 11,
    "why": "Firing rate"
   },
   {
    "table": "input_register",
    "address": 13,
    "why": "Status code"
   },
   {
    "table": "input_register",
    "address": 15,
    "why": "Lockout code"
   }
  ],
  "enable": "In the boiler installer menu go to CONTROL MODES and set ModBus to ACTIVE, then pick the control mode (enable only, enable + rate/setpoint, rate only, DHW). Set BMS TYPE to POWER or SETPOINT for rate commands. Re-send the configuration word in 40001 before each command.",
  "watchdog": "MODBUS T/O in the CONTROL MODES menu, 5-120 s (default 10 s): if BAS-supplied temperatures or the 0-10 V value are not refreshed in time the boiler falls back to its own sensors. Enable-type commands must be refreshed at least every 4 minutes or the boiler reverts to its own inputs.",
  "quirks": [
   "Modicon addressing: 40001 is holding register 0 on the wire.",
   "Temperatures are passed as degrees C x 10 (the manual's examples: 267 = 26.7 C, 683 = 68.3 C); the map assumes DIP switch 8 is OFF (Celsius).",
   "A rate command is a plain percentage (0-100). To command a temperature setpoint via 40003 the value is the 0-10 V equivalent percentage, interpolated from the BMS setpoint-at-low/high-voltage parameters, not degrees.",
   "The lockout code changes during normal operation; only trust it when the status code (30014) reads 40."
  ],
  "setup": [
   "DIP switches 1-7 set the Modbus address (binary weights 1-64, maximum 127).",
   "DIP switch 8: OFF = Celsius, ON = Fahrenheit.",
   "DIP switch 9: OFF = 9600 baud, ON = 19200 baud.",
   "DIP switch 10: OFF = no parity with 2 stop bits, ON = even parity with 1 stop bit.",
   "RTU only; use 120 ohm termination at the ends of the RS-485 run.",
   "For cascades, a board on the leader alone gives total cascade data; fit a board to each unit to see individual temperatures."
  ],
  "gotchas": [
   "Writing commands without setting the matching bit in 40001 has no effect; the boiler keeps using its own inputs.",
   "Board LED D7 shows faults: 1.5 s on / 0.5 s off means no Modbus communication, 0.5 s on / 1.5 s off means no communication with the burner control."
  ]
 },
 "page": "https://easymodbus.com/modbus-register-maps/lochinvar/knight-armor-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."
}
