{
  "$schema": "https://raw.githubusercontent.com/nobrega8/mbmap-library/main/schema/mbmap-2.schema.json",
  "mbmap": 2,
  "vendor": "Electron do Brasil",
  "model": "EP4 IoT",
  "models": [
    "EP4 IoT",
    "EP4"
  ],
  "vendor_website": "electron.com.br",
  "description": "Thermal protection relay (ANSI 23, 26, 38, 45, 49, 74, 77, 94) with four temperature sensors, alarm, shutdown, fault and ventilation relays, analog output and Modbus RTU",
  "revision": 1,
  "revised": "2026-11-10",
  "source": "Electron do Brasil, Mapa de Registradores MODBUS RTU, Relé de Proteção Térmica EP4 IoT",
  "sources": [
    {
      "title": "Mapa de Registradores MODBUS RTU, Relé de Proteção Térmica EP4 IoT",
      "url": "https://electron.com.br/api/downloads/file/mapa_de_registradores_modbus_rtu_ep4_iot-2.pdf",
      "note": "linked in issue #129; the document linked for the EP3 in issue #128 has the same text"
    }
  ],
  "notes": [
    "All registers are holding registers. The document numbers them 1 to 99 and calls the type Holding Register (40.000), so the addresses are 1-based (address on the wire = number minus 1). The document does not say so explicitly: if a read fails, try address_base 0.",
    "The document allows 2400 to 57600 bps with automatic baud rate detection, 8 data bits and 1 stop bit. It gives no parity, default baud rate or slave address: 9600 N and 1 are placeholders; the slave address is in register 50.",
    "Temperatures are shown in the document with one decimal and a scale of -1000:10, which it does not explain. They are given as raw values: check against the display before applying a scale.",
    "Registers 26, 42, 43, 45, 46, 47, 48, 49 and 61 are bit fields, one entry per bit. The command bits are write-only. Registers 80 to 83 (map latitude, two registers each, both labelled latitude) and the maximum current-output temperature of sensor 4 are not in the document or not clear, so they are left out.",
    "The EP3 IoT document linked in issue #128 has exactly the same content and title (EP4 IoT), so this map may not match an EP3 IoT.",
    "Written from the manufacturer's document; not tested on a device."
  ],
  "protocol": "rtu",
  "unit_id": 1,
  "baudrate": 9600,
  "parity": "N",
  "databits": 8,
  "stopbits": 1,
  "address_base": 1,
  "byte_order": "big",
  "word_order": "big",
  "x_status": "official",
  "enums": {
    "forced_vent": {"0": "Disabled", "1": "Enabled"},
    "exercise": {"0": "Off", "1": "On"},
    "display_mode": {"0": "Hot", "1": "Scan", "2": "Manual"},
    "relay_logic": {"0": "Normal", "1": "Inverse"},
    "rs485_protection": {"0": "Write protection disabled", "1": "Write protection enabled"},
    "analog_source": {"0": "Off", "1": "Sensor 1", "2": "Sensor 2", "3": "Sensor 3", "4": "Sensor 4", "5": "Highest temperature (HOT function)", "6": "Scan"}
  },
  "registers": [
    {"name": "Alarm temperature sensor 1", "group": "Settings", "area": "holding", "address": 1, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Alarm temperature sensor 2", "group": "Settings", "area": "holding", "address": 2, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Alarm temperature sensor 3", "group": "Settings", "area": "holding", "address": 3, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Alarm temperature sensor 4", "group": "Settings", "area": "holding", "address": 4, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Alarm hysteresis", "group": "Settings", "area": "holding", "address": 9, "type": "uint16", "scale": 0.1, "access": "RW", "write_min": 0, "write_max": 10, "description": "Range 0 to 10.0"},
    {"name": "Shutdown temperature sensor 1", "group": "Settings", "area": "holding", "address": 10, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Shutdown temperature sensor 2", "group": "Settings", "area": "holding", "address": 11, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Shutdown temperature sensor 3", "group": "Settings", "area": "holding", "address": 12, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Shutdown temperature sensor 4", "group": "Settings", "area": "holding", "address": 13, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Shutdown delay", "group": "Settings", "area": "holding", "address": 18, "type": "uint16", "unit": "min", "access": "RW", "write_min": 0, "write_max": 20},
    {"name": "Cooling temperature sensor 1", "group": "Settings", "area": "holding", "address": 19, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Cooling temperature sensor 2", "group": "Settings", "area": "holding", "address": 20, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Cooling temperature sensor 3", "group": "Settings", "area": "holding", "address": 21, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Cooling temperature sensor 4", "group": "Settings", "area": "holding", "address": 22, "type": "uint16", "access": "RW", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Forced ventilation", "group": "Settings", "area": "holding", "address": 24, "type": "uint16", "access": "RW", "enum": "forced_vent"},
    {"name": "Ventilation exercise", "group": "Settings", "area": "holding", "address": 25, "type": "uint16", "access": "RW", "enum": "exercise"},
    {"name": "Reset maximum temperatures", "group": "Commands", "area": "holding", "address": 26, "type": "bool", "bit": 0, "access": "W", "description": "Write 1"},
    {"name": "Reset equipment", "group": "Commands", "area": "holding", "address": 26, "type": "bool", "bit": 1, "access": "W", "description": "Write 1"},
    {"name": "Cooling shutdown hysteresis", "group": "Settings", "area": "holding", "address": 27, "type": "uint16", "scale": 0.1, "access": "RW", "write_min": 0, "write_max": 30, "description": "Range 0 to 30.0"},
    {"name": "Display mode", "group": "Settings", "area": "holding", "address": 28, "type": "uint16", "access": "RW", "enum": "display_mode"},
    {"name": "Temperature sensor 1", "group": "Measurements", "area": "holding", "address": 29, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature sensor 2", "group": "Measurements", "area": "holding", "address": 30, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature sensor 3", "group": "Measurements", "area": "holding", "address": 31, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature sensor 4", "group": "Measurements", "area": "holding", "address": 32, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature offset sensor 1", "group": "Settings", "area": "holding", "address": 33, "type": "int16", "access": "RW", "description": "Range -10.0 to 10.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature offset sensor 2", "group": "Settings", "area": "holding", "address": 34, "type": "int16", "access": "RW", "description": "Range -10.0 to 10.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature offset sensor 3", "group": "Settings", "area": "holding", "address": 35, "type": "int16", "access": "RW", "description": "Range -10.0 to 10.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Temperature offset sensor 4", "group": "Settings", "area": "holding", "address": 36, "type": "int16", "access": "RW", "description": "Range -10.0 to 10.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Maximum temperature sensor 1", "group": "Measurements", "area": "holding", "address": 37, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Maximum temperature sensor 2", "group": "Measurements", "area": "holding", "address": 38, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Maximum temperature sensor 3", "group": "Measurements", "area": "holding", "address": 39, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Maximum temperature sensor 4", "group": "Measurements", "area": "holding", "address": 40, "type": "uint16", "access": "R", "description": "Range 0 to 200.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Sensor 1 enabled", "group": "Settings", "area": "holding", "address": 42, "type": "bool", "bit": 0, "access": "RW"},
    {"name": "Sensor 2 enabled", "group": "Settings", "area": "holding", "address": 42, "type": "bool", "bit": 1, "access": "RW"},
    {"name": "Sensor 3 enabled", "group": "Settings", "area": "holding", "address": 42, "type": "bool", "bit": 2, "access": "RW"},
    {"name": "Sensor 4 enabled", "group": "Settings", "area": "holding", "address": 42, "type": "bool", "bit": 3, "access": "RW"},
    {"name": "Relay 1 logic (alarm)", "group": "Settings", "area": "holding", "address": 43, "type": "bool", "bit": 0, "access": "RW", "enum": "relay_logic"},
    {"name": "Relay 2 logic (shutdown)", "group": "Settings", "area": "holding", "address": 43, "type": "bool", "bit": 1, "access": "RW", "enum": "relay_logic"},
    {"name": "Relay 3 logic (fault)", "group": "Settings", "area": "holding", "address": 43, "type": "bool", "bit": 2, "access": "RW", "enum": "relay_logic"},
    {"name": "Relay 4 logic (ventilation)", "group": "Settings", "area": "holding", "address": 43, "type": "bool", "bit": 3, "access": "RW", "enum": "relay_logic", "description": "The document lists value 1 as Normal for this relay: taken to be a typing error"},
    {"name": "High temperature alarm sensor 1", "group": "Status", "area": "holding", "address": 45, "type": "bool", "bit": 0, "access": "R"},
    {"name": "High temperature alarm sensor 2", "group": "Status", "area": "holding", "address": 45, "type": "bool", "bit": 1, "access": "R"},
    {"name": "High temperature alarm sensor 3", "group": "Status", "area": "holding", "address": 45, "type": "bool", "bit": 2, "access": "R"},
    {"name": "High temperature alarm sensor 4", "group": "Status", "area": "holding", "address": 45, "type": "bool", "bit": 3, "access": "R"},
    {"name": "Shutdown counting sensor 1", "group": "Status", "area": "holding", "address": 46, "type": "bool", "bit": 0, "access": "R"},
    {"name": "Shutdown counting sensor 2", "group": "Status", "area": "holding", "address": 46, "type": "bool", "bit": 1, "access": "R"},
    {"name": "Shutdown counting sensor 3", "group": "Status", "area": "holding", "address": 46, "type": "bool", "bit": 2, "access": "R"},
    {"name": "Shutdown counting sensor 4", "group": "Status", "area": "holding", "address": 46, "type": "bool", "bit": 3, "access": "R", "description": "Sensor 4 is the ambient sensor"},
    {"name": "Shutdown by high temperature sensor 1", "group": "Status", "area": "holding", "address": 47, "type": "bool", "bit": 0, "access": "R"},
    {"name": "Shutdown by high temperature sensor 2", "group": "Status", "area": "holding", "address": 47, "type": "bool", "bit": 1, "access": "R"},
    {"name": "Shutdown by high temperature sensor 3", "group": "Status", "area": "holding", "address": 47, "type": "bool", "bit": 2, "access": "R"},
    {"name": "Shutdown by high temperature sensor 4", "group": "Status", "area": "holding", "address": 47, "type": "bool", "bit": 3, "access": "R", "description": "Sensor 4 is the ambient sensor"},
    {"name": "Fan on by sensor 1", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 0, "access": "R"},
    {"name": "Fan on by sensor 2", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 1, "access": "R"},
    {"name": "Fan on by sensor 3", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 2, "access": "R"},
    {"name": "Fan on by sensor 4", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 3, "access": "R"},
    {"name": "Fan on by forced ventilation", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 4, "access": "R"},
    {"name": "Fan on by sensor reading failure", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 6, "access": "R"},
    {"name": "Fan on by ventilation exercise", "group": "Status", "area": "holding", "address": 48, "type": "bool", "bit": 7, "access": "R"},
    {"name": "Reading failure sensor 1", "group": "Status", "area": "holding", "address": 49, "type": "bool", "bit": 0, "access": "R"},
    {"name": "Reading failure sensor 2", "group": "Status", "area": "holding", "address": 49, "type": "bool", "bit": 1, "access": "R"},
    {"name": "Reading failure sensor 3", "group": "Status", "area": "holding", "address": 49, "type": "bool", "bit": 2, "access": "R"},
    {"name": "Reading failure sensor 4", "group": "Status", "area": "holding", "address": 49, "type": "bool", "bit": 3, "access": "R"},
    {"name": "Serial network address", "group": "Device", "area": "holding", "address": 50, "type": "uint16", "access": "R", "description": "Range 1 to 254"},
    {"name": "RS-485 write protection", "group": "Settings", "area": "holding", "address": 51, "type": "uint16", "access": "RW", "enum": "rs485_protection"},
    {"name": "Analog output source", "group": "Analog output", "area": "holding", "address": 60, "type": "uint16", "access": "RW", "write_min": 0, "write_max": 6, "enum": "analog_source"},
    {"name": "Hot current output includes sensor 1", "group": "Analog output", "area": "holding", "address": 61, "type": "bool", "bit": 0, "access": "RW"},
    {"name": "Hot current output includes sensor 2", "group": "Analog output", "area": "holding", "address": 61, "type": "bool", "bit": 1, "access": "RW"},
    {"name": "Hot current output includes sensor 3", "group": "Analog output", "area": "holding", "address": 61, "type": "bool", "bit": 2, "access": "RW"},
    {"name": "Hot current output includes sensor 4", "group": "Analog output", "area": "holding", "address": 61, "type": "bool", "bit": 3, "access": "RW"},
    {"name": "Current output scan time", "group": "Analog output", "area": "holding", "address": 62, "type": "uint16", "scale": 500, "unit": "ms", "access": "RW", "write_min": 5, "write_max": 50, "description": "The value is the number of 500 ms periods; range 5 to 50"},
    {"name": "Current output correction", "group": "Analog output", "area": "holding", "address": 63, "type": "int16", "access": "RW", "description": "Range -1.00 to 1.00; the document's scale column (-1000:100) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output minimum temperature sensor 1", "group": "Analog output", "area": "holding", "address": 70, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output minimum temperature sensor 2", "group": "Analog output", "area": "holding", "address": 71, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output minimum temperature sensor 3", "group": "Analog output", "area": "holding", "address": 72, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output minimum temperature sensor 4", "group": "Analog output", "area": "holding", "address": 73, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output maximum temperature sensor 1", "group": "Analog output", "area": "holding", "address": 75, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output maximum temperature sensor 2", "group": "Analog output", "area": "holding", "address": 76, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Current output maximum temperature sensor 3", "group": "Analog output", "area": "holding", "address": 77, "type": "uint16", "access": "RW", "description": "Range 0 to 2000; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Internal temperature", "group": "Measurements", "area": "holding", "address": 92, "type": "int16", "access": "R", "description": "Range -50.0 to 250.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Maximum internal temperature", "group": "Measurements", "area": "holding", "address": 93, "type": "int16", "access": "R", "description": "Range -50.0 to 250.0; the document's scale column (-1000:10) is not explained, so the value is raw (check against the display)"},
    {"name": "Calibration day", "group": "Device", "area": "holding", "address": 94, "type": "uint16", "access": "R", "description": "Range 1 to 31"},
    {"name": "Calibration month", "group": "Device", "area": "holding", "address": 95, "type": "uint16", "access": "R", "description": "Range 1 to 12"},
    {"name": "Calibration year", "group": "Device", "area": "holding", "address": 96, "type": "uint16", "access": "R", "description": "Range 2020 to 2099"},
    {"name": "Serial number", "group": "Device", "area": "holding", "address": 97, "type": "uint32", "access": "R", "role": "serial", "description": "Registers 97 (MSB) and 98 (LSB)"},
    {"name": "Password reminder", "group": "Device", "area": "holding", "address": 99, "type": "uint16", "access": "R", "description": "Range 0 to 999"}
  ]
}
