{
  "$schema": "https://raw.githubusercontent.com/nobrega8/mbmap-library/main/schema/mbmap-2.schema.json",
  "mbmap": 2,
  "vendor": "Treetech",
  "model": "TM",
  "models": ["TM"],
  "vendor_website": "treetech.com.br",
  "description": "Transformer temperature monitor: RTD, oil, winding and OLTC temperatures, load and current per winding, cooling stage, alarms, relay states and identity",
  "revision": 1,
  "revised": "2026-11-08",
  "firmware": "1.03 r1",
  "source": "Treetech TM Mapa de Protocolos de Comunicação MAP-088, rev. 1.01",
  "sources": [
    {"title": "TM - Monitor de Temperaturas: Mapa de Protocolos de Comunicação (MAP-088)", "version": "1.01", "date": "2024-07-18", "url": "https://treetech.com.br/wp-content/uploads/2024/07/Treetech_TM_mapa_de_protocolo_pt_1.01.pdf", "note": "section 2 (Modbus); linked in issue #151"}
  ],
  "notes": [
    "Modbus RTU on RS-485, FC01-FC06, FC15 and FC16. Addresses are 0-based, as sent on the wire.",
    "Baud rate is selectable (4800 to 115200 bit/s), 8 data bits, no parity, 1 or 2 stop bits (detected automatically). The document gives no factory default for the baud rate or the address; 9600 and 1 are assumed here.",
    "The document lists every value as a 16-bit word without stating a scale. Scales here are read from the documented ranges: temperatures and load are whole numbers, the winding current (0 to 655.35 kA) is in hundredths. The secondary current, the 48-bit timestamps and most settings are left out because their scale is not clear.",
    "Winding 2 and 3 values only apply when the device is set for three windings (input register 1).",
    "The document was written for firmware 1.03 r1. Written from that document; this map has not been tested on a device."
  ],
  "protocol": "rtu",
  "unit_id": 1,
  "baudrate": 9600,
  "parity": "N",
  "databits": 8,
  "stopbits": 1,
  "byte_order": "big",
  "word_order": "big",
  "address_base": 0,
  "x_status": "official",
  "enums": {
    "device_status": {"0": "Normal", "1": "Maintenance", "2": "Major alarm", "3": "Medium alarm", "4": "Minor alarm", "5": "Starting"},
    "windings": {"0": "1 winding", "1": "3 windings"},
    "cooling_stage": {"1": "No stage active", "2": "Stage 1 active", "3": "Stage 2 active"},
    "baud_rate": {"0": "4800", "1": "9600", "2": "19200", "3": "38400", "4": "57600", "5": "115200"},
    "uart_protocol": {"1": "Modbus", "2": "DNP3"},
    "relay_state": {"0": "Open", "1": "Closed"},
    "quality": {"0": "Bad", "1": "Good"},
    "cooling_group_state": {"0": "Automatic", "1": "On"}
  },
  "registers": [
    {"name": "Device status", "group": "Status", "area": "input", "address": 0, "type": "uint16", "enum": "device_status"},
    {"name": "Function", "group": "Status", "area": "input", "address": 1, "type": "uint16", "enum": "windings", "description": "One or three windings"},

    {"name": "Sensor 1 temperature", "group": "RTD sensors", "area": "input", "address": 10000, "type": "int16", "unit": "°C"},
    {"name": "Sensor 1 maximum temperature", "group": "RTD sensors", "area": "input", "address": 10001, "type": "int16", "unit": "°C"},
    {"name": "Sensor 2 temperature", "group": "RTD sensors", "area": "input", "address": 10002, "type": "int16", "unit": "°C"},
    {"name": "Sensor 2 maximum temperature", "group": "RTD sensors", "area": "input", "address": 10003, "type": "int16", "unit": "°C"},

    {"name": "Oil temperature", "group": "Oil", "area": "input", "address": 10100, "type": "int16", "unit": "°C"},
    {"name": "Oil maximum temperature", "group": "Oil", "area": "input", "address": 10101, "type": "int16", "unit": "°C"},
    {"name": "Oil trip delay remaining", "group": "Oil", "area": "input", "address": 10105, "type": "uint16", "unit": "min", "description": "Time left before the oil temperature trip"},

    {"name": "Winding 1 temperature", "group": "Winding 1", "area": "input", "address": 10200, "type": "int16", "unit": "°C"},
    {"name": "Winding 1 maximum temperature", "group": "Winding 1", "area": "input", "address": 10201, "type": "int16", "unit": "°C"},
    {"name": "Winding 1 trip delay remaining", "group": "Winding 1", "area": "input", "address": 10205, "type": "uint16", "unit": "min"},
    {"name": "Winding 1 final gradient", "group": "Winding 1", "area": "input", "address": 10206, "type": "int16", "unit": "°C", "description": "Final winding-to-oil temperature gradient"},
    {"name": "Winding 1 load", "group": "Winding 1", "area": "input", "address": 10207, "type": "uint16", "unit": "%"},
    {"name": "Winding 1 current", "group": "Winding 1", "area": "input", "address": 10208, "type": "uint16", "scale": 0.01, "unit": "kA"},

    {"name": "Winding 2 temperature", "group": "Winding 2", "area": "input", "address": 10300, "type": "int16", "unit": "°C"},
    {"name": "Winding 2 maximum temperature", "group": "Winding 2", "area": "input", "address": 10301, "type": "int16", "unit": "°C"},
    {"name": "Winding 2 trip delay remaining", "group": "Winding 2", "area": "input", "address": 10305, "type": "uint16", "unit": "min"},
    {"name": "Winding 2 final gradient", "group": "Winding 2", "area": "input", "address": 10306, "type": "int16", "unit": "°C"},
    {"name": "Winding 2 load", "group": "Winding 2", "area": "input", "address": 10307, "type": "uint16", "unit": "%"},
    {"name": "Winding 2 current", "group": "Winding 2", "area": "input", "address": 10308, "type": "uint16", "scale": 0.01, "unit": "kA"},

    {"name": "Winding 3 temperature", "group": "Winding 3", "area": "input", "address": 10400, "type": "int16", "unit": "°C"},
    {"name": "Winding 3 maximum temperature", "group": "Winding 3", "area": "input", "address": 10401, "type": "int16", "unit": "°C"},
    {"name": "Winding 3 trip delay remaining", "group": "Winding 3", "area": "input", "address": 10405, "type": "uint16", "unit": "min"},
    {"name": "Winding 3 final gradient", "group": "Winding 3", "area": "input", "address": 10406, "type": "int16", "unit": "°C"},
    {"name": "Winding 3 load", "group": "Winding 3", "area": "input", "address": 10407, "type": "uint16", "unit": "%"},
    {"name": "Winding 3 current", "group": "Winding 3", "area": "input", "address": 10408, "type": "uint16", "scale": 0.01, "unit": "kA"},

    {"name": "Cooling stage", "group": "Cooling", "area": "input", "address": 10500, "type": "uint16", "enum": "cooling_stage"},
    {"name": "Fan exercise time remaining", "group": "Cooling", "area": "input", "address": 10501, "type": "uint16", "unit": "s"},
    {"name": "Cooling group 1 state", "group": "Cooling", "area": "discrete", "address": 10700, "type": "bool", "enum": "cooling_group_state"},
    {"name": "Cooling group 2 state", "group": "Cooling", "area": "discrete", "address": 10701, "type": "bool", "enum": "cooling_group_state"},
    {"name": "Cooling stage set by temperature", "group": "Cooling", "area": "discrete", "address": 10702, "type": "bool"},
    {"name": "Cooling stage set by load", "group": "Cooling", "area": "discrete", "address": 10703, "type": "bool"},

    {"name": "OLTC learning time remaining", "group": "OLTC differential", "area": "input", "address": 10600, "type": "uint16", "unit": "min", "description": "Time left in the automatic learning of the differential alarms"},
    {"name": "Main tank oil temperature for differential", "group": "OLTC differential", "area": "input", "address": 10601, "type": "int16", "unit": "°C"},
    {"name": "OLTC oil temperature", "group": "OLTC differential", "area": "input", "address": 10602, "type": "int16", "unit": "°C"},
    {"name": "OLTC oil maximum temperature", "group": "OLTC differential", "area": "input", "address": 10603, "type": "int16", "unit": "°C"},
    {"name": "Instantaneous differential", "group": "OLTC differential", "area": "input", "address": 10604, "type": "int16", "unit": "°C"},
    {"name": "Instantaneous differential minimum", "group": "OLTC differential", "area": "input", "address": 10605, "type": "int16", "unit": "°C"},
    {"name": "Instantaneous differential maximum", "group": "OLTC differential", "area": "input", "address": 10606, "type": "int16", "unit": "°C"},
    {"name": "Filtered differential", "group": "OLTC differential", "area": "input", "address": 10607, "type": "int16", "unit": "°C"},
    {"name": "Filtered differential minimum", "group": "OLTC differential", "area": "input", "address": 10608, "type": "int16", "unit": "°C"},
    {"name": "Filtered differential maximum", "group": "OLTC differential", "area": "input", "address": 10609, "type": "int16", "unit": "°C"},

    {"name": "Oil temperature high alarm", "group": "Alarms", "area": "discrete", "address": 10104, "type": "bool"},
    {"name": "Oil temperature high alarm memory", "group": "Alarms", "area": "discrete", "address": 10105, "type": "bool"},
    {"name": "Oil temperature trip", "group": "Alarms", "area": "discrete", "address": 10106, "type": "bool"},
    {"name": "Oil temperature trip memory", "group": "Alarms", "area": "discrete", "address": 10107, "type": "bool"},
    {"name": "Oil temperature trip countdown", "group": "Alarms", "area": "discrete", "address": 10108, "type": "bool", "description": "The trip delay is counting"},
    {"name": "Winding 1 temperature high alarm", "group": "Alarms", "area": "discrete", "address": 10202, "type": "bool"},
    {"name": "Winding 1 temperature trip", "group": "Alarms", "area": "discrete", "address": 10204, "type": "bool"},
    {"name": "Winding 1 temperature trip countdown", "group": "Alarms", "area": "discrete", "address": 10206, "type": "bool"},
    {"name": "Winding 2 temperature high alarm", "group": "Alarms", "area": "discrete", "address": 10302, "type": "bool"},
    {"name": "Winding 2 temperature trip", "group": "Alarms", "area": "discrete", "address": 10304, "type": "bool"},
    {"name": "Winding 2 temperature trip countdown", "group": "Alarms", "area": "discrete", "address": 10306, "type": "bool"},
    {"name": "Winding 3 temperature high alarm", "group": "Alarms", "area": "discrete", "address": 10402, "type": "bool"},
    {"name": "Winding 3 temperature trip", "group": "Alarms", "area": "discrete", "address": 10404, "type": "bool"},
    {"name": "Winding 3 temperature trip countdown", "group": "Alarms", "area": "discrete", "address": 10406, "type": "bool"},
    {"name": "OLTC instantaneous differential alarm", "group": "Alarms", "area": "discrete", "address": 10503, "type": "bool"},
    {"name": "OLTC filtered differential alarm", "group": "Alarms", "area": "discrete", "address": 10505, "type": "bool"},

    {"name": "RTD reading internal fault", "group": "Self-diagnostics", "area": "discrete", "address": 10000, "type": "bool"},
    {"name": "RTD1 reading fault", "group": "Self-diagnostics", "area": "discrete", "address": 10002, "type": "bool"},
    {"name": "RTD2 reading fault", "group": "Self-diagnostics", "area": "discrete", "address": 10012, "type": "bool"},
    {"name": "Redundant sensors difference", "group": "Self-diagnostics", "area": "discrete", "address": 10100, "type": "bool", "description": "The two oil sensors differ by more than the set maximum"},
    {"name": "Flash write fault", "group": "Self-diagnostics", "area": "discrete", "address": 0, "type": "bool"},
    {"name": "Relay settings fault", "group": "Self-diagnostics", "area": "discrete", "address": 2, "type": "bool"},
    {"name": "Settings quality", "group": "Self-diagnostics", "area": "discrete", "address": 4, "type": "bool", "enum": "quality"},
    {"name": "Settings fault", "group": "Self-diagnostics", "area": "discrete", "address": 5, "type": "bool"},
    {"name": "Oil temperature quality", "group": "Self-diagnostics", "area": "discrete", "address": 10110, "type": "bool", "enum": "quality"},
    {"name": "Winding 1 temperature quality", "group": "Self-diagnostics", "area": "discrete", "address": 10208, "type": "bool", "enum": "quality"},
    {"name": "Winding 2 temperature quality", "group": "Self-diagnostics", "area": "discrete", "address": 10308, "type": "bool", "enum": "quality"},
    {"name": "Winding 3 temperature quality", "group": "Self-diagnostics", "area": "discrete", "address": 10408, "type": "bool", "enum": "quality"},
    {"name": "USB write locked", "group": "Self-diagnostics", "area": "discrete", "address": 29, "type": "bool"},

    {"name": "Relay 1", "group": "Relays", "area": "discrete", "address": 21, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 2", "group": "Relays", "area": "discrete", "address": 22, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 3", "group": "Relays", "area": "discrete", "address": 23, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 4", "group": "Relays", "area": "discrete", "address": 24, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 5", "group": "Relays", "area": "discrete", "address": 25, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 6", "group": "Relays", "area": "discrete", "address": 26, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 7", "group": "Relays", "area": "discrete", "address": 27, "type": "bool", "enum": "relay_state"},
    {"name": "Relay 8", "group": "Relays", "area": "discrete", "address": 28, "type": "bool", "enum": "relay_state"},

    {"name": "Reset alarm memory", "group": "Commands", "area": "coil", "address": 4, "type": "bool", "access": "W", "description": "Write 1 to clear the alarm memory (part 1)"},
    {"name": "Reset oil maximum temperature", "group": "Commands", "area": "coil", "address": 5, "type": "bool", "access": "W", "description": "Write 1 to reset"},
    {"name": "Reset winding 1 maximum temperature", "group": "Commands", "area": "coil", "address": 6, "type": "bool", "access": "W", "description": "Write 1 to reset"},
    {"name": "Reset winding 2 maximum temperature", "group": "Commands", "area": "coil", "address": 7, "type": "bool", "access": "W", "description": "Write 1 to reset"},
    {"name": "Reset winding 3 maximum temperature", "group": "Commands", "area": "coil", "address": 8, "type": "bool", "access": "W", "description": "Write 1 to reset"},
    {"name": "Reset OLTC oil maximum temperature", "group": "Commands", "area": "coil", "address": 15, "type": "bool", "access": "W", "description": "Write 1 to reset"},

    {"name": "Oil temperature alarm setpoint", "group": "Settings", "area": "holding", "address": 10100, "type": "int16", "unit": "°C", "access": "RW", "write_min": -55, "write_max": 200},
    {"name": "Oil temperature trip setpoint", "group": "Settings", "area": "holding", "address": 10101, "type": "int16", "unit": "°C", "access": "RW", "write_min": -55, "write_max": 200},
    {"name": "Oil temperature trip delay", "group": "Settings", "area": "holding", "address": 10102, "type": "uint16", "unit": "min", "access": "RW", "write_min": 0, "write_max": 20},
    {"name": "Winding 1 temperature alarm setpoint", "group": "Settings", "area": "holding", "address": 10200, "type": "int16", "unit": "°C", "access": "RW", "write_min": -55, "write_max": 200},
    {"name": "Winding 1 temperature trip setpoint", "group": "Settings", "area": "holding", "address": 10201, "type": "int16", "unit": "°C", "access": "RW", "write_min": -55, "write_max": 200},
    {"name": "CT1 ratio", "group": "Settings", "area": "holding", "address": 400, "type": "uint16", "access": "RW", "write_min": 1, "write_max": 10000},
    {"name": "CT2 ratio", "group": "Settings", "area": "holding", "address": 401, "type": "uint16", "access": "RW", "write_min": 1, "write_max": 10000},
    {"name": "CT3 ratio", "group": "Settings", "area": "holding", "address": 402, "type": "uint16", "access": "RW", "write_min": 1, "write_max": 10000},

    {"name": "UART1 baud rate", "group": "Communication", "area": "holding", "address": 500, "type": "uint16", "enum": "baud_rate", "access": "RW"},
    {"name": "UART1 protocol", "group": "Communication", "area": "holding", "address": 501, "type": "uint16", "enum": "uart_protocol", "access": "RW"},
    {"name": "UART1 address", "group": "Communication", "area": "holding", "address": 502, "type": "uint16", "access": "RW", "write_min": 1, "write_max": 65519, "description": "Applied with the key in register 505"},
    {"name": "UART2 baud rate", "group": "Communication", "area": "holding", "address": 506, "type": "uint16", "enum": "baud_rate", "access": "RW"},
    {"name": "UART2 protocol", "group": "Communication", "area": "holding", "address": 507, "type": "uint16", "enum": "uart_protocol", "access": "RW"},
    {"name": "UART2 address", "group": "Communication", "area": "holding", "address": 508, "type": "uint16", "access": "RW", "write_min": 1, "write_max": 65519, "description": "Applied with the key in register 511"},

    {"name": "Serial number", "group": "Identity", "area": "input", "address": 45000, "type": "uint32", "role": "serial"},
    {"name": "Firmware version", "group": "Identity", "area": "input", "address": 45002, "type": "uint16", "description": "Lower board"},
    {"name": "Firmware release", "group": "Identity", "area": "input", "address": 45003, "type": "uint16", "description": "Lower board"},
    {"name": "Bootloader version", "group": "Identity", "area": "input", "address": 45004, "type": "uint16"},
    {"name": "Bootloader release", "group": "Identity", "area": "input", "address": 45005, "type": "uint16"},
    {"name": "Device code", "group": "Identity", "area": "input", "address": 45006, "type": "uint16"},

    {"name": "Time zone", "group": "Clock", "area": "input", "address": 45100, "type": "int16", "unit": "h"},
    {"name": "Day", "group": "Clock", "area": "input", "address": 45101, "type": "uint16"},
    {"name": "Month", "group": "Clock", "area": "input", "address": 45102, "type": "uint16"},
    {"name": "Year", "group": "Clock", "area": "input", "address": 45103, "type": "uint16"},
    {"name": "Hour", "group": "Clock", "area": "input", "address": 45104, "type": "uint16"},
    {"name": "Minute", "group": "Clock", "area": "input", "address": 45105, "type": "uint16"},
    {"name": "Second", "group": "Clock", "area": "input", "address": 45106, "type": "uint16"}
  ]
}
