{
 "manufacturer": "Flexit",
 "manufacturer_slug": "flexit",
 "model": "Nordic residential air handling unit (Flexit GO, built-in Modbus)",
 "model_slug": "nordic",
 "short_model": "Flexit Nordic",
 "aliases": [
  "Nordic S2",
  "Nordic S3",
  "Nordic S4",
  "Nordic CL2",
  "Nordic CL3",
  "Nordic CL4",
  "Flexit GO",
  "Modbus Nordic Basic",
  "117989"
 ],
 "equipment_type": "Air handler",
 "applies_to": "Flexit NORDIC series residential ventilation units with Flexit GO control and built-in Modbus RTU (cable harness 116405), per the 'Modbus Nordic Basic' register sheet and instruction 117989-01 (2020-01). Not EcoNordic, which has its own register sheet.",
 "summary": "Flexit Nordic units are residential balanced-ventilation air handlers with heat recovery. The controller exposes a Modbus RTU slave on RS-485: measurements and outputs are 32-bit IEEE floats over two registers (high word first), while modes, digital inputs and alarm states are single 16-bit registers. This map covers temperatures, fan speeds, ventilation mode commands, home/away set points, filter timer and the A/B alarm handling.",
 "transport": [
  "RTU"
 ],
 "defaults": {
  "unit_id": 1,
  "baud": 9600,
  "parity": "Even",
  "data_bits": 8,
  "stop_bits": 1,
  "tcp_port": null
 },
 "addressing": {
  "convention": "0-based",
  "note": "The register sheet's address column is headed 'Modbus address (Base 0)' and prints references with a table prefix (3x = input register, FC 04; 4x = holding register, FC 03/06/16). The number after the prefix is the wire address unchanged: 3x0001 -> input register 1, 4x2013 -> holding register 2013."
 },
 "default_word_order": "ABCD",
 "firmware": null,
 "source": {
  "title": "Modbus Nordic Basic (register sheet, Modbus_Nordic_Basic.xlsx)",
  "doc_number": null,
  "revision_date": null,
  "url": "https://flexitwebsiteprodstorage.blob.core.windows.net/product-documents/2883",
  "pages": "single worksheet 'Blad1'"
 },
 "notes": [
  "Connection, serial defaults, function codes and data-type encoding come from the companion instruction 'Flexit GO - External Modbus communication', 117989-01, 2020-01 (English section pp. 12-15): https://flexitwebsiteprodstorage.blob.core.windows.net/product-documents/2881 . It defines 32-bit values as dd cc at register x and bb aa at x+1, i.e. most significant word first (ABCD); the sheet header also says big-endian byte order.",
  "Both documents are listed on Flexit's FlexitGO product page (Documentation tab).",
  "Register 4x9001 System Status gates the rest: the sheet says the Modbus registers are only reachable while it reads 0 (Operation mode).",
  "Left out: 'Frost protection temp. for heating coil' (3x0033), because the sheet gives it units Pa and a -3000 to 3000 range, which cannot be right for a temperature.",
  "Left out: smoke/fire fan operation and CO detector inputs (3x3016-3x3020), fire damper command 4x2043 and cooling pump command 4x2004 - option-only points; read them from the sheet if your unit has them.",
  "Output registers 4x0001-4x0025 and 4x2001/4x2007 are holding registers but marked read-only (R) in the sheet; they report what the controller is driving and cannot be overridden.",
  "Alarm code values (3x1021 etc.) are numbers whose meanings are in the unit's alarm list, which this sheet does not reproduce."
 ],
 "registers": [
  {
   "table": "input_register",
   "address": 1,
   "documented": "3x0001",
   "name": "Outside air temperature",
   "description": "-50 to 50 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 5,
   "documented": "3x0005",
   "name": "Supply air temperature",
   "description": "-50 to 80 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 9,
   "documented": "3x0009",
   "name": "Extract air temperature",
   "description": "-50 to 80 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 13,
   "documented": "3x0013",
   "name": "Exhaust air temperature",
   "description": "-50 to 80 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 17,
   "documented": "3x0017",
   "name": "Room temperature",
   "description": "From the CI70 panel sensor, 0 to 50 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 21,
   "documented": "3x0021",
   "name": "Supply air fan speed feedback",
   "description": "Measured supply fan speed.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "rpm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 25,
   "documented": "3x0025",
   "name": "Exhaust air fan speed feedback",
   "description": "Measured exhaust fan speed.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "rpm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 37,
   "documented": "3x0037",
   "name": "Supply air pressure",
   "description": "Only with duct-pressure fan control (CI80).",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "Pa",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 41,
   "documented": "3x0041",
   "name": "Extract air pressure",
   "description": "Only with duct-pressure fan control (CI80).",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "Pa",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 61,
   "documented": "3x0061",
   "name": "Extract air relative humidity",
   "description": "Only if a humidity sensor is configured on X3.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 149,
   "documented": "3x0149",
   "name": "Room air quality input value",
   "description": "Air-quality sensor on X3, 0-2000 ppm; only if configured.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "ppm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1001,
   "documented": "3x1001",
   "name": "Room air humidity 1",
   "description": "Wireless CI77 sensor 1; needs the CI75 adapter.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1003,
   "documented": "3x1003",
   "name": "Room air humidity 2",
   "description": "Wireless CI77 sensor 2; needs the CI75 adapter.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1005,
   "documented": "3x1005",
   "name": "Room air humidity 3",
   "description": "Wireless CI77 sensor 3; needs the CI75 adapter.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1007,
   "documented": "3x1007",
   "name": "Room air quality 1 (CO2)",
   "description": "Wireless CI76 CO2 sensor; needs the CI75 adapter.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "ppm",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1021,
   "documented": "3x1021",
   "name": "A-alarm code",
   "description": "Code of the active A alarm, 0-9999.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1023,
   "documented": "3x1023",
   "name": "B-alarm code",
   "description": "Code of the active B alarm, 0-9999.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1025,
   "documented": "3x1025",
   "name": "Fault counter",
   "description": "Number of entries in the fault list.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1027,
   "documented": "3x1027",
   "name": "Fault list number",
   "description": "Current position in the fault list.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1029,
   "documented": "3x1029",
   "name": "Display fault list",
   "description": "Alarm code at the current fault-list position.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1035,
   "documented": "3x1035",
   "name": "Remaining time of rapid ventilation",
   "description": "Minutes left of temporary High.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "min",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 1037,
   "documented": "3x1037",
   "name": "Remaining time of fireplace ventilation",
   "description": "Minutes left of fireplace mode.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "min",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3001,
   "documented": "3x3001",
   "name": "A-alarm indication",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "1": "Normal",
    "2": "Alarm"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3002,
   "documented": "3x3002",
   "name": "A-alarm state",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "1": "Acknowledged, unlocked",
    "2": "Unacknowledged",
    "3": "Locked"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3003,
   "documented": "3x3003",
   "name": "B-alarm indication",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "1": "Normal",
    "2": "Alarm"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3004,
   "documented": "3x3004",
   "name": "B-alarm state",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "1": "Acknowledged, unlocked",
    "2": "Unacknowledged",
    "3": "Locked"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3006,
   "documented": "3x3006",
   "name": "High input",
   "description": "Only if configured on DI1 or DI2.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3007,
   "documented": "3x3007",
   "name": "Home input",
   "description": "Only if configured on DI1, DI2 or X8.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3008,
   "documented": "3x3008",
   "name": "Away input",
   "description": "Only if configured on DI1, DI2 or X8.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3009,
   "documented": "3x3009",
   "name": "Stop input",
   "description": "Only if configured on DI1 or DI2.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3010,
   "documented": "3x3010",
   "name": "Fireplace ventilation input",
   "description": "Only if configured on DI1 or DI2.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3011,
   "documented": "3x3011",
   "name": "Cooker hood ventilation input",
   "description": "Only if configured on DI1 or DI2.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3013,
   "documented": "3x3013",
   "name": "Fire damper feedback",
   "description": "Only if a fire damper with feedback is configured.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3015,
   "documented": "3x3015",
   "name": "Emergency off",
   "description": "Only if configured on X8.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3023,
   "documented": "3x3023",
   "name": "Heating coil overtemperature detector",
   "description": "Only with an electric heater.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 3034,
   "documented": "3x3034",
   "name": "Heat recovery ventilation state",
   "description": "Ventilation mode the unit is running now.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "1": "Off",
    "2": "Away",
    "3": "Home",
    "4": "High",
    "5": "Fume hood",
    "6": "Fireplace",
    "7": "Temporary high"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1,
   "documented": "4x0001",
   "name": "Rotary heat exchanger speed",
   "description": "Output signal, 0-100 %.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 5,
   "documented": "4x0005",
   "name": "Supply air fan speed",
   "description": "Fan output signal, 0-100 %.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 9,
   "documented": "4x0009",
   "name": "Exhaust air fan speed",
   "description": "Fan output signal, 0-100 %.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 13,
   "documented": "4x0013",
   "name": "Heating coil electric position",
   "description": "Only with an electric heater.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 17,
   "documented": "4x0017",
   "name": "Heating coil valve position",
   "description": "Only with water heating.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 25,
   "documented": "4x0025",
   "name": "Cooling coil valve position",
   "description": "Only with water cooling and the valve on X7.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1103,
   "documented": "4x1103",
   "name": "Rapid ventilation runtime",
   "description": "Length of temporary High, 1-360 min.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "min",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1105,
   "documented": "4x1105",
   "name": "Fireplace ventilation runtime",
   "description": "Length of fireplace mode, 0-360 min.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "min",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1155,
   "documented": "4x1155",
   "name": "Setpoint temperature when home",
   "description": "10 to 30 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1163,
   "documented": "4x1163",
   "name": "Setpoint temperature when away",
   "description": "10 to 30 °C.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "°C",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1269,
   "documented": "4x1269",
   "name": "Operating time for filter replacement",
   "description": "Filter change interval, 0-99990 h.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "h",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1271,
   "documented": "4x1271",
   "name": "Operating time filter",
   "description": "Hours run on the current filter, 0-99999 h.",
   "data_type": "FLOAT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "h",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 1615,
   "documented": "4x1615",
   "name": "Away delay timer duration",
   "description": "Delay before Comfort button 0 switches to Away, 0-600 min.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "units": "min",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 2001,
   "documented": "4x2001",
   "name": "Heating coil pump command",
   "description": "Only with water heating.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 2007,
   "documented": "4x2007",
   "name": "Outside air damper command",
   "description": "Only if the damper is configured on Q1-Q3.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 2013,
   "documented": "4x2013",
   "name": "Room operating mode",
   "description": "Requested ventilation mode; used only while Comfort button 4x2040 = 1.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Stop",
    "2": "Away",
    "3": "Home",
    "4": "High"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 2040,
   "documented": "4x2040",
   "name": "Comfort button",
   "description": "0 = Away after the delay in 4x1615; 1 = follow 4x2013.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "0": "Inactive",
    "1": "Active"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 3002,
   "documented": "4x3002",
   "name": "A-alarm acknowledgement",
   "description": "Write 2 to acknowledge or 3 to reset.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Ready",
    "2": "Acknowledge",
    "3": "Reset"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 3003,
   "documented": "4x3003",
   "name": "B-alarm acknowledgement",
   "description": "Write 2 to acknowledge.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Ready",
    "2": "Acknowledge"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 3004,
   "documented": "4x3004",
   "name": "Fault list operation",
   "description": "2 steps to the next fault; 3 clears inactive alarms.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Ready",
    "2": "Next fault",
    "3": "Refresh"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 3006,
   "documented": "4x3006",
   "name": "Trigger temporary rapid ventilation",
   "description": "Write 2 to start temporary High.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Ready",
    "2": "Trigger"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 3007,
   "documented": "4x3007",
   "name": "Trigger temporary fireplace ventilation",
   "description": "Write 2 to start fireplace mode.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "1": "Ready",
    "2": "Trigger"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 9001,
   "documented": "4x9001",
   "name": "System status",
   "description": "Other registers answer only while this reads 0.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Operation mode",
    "2": "Configuration mode"
   },
   "bits": null,
   "offset": 0
  }
 ],
 "integration": {
  "summary": "Wire RS-485 to terminals 16 (D+), 17 (D-) and 18 (G0) through harness 116405, poll at 9600 8E1 address 1, and check 4x9001 = 0 first. Read temperatures and fan outputs as ABCD floats; set the ventilation mode with 4x2013 after writing 4x2040 = 1.",
  "minimum_registers": [
   {
    "table": "holding_register",
    "address": 9001,
    "why": "System status (must be operation mode)"
   },
   {
    "table": "input_register",
    "address": 5,
    "why": "Supply air temperature"
   },
   {
    "table": "input_register",
    "address": 1,
    "why": "Outside air temperature"
   },
   {
    "table": "input_register",
    "address": 9,
    "why": "Extract air temperature"
   },
   {
    "table": "input_register",
    "address": 3034,
    "why": "Current ventilation mode"
   },
   {
    "table": "holding_register",
    "address": 2013,
    "why": "Ventilation mode command"
   },
   {
    "table": "holding_register",
    "address": 2040,
    "why": "Comfort button (enables 4x2013)"
   },
   {
    "table": "holding_register",
    "address": 1155,
    "why": "Home temperature set point"
   },
   {
    "table": "input_register",
    "address": 3001,
    "why": "A-alarm indication"
   },
   {
    "table": "holding_register",
    "address": 1271,
    "why": "Filter operating hours"
   }
  ],
  "enable": "Modbus is built into the Nordic controller; connect a master with cable harness 116405. 4x2013 Room operating mode works only while 4x2040 Comfort button = 1, and a mode selected on a digital input overrides it.",
  "watchdog": null,
  "quirks": [
   "Addresses are 0-based: use the number after 3x/4x unchanged on the wire.",
   "Floats and 32-bit unsigned values occupy two registers with the high word in the lower address (ABCD); write them with FC 16 only.",
   "Many float registers sit at odd addresses (3x0001, 3x0005); read each as a 2-register block starting at the listed address.",
   "Several 16-bit enums start at 1, not 0 (ventilation state, alarm indication/state, the trigger and acknowledge registers)."
  ],
  "setup": [
   "Defaults: address 1 (1-247), 9600 baud (9600/19200), 8 data bits, even parity (none/even/odd), 1 stop bit (1/2).",
   "Nordic terminals: 16 = D+, 17 = D-, 18 = Ref (G0). Cable length 30 m maximum.",
   "Supported function codes: 03, 04, 06 and 16; up to 125 registers per read and 123 per write."
  ],
  "gotchas": [
   "If 4x9001 reads 2 (configuration mode) the other registers do not answer.",
   "A write that is out of range is clamped: the controller replies with the value actually stored, so read back after writing.",
   "A bulk read across a gap between defined registers fails with exception 02; read separate blocks.",
   "Temporary High and fireplace modes are started by writing 2 to 4x3006/4x3007, not by 4x2013."
  ]
 },
 "page": "https://easymodbus.com/modbus-register-maps/flexit/nordic",
 "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."
}
