{
 "manufacturer": "Carlo Gavazzi",
 "manufacturer_slug": "carlo-gavazzi",
 "model": "EM271 dual three-phase energy meter with TCD current sensors",
 "model_slug": "em271",
 "short_model": "EM271",
 "aliases": [
  "EM271",
  "EM27172DMV53X2SX",
  "EM27172DMV63X2SX"
 ],
 "equipment_type": "Energy meter",
 "applies_to": "EM271 (firmware r.d0+, PF values from r.d2) on RS485 Modbus RTU, per communication protocol version 1 revision 2 (2018-01-29).",
 "summary": "The EM271 is an energy meter that measures two loads through two TCD current-sensor inputs (TCDA1, TCDA2), as two three-phase loads or up to six single-phase loads. Values are 32-bit integers sent low word first with fixed scaling. This map covers voltages, per-input currents, power and energy, the SUM totals, PF, identification and the measuring-system, RS485 and reset registers.",
 "transport": [
  "RTU"
 ],
 "defaults": {
  "unit_id": null,
  "baud": null,
  "parity": null,
  "data_bits": null,
  "stop_bits": 1,
  "tcp_port": null
 },
 "addressing": {
  "convention": "Modicon",
  "note": "Each row shows a 6-digit Modicon number for function 04 (3xxxxx; replace the first digit with 4 for function 03) next to the hex 'physical address' that the document says goes in the frame. Wire address = physical address: 300269 / 010Ch is requested as 0x010C."
 },
 "default_word_order": "CDAB",
 "firmware": "r.d0+ (PF values from r.d2)",
 "source": {
  "title": "EM271 Communication Protocol",
  "doc_number": "Version 1 Revision 2",
  "revision_date": "2018-01-29",
  "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/OTHERSTUFF/COMPRO/EM271_CP.pdf",
  "pages": "Functions pp. 3-5; data format p. 7; instantaneous table pp. 8-9; version, keypad p. 9; ID and settings pp. 10-12; serial and year p. 13"
 },
 "notes": [
  "Word order: the data-format section states that the byte order inside a word is MSB first and that INT32, UINT32 and UINT64 values are sent LSW first, so all 32-bit values here are CDAB.",
  "Scaling is taken from the Notes column: Volt*10, Ampere*1000, Watt*10, VA*10, var*10, kWh*10, kvarh*10 and PF*1000, so the scales are 0.1, 0.001, 0.1, 0.1, 0.1, 0.1, 0.1 and 0.001.",
  "Availability depends on the measuring system (3P 1.3P, 3P 2.3P, 3P 3.1P, 3P 6.1P, 1P 3.1P, 1P 6.1P); the document marks some values as available only when the SUM function is on. Values are valid only when the same variable is shown on the meter display.",
  "Functions 03 and 04 return the same data. The text allows up to 18 registers per read, but the request-frame table prints '1 to 10h (1 to 11)', so keep each read to 16 registers or fewer. The version, keypad and ID registers may only be read one word at a time. Writes use function 06 only.",
  "Setting rows (1000h onwards) are printed with 3xxxxx Modicon numbers but are written with function 06, so they are listed as holding registers.",
  "Left out: per-phase demand and max-demand values, VA demand, per-phase var, per-phase PF, kWh(+) L2/L3 per TCD input, password, VT ratio and CT-type rows (model- and TCD-dependent tables), pulse output settings, easy-connection and TCD phase-order menus, and the UINT32 secondary address.",
  "1003h/1004h report the detected TCD primary current in amperes (65535 = no TCD, 0 = TCDMM detected) and 1023h/1024h set the primary for TCDMM sensors; these rows are left out.",
  "The serial port uses a fixed 1 stop bit; baud (9600/19200/38400) and parity (none/even) are set at 2001h/2002h.",
  "The ID code at 000Bh shares its address with the second word of V L3-L1 (000Ah-000Bh); the document prints both. Read 000Bh on its own, one word per request, as the ID table requires."
 ],
 "registers": [
  {
   "table": "input_register",
   "address": 0,
   "documented": "300001 / 0000h",
   "name": "V L1-N",
   "description": "Also the L-N voltage in single-phase systems.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 2,
   "documented": "300003 / 0002h",
   "name": "V L2-N",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 4,
   "documented": "300005 / 0004h",
   "name": "V L3-N",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 6,
   "documented": "300007 / 0006h",
   "name": "V L1-L2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 8,
   "documented": "300009 / 0008h",
   "name": "V L2-L3",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 10,
   "documented": "300011 / 000Ah",
   "name": "V L3-L1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "V",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 11,
   "documented": "300012 / 000Bh",
   "name": "Carlo Gavazzi identification code",
   "description": "Identifies the model variant.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "274": "EM27172DMV53X2SX",
    "275": "EM27172DMV53XOSX",
    "276": "EM27172DMV63X2SX",
    "277": "EM27172DMV63XOSX"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 12,
   "documented": "300013 / 000Ch",
   "name": "A L1 (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 14,
   "documented": "300015 / 000Eh",
   "name": "A L2 (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 16,
   "documented": "300017 / 0010h",
   "name": "A L3 (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 18,
   "documented": "300019 / 0012h",
   "name": "W (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 20,
   "documented": "300021 / 0014h",
   "name": "VA (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "VA",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 22,
   "documented": "300023 / 0016h",
   "name": "var (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "var",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 24,
   "documented": "300025 / 0018h",
   "name": "kWh(+) total (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 26,
   "documented": "300027 / 001Ah",
   "name": "kvarh(+) total (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kvarh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 28,
   "documented": "300029 / 001Ch",
   "name": "W demand (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 32,
   "documented": "300033 / 0020h",
   "name": "W max demand (sum)",
   "description": "Only when the SUM function is on.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 36,
   "documented": "300037 / 0024h",
   "name": "PF (sum)",
   "description": "SUM only. From firmware r.d2.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 268,
   "documented": "300269 / 010Ch",
   "name": "A L1 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 270,
   "documented": "300271 / 010Eh",
   "name": "A L2 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 272,
   "documented": "300273 / 0110h",
   "name": "A L3 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 274,
   "documented": "300275 / 0112h",
   "name": "W L1 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 276,
   "documented": "300277 / 0114h",
   "name": "W L2 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 278,
   "documented": "300279 / 0116h",
   "name": "W L3 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 280,
   "documented": "300281 / 0118h",
   "name": "W total TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 282,
   "documented": "300283 / 011Ah",
   "name": "VA total TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "VA",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 284,
   "documented": "300285 / 011Ch",
   "name": "var total TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "var",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 286,
   "documented": "300287 / 011Eh",
   "name": "kWh(+) total TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 288,
   "documented": "300289 / 0120h",
   "name": "kvarh(+) total TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kvarh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 298,
   "documented": "300299 / 012Ah",
   "name": "kWh(+) L1 TCDA1",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 328,
   "documented": "300329 / 0148h",
   "name": "PF TCDA1",
   "description": "From firmware r.d2.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 524,
   "documented": "300525 / 020Ch",
   "name": "A L1 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 526,
   "documented": "300527 / 020Eh",
   "name": "A L2 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 528,
   "documented": "300529 / 0210h",
   "name": "A L3 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "A",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 530,
   "documented": "300531 / 0212h",
   "name": "W L1 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 532,
   "documented": "300533 / 0214h",
   "name": "W L2 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 534,
   "documented": "300535 / 0216h",
   "name": "W L3 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 536,
   "documented": "300537 / 0218h",
   "name": "W total TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 538,
   "documented": "300539 / 021Ah",
   "name": "VA total TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "VA",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 540,
   "documented": "300541 / 021Ch",
   "name": "var total TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "var",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 542,
   "documented": "300543 / 021Eh",
   "name": "kWh(+) total TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 544,
   "documented": "300545 / 0220h",
   "name": "kvarh(+) total TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kvarh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 554,
   "documented": "300555 / 022Ah",
   "name": "kWh(+) L1 TCDA2",
   "description": "",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.1,
   "units": "kWh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 584,
   "documented": "300585 / 0248h",
   "name": "PF TCDA2",
   "description": "From firmware r.d2.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "CDAB",
   "scale": 0.001,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 770,
   "documented": "300771 / 0302h",
   "name": "Firmware version code",
   "description": "0 = A, 1 = B, and so on.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 771,
   "documented": "300772 / 0303h",
   "name": "Firmware revision code",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 772,
   "documented": "300773 / 0304h",
   "name": "Front selector status",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": {
    "0": "Keypad unlocked",
    "1": "Keypad locked"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 20480,
   "documented": "320481 / 5000h",
   "name": "Serial number",
   "description": "13 ASCII characters, two per register, high byte first.",
   "data_type": "STRING",
   "length": 7,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 20487,
   "documented": "320488 / 5007h",
   "name": "Production year",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 4098,
   "documented": "304099 / 1002h",
   "name": "Measuring system",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "0": "3P 1.3P",
    "1": "3P 2.3P",
    "2": "3P 3.1P",
    "3": "3P 6.1P",
    "4": "1P 3.1P",
    "5": "1P 6.1P"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 4112,
   "documented": "304113 / 1010h",
   "name": "Demand integration time",
   "description": "1-60; out-of-range values become 15.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 8192,
   "documented": "308193 / 2000h",
   "name": "RS485 instrument address",
   "description": "1-247; other values become 1.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 8193,
   "documented": "308194 / 2001h",
   "name": "RS485 baud rate",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "0": "9600",
    "1": "19200",
    "2": "38400"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 8194,
   "documented": "308195 / 2002h",
   "name": "RS485 parity",
   "description": "",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "RW",
   "values": {
    "0": "None",
    "1": "Even"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 16384,
   "documented": "316385 / 4000h",
   "name": "Reset partial meters and demand",
   "description": "Write 1 to clear partial energy, kW demand and peak demand.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "W",
   "values": {
    "1": "Execute"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 16385,
   "documented": "316386 / 4001h",
   "name": "Reset total energy meters",
   "description": "Write 1 to clear total energy.",
   "data_type": "UINT16",
   "length": 1,
   "word_order": null,
   "scale": 1,
   "units": "",
   "access": "W",
   "values": {
    "1": "Execute"
   },
   "bits": null,
   "offset": 0
  }
 ],
 "integration": {
  "summary": "Over RS485 read input registers (function 04, or 03) in short blocks: 0000h-000Ah for voltages, 010Ch-0120h for load 1 (TCDA1) and 020Ch-0220h for load 2 (TCDA2). All values are INT32 low word first with fixed scaling.",
  "minimum_registers": [
   {
    "table": "input_register",
    "address": 0,
    "why": "V L1-N (x0.1 V)"
   },
   {
    "table": "input_register",
    "address": 268,
    "why": "TCDA1 current L1 (x0.001 A)"
   },
   {
    "table": "input_register",
    "address": 280,
    "why": "TCDA1 total power (x0.1 W)"
   },
   {
    "table": "input_register",
    "address": 286,
    "why": "TCDA1 kWh(+) (x0.1 kWh)"
   },
   {
    "table": "input_register",
    "address": 536,
    "why": "TCDA2 total power"
   },
   {
    "table": "input_register",
    "address": 542,
    "why": "TCDA2 kWh(+)"
   },
   {
    "table": "input_register",
    "address": 11,
    "why": "Model ID"
   }
  ],
  "enable": "Modbus RTU runs on the built-in RS485 port. Address, baud and parity are set from the meter's configuration or written at 2000h-2002h.",
  "watchdog": null,
  "quirks": [
   "32-bit values are low word first (CDAB).",
   "Keep reads to 16 registers or fewer (the request table caps the count at 10h); ID and version words are read one at a time.",
   "Totals at 000Ch-0024h are only available with the SUM function on.",
   "Out-of-range markers: the high word (second register) reads 7FFFh on overflow, 7FFDh when the variable is not part of the selected measuring system and 7FFEh when a needed TCD is missing; the low word is then FFFFh."
  ],
  "setup": [
   "Baud options: 9600, 19200, 38400; parity none or even.",
   "Choose the measuring system (1002h) to match how the two TCD inputs are wired."
  ],
  "gotchas": [
   "A value is valid only if the meter also shows it on the display for the selected system.",
   "Maximum answer time is 500 ms; keep the master timeout above that."
  ]
 },
 "page": "https://easymodbus.com/modbus-register-maps/carlo-gavazzi/em271",
 "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."
}
