Skip to content

Modbus Example Configurations

This page collects ready-to-load Modbus slave templates that let whatwatt Go emulate several common power meters.

All example JSON files live in the local examples directory next to this page.

Available Templates

Compatibility Notes

  • siemens_pac2200.json matches the EVCC siemens-pac2200 and MBMD pac2200 paths.
  • carlo_gavazzi_em24_e1.json is aimed at EVCC cg-em24_e1 and MBMD cgem24_e1.
  • huawei_dtsu666_h.json and huawei_ddsu666_h.json follow Huawei's shared inverter-facing smart meter block at 37100. The single-phase template differs mainly by the meter type flag and zero-filled phase B/C registers.
  • huawei_smartlogger_external_meter.json and huawei_emma_external_meter.json model the higher-level register spaces exported by Huawei SmartLogger and EMMA integrations, not the raw RS485 meter wire image.
  • fronius_smart_meter_63a.json follows the Fronius Smart Meter IP emulator style used by Fronius inverter probing. It starts with a Fronius-specific SunSpec-like block at 40000 and exposes several extra zero-valued probe registers.
  • herholdt_m3pro.json follows the Herholdt M1PRO/M3PRO protocol table. Register addresses are used exactly as printed in the vendor document; some third-party Modbus tools may display or require entering N+1 for the same wire address.
  • sunspec_model_1_203.json and sunspec_model_1_213.json are suitable for EVCC templates that consume generic SunSpec meter models, including sunspec-meter, keba-kecontact, kostal-ksem, and device-specific templates that fall back to model 203 or 213.

Implementation Notes

  • The carlo_gavazzi_em24_e1.json, Huawei, Fronius, Herholdt, and SunSpec templates require FW 2.0.2 or newer.
  • The EM24_E1 template follows the Carlo Gavazzi word order rule LSW -> MSW for 32-bit values.
  • The Huawei direct meter templates fix frequency at 50.00 Hz and leave line-to-line voltages at 0, because the internal report provides phase-to-neutral voltages but no dedicated line-voltage or frequency source for the Modbus slave.
  • The Huawei SmartLogger and EMMA templates reuse the available import/export and per-phase power counters. Where Huawei publishes totals with no exact whatwatt Go equivalent, the template mirrors the closest available aggregate or keeps the field zero-filled.
  • The Fronius template intentionally zero-fills most of the trailing Model 213 block, following the reference emulator behavior where the inverter primarily consumes live total and per-phase power values.
  • The Herholdt template fixes register 4117 to floating-point mode. Herholdt's custom packed integer N8 layout is not represented; each N8 value is exposed as a float32 value in the first two registers with the trailing two registers zero-filled. Named Herholdt measurements use "scaler": 0, because the internal report already stores values in the units used by the Herholdt table.
  • Herholdt values are exposed in kWh, kW, kvar, kVA, V, A, and power factor ratio, matching the float-mode units in the vendor table.
  • The Herholdt template fills the frequency register with a fixed 50.0 Hz, because the current internal report has no live frequency source for the Modbus slave.
  • Where the internal whatwatt Go report has no direct equivalent for a vendor-specific register, the template keeps that register present and fills it with 0. This preserves contiguous address ranges expected by polling clients.
  • The SunSpec templates expose values already available from the internal report, including voltages, per-phase currents, active/reactive/apparent power, power factor, imported/exported active energy, and reactive quadrant energies.

Huawei Notes

Use one of the direct meter templates when the client expects the common Huawei smart meter block at 37100:

  • huawei_dtsu666_h.json for three-phase DTSU666-H-style polling,
  • huawei_ddsu666_h.json for single-phase DDSU666-H-style polling.

Use the SmartLogger or EMMA templates when the integration polls the higher-level Huawei gateway register maps instead:

  • huawei_smartlogger_external_meter.json exposes the external meter areas at 32260 and 32299,
  • huawei_emma_external_meter.json exposes the EMMA external meter area at 30500.

Preview:

[
  {
    "start_address": 37100,
    "word_order": "msw",
    "constants": {
      "METER_STATUS_NORMAL": 1,
      "GRID_FREQUENCY_50HZ": 50,
      "METER_TYPE_THREE_PHASE": 1,
      "METER_TYPE_CHECK_OK": 1
    },
    "registers": [
      {"id": "METER_STATUS_NORMAL", "type": "short"},
      {"id": "32.7.0", "type": "int", "scaler": 1},
      {"id": "52.7.0", "type": "int", "scaler": 1},
      {"id": "72.7.0", "type": "int", "scaler": 1},
      {"id": "31.7.0", "type": "int", "scaler": 2},
      {"id": "51.7.0", "type": "int", "scaler": 2},
      {"id": "71.7.0", "type": "int", "scaler": 2},
      {"id": "power.active", "type": "int", "scaler": 3},
      {"id": "power.reactive", "type": "int", "scaler": 3},
      {"id": "13.7.0", "type": "short", "scaler": 3},
      {"id": "GRID_FREQUENCY_50HZ", "type": "short", "scaler": 2},
      {"id": "2.8.0", "type": "int", "scaler": 2},
      {"id": "1.8.0", "type": "int", "scaler": 2},
      {"id": "3.8.0", "type": "int", "scaler": 2},
      {"id": "METER_TYPE_THREE_PHASE", "type": "short"},
      {"id": "0", "type": "int"},
      {"id": "0", "type": "int"},
      {"id": "0", "type": "int"},
      {"id": "power.active.l1", "type": "int", "scaler": 3},
      {"id": "power.active.l2", "type": "int", "scaler": 3},
      {"id": "power.active.l3", "type": "int", "scaler": 3},
      {"id": "METER_TYPE_CHECK_OK", "type": "short"}
    ]
  }
]

Fronius Notes

The Fronius template is designed for clients that probe a Fronius Smart Meter 63A-compatible endpoint. It uses a Fronius-specific SunSpec-like register layout and includes static identification fields, live power values, and zero-filled compatibility placeholders.

Preview:

[
  {
    "start_address": 0,
    "word_order": "msw",
    "registers": [
      {"id": "1", "type": "short"},
      {"id": "0", "type": "short"}
    ]
  },
  {
    "start_address": 11,
    "word_order": "msw",
    "registers": [
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"}
    ]
  },
  {
    "start_address": 768,
    "word_order": "msw",
    "registers": [
      {"id": "0", "type": "short"}
    ]
  },
  {
    "start_address": 1706,
    "word_order": "msw",
    "registers": [
      {"id": "0", "type": "short"}
    ]
  },
  {
    "start_address": 40000,
    "word_order": "msw",
    "constants": {
      "SUNS_ID": "SunS",
      "C_COMMON_ID": 1,
      "C_COMMON_LEN": 65,
      "CHR_F": 70,
      "CHR_r": 114,
      "CHR_o": 111,
      "CHR_n": 110,
      "CHR_i": 105,
      "CHR_u": 117,
      "CHR_s": 115,
      "CHR_S": 83,
      "CHR_m": 109,
      "CHR_a": 97,
      "CHR_t": 116,
      "CHR_SPACE": 32,
      "CHR_M": 77,
      "CHR_e": 101,
      "CHR_6": 54,
      "CHR_3": 51,
      "CHR_A": 65,
      "CHR_0": 48,
      "CHR_1": 49,
      "C_DA": 240,
      "C_M213_ID": 213,
      "C_M213_LEN": 124,
      "C_FREQ_50": 50,
      "C_EVT": 0,
      "C_END_MODEL": -1,
      "C_END_LEN": 0
    },
    "registers": [
      {"id": "SUNS_ID", "type": "string"},

      {"id": "C_COMMON_ID", "type": "short"},
      {"id": "C_COMMON_LEN", "type": "short"},

      {"id": "CHR_F", "type": "short"},
      {"id": "CHR_r", "type": "short"},
      {"id": "CHR_o", "type": "short"},
      {"id": "CHR_n", "type": "short"},
      {"id": "CHR_i", "type": "short"},
      {"id": "CHR_u", "type": "short"},
      {"id": "CHR_s", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},

      {"id": "CHR_S", "type": "short"},
      {"id": "CHR_m", "type": "short"},
      {"id": "CHR_a", "type": "short"},
      {"id": "CHR_r", "type": "short"},
      {"id": "CHR_t", "type": "short"},
      {"id": "CHR_SPACE", "type": "short"},
      {"id": "CHR_M", "type": "short"},
      {"id": "CHR_e", "type": "short"},
      {"id": "CHR_t", "type": "short"},
      {"id": "CHR_e", "type": "short"},
      {"id": "CHR_r", "type": "short"},
      {"id": "CHR_SPACE", "type": "short"},
      {"id": "CHR_6", "type": "short"},
      {"id": "CHR_3", "type": "short"},
      {"id": "CHR_A", "type": "short"},
      {"id": "0", "type": "short"},

      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},

      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},

      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_0", "type": "short"},
      {"id": "CHR_1", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"},

      {"id": "C_DA", "type": "short"},

      {"id": "C_M213_ID", "type": "short"},
      {"id": "C_M213_LEN", "type": "short"},

      {"id": "0", "type": "float", "scaler": 0},
      {"id": "31.7.0", "type": "float", "scaler": 0},
      {"id": "51.7.0", "type": "float", "scaler": 0},
      {"id": "71.7.0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "32.7.0", "type": "float", "scaler": 0},
      {"id": "52.7.0", "type": "float", "scaler": 0},
      {"id": "72.7.0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "C_FREQ_50", "type": "float", "scaler": 0},
      {"id": "power.active", "type": "float", "scaler": 3},
      {"id": "power.active.l1", "type": "float", "scaler": 3},
      {"id": "power.active.l2", "type": "float", "scaler": 3},
      {"id": "power.active.l3", "type": "float", "scaler": 3},
      {"id": "9.7.0", "type": "float", "scaler": 3},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "power.reactive", "type": "float", "scaler": 3},
      {"id": "power.reactive.l1", "type": "float", "scaler": 3},
      {"id": "power.reactive.l2", "type": "float", "scaler": 3},
      {"id": "power.reactive.l3", "type": "float", "scaler": 3},
      {"id": "13.7.0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},

      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},
      {"id": "0", "type": "float", "scaler": 0},

      {"id": "C_EVT", "type": "int"},

      {"id": "C_END_MODEL", "type": "short"},
      {"id": "C_END_LEN", "type": "short"}
    ]
  },
  {
    "start_address": 50000,
    "word_order": "msw",
    "registers": [
      {"id": "0", "type": "short"},
      {"id": "0", "type": "short"}
    ]
  }
]

Herholdt M3PRO Notes

The Herholdt template follows the M1PRO/M3PRO register table with literal 0-based Modbus addresses beginning at 4100. The template is stored as one contiguous register area so it remains compatible with the current parser, while preserving the Herholdt register order.

Important register conventions:

  • 4117 is fixed to 0, selecting floating-point numeric encoding.
  • N4 fields from the Herholdt table are represented as 32-bit floats.
  • N8 fields are represented as 32-bit floats in the first two registers, followed by two zero-filled registers.
  • Herholdt integer-mode scaling by 10000 does not apply to this template because the template selects float mode.

Preview:

[
  {
    "start_address": 4100,
    "word_order": "msw",
    "constants": {
      "FW_REV_1_0": 65296,
      "PID_M3PRO": "HERHOLDT M3PRO",
      "BAUD_19200": 19200,
      "PARITY_NONE": 0,
      "STOPBITS_ONE": 1,
      "MODBUS_ADDR_ONE": 1,
      "FLOAT_MODE": 0,
      "GRID_FREQUENCY_50HZ": 50
    },
    "registers": [
      {"id": "FW_REV_1_0", "type": "short"},
      {"type": "short"},
      {"id": "96.14.0", "type": "short", "scaler": 0},
      {"type": "short"},
      {"id": "PID_M3PRO", "type": "string"},
      {"type": "short"},
      {"id": "BAUD_19200", "type": "short"},
      {"id": "PARITY_NONE", "type": "short"},
      {"id": "STOPBITS_ONE", "type": "short"},
      {"id": "MODBUS_ADDR_ONE", "type": "short"},
      {"type": "short"},
      {"id": "FLOAT_MODE", "type": "short"},
      {"type": "short"},

      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "1.8.1", "type": "float", "scaler": 0}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "1.8.2", "type": "float", "scaler": 0}, {"type": "int"},

      {"id": "power.active.l1", "type": "float", "scaler": 0},
      {"id": "power.active.l2", "type": "float", "scaler": 0},
      {"id": "power.active.l3", "type": "float", "scaler": 0},
      {"id": "power.active", "type": "float", "scaler": 0}, {"type": "int"},

      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "2.8.1", "type": "float", "scaler": 0}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "2.8.2", "type": "float", "scaler": 0}, {"type": "int"},

      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "3.8.1", "type": "float", "scaler": 0}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "3.8.2", "type": "float", "scaler": 0}, {"type": "int"},

      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "4.8.1", "type": "float", "scaler": 0}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"type": "float"}, {"type": "int"},
      {"id": "4.8.2", "type": "float", "scaler": 0}, {"type": "int"},

      {"id": "power.reactive.l1", "type": "float", "scaler": 0},
      {"id": "power.reactive.l2", "type": "float", "scaler": 0},
      {"id": "power.reactive.l3", "type": "float", "scaler": 0},
      {"id": "power.reactive", "type": "float", "scaler": 0}, {"type": "int"},

      {"id": "32.7.0", "type": "float", "scaler": 0},
      {"id": "52.7.0", "type": "float", "scaler": 0},
      {"id": "72.7.0", "type": "float", "scaler": 0},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"id": "31.7.0", "type": "float", "scaler": 0},
      {"id": "51.7.0", "type": "float", "scaler": 0},
      {"id": "71.7.0", "type": "float", "scaler": 0},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"id": "9.7.0", "type": "float", "scaler": 0}, {"type": "int"},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"id": "13.7.0", "type": "float", "scaler": 0},
      {"id": "GRID_FREQUENCY_50HZ", "type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},
      {"type": "float"},

      {"id": "1.8.0", "type": "float", "scaler": 0}, {"type": "int"},
      {"id": "2.8.0", "type": "float", "scaler": 0}, {"type": "int"},
      {"id": "1.8.1", "type": "float", "scaler": 0}, {"type": "int"},
      {"id": "1.8.2", "type": "float", "scaler": 0}, {"type": "int"},
      {"id": "2.8.1", "type": "float", "scaler": 0}, {"type": "int"},
      {"id": "2.8.2", "type": "float", "scaler": 0}, {"type": "int"}
    ]
  }
]

SunSpec Notes

The SunSpec templates depend on features added in FW 2.0.2:

  • area-level constants, used to publish static SunSpec metadata and placeholder values,
  • string register type for the SunS identifier and Common Model text fields,
  • detailed GET /api/v1/modbus?address_format=dec|hex output, useful when verifying the calculated register map,
  • support for Modbus function 03 in addition to function 04, which is required by standard SunSpec clients during model discovery.

The Model 203 template defines a single register area starting at address 0 and contains:

  1. The SunS identifier.
  2. SunSpec Model 1 (Common Model).
  3. SunSpec Model 203 (Wye-Connect Three Phase Meter).
  4. The SunSpec end marker (0xFFFF, followed by length 0).

Its constants object is used for manufacturer strings, model identifiers, scale factors, placeholder values, and the final end marker.

Where a matching whatwatt Go measurement exists, the template maps it directly, for example:

  • 31.7.0, 51.7.0, 71.7.0 for phase currents,
  • 32.7.0, 52.7.0, 72.7.0 for phase-to-neutral voltages,
  • power.active, power.active.l1, power.active.l2, power.active.l3 for active power,
  • power.reactive, power.reactive.l1, power.reactive.l2, power.reactive.l3 for reactive power,
  • 9.7.0 for apparent power,
  • 13.7.0 for power factor,
  • 1.8.0, 2.8.0, 5.8.0, 6.8.0, 7.8.0, 8.8.0 for selected energy counters.

Fields without a native whatwatt Go equivalent are filled with placeholder constants such as -32768 for int16 and sunssf, or 0 for acc32 and event bitfields.

Preview:

[
  {
    "start_address": 0,
    "word_order": "msw",
    "constants": {
      "SUNS_ID": "SunS",
      "C_COMMON_ID": 1,
      "C_COMMON_LEN": 66,
      "C_MN": "whatwatt                        ",
      "C_MD": "whatwatt-go sunspec meter       ",
      "C_OPT": "standard        ",
      "C_VR": "fw-2.0.2-dev    ",
      "C_SN": "whatwatt-sunspec-meter-000001   ",
      "C_DA": 1,
      "C_PAD": 0,
      "C_M203_ID": 203,
      "C_M203_LEN": 105,
      "C_NI16": -32768,
      "C_NACC32": 0,
      "C_EVT": 0,
      "C_A_SF": -2,
      "C_V_SF": -1,
      "C_HZ_SF": -32768,
      "C_W_SF": 0,
      "C_VA_SF": 0,
      "C_VAR_SF": 0,
      "C_PF_SF": -3,
      "C_WH_SF": 0,
      "C_VAH_SF": -32768,
      "C_VARH_SF": 0,
      "C_END_MODEL": -1,
      "C_END_LEN": 0
    },
    "registers": [
      {"id": "SUNS_ID", "type": "string"},

      {"id": "C_COMMON_ID", "type": "short"},
      {"id": "C_COMMON_LEN", "type": "short"},
      {"id": "C_MN", "type": "string"},
      {"id": "C_MD", "type": "string"},
      {"id": "C_OPT", "type": "string"},
      {"id": "C_VR", "type": "string"},
      {"id": "C_SN", "type": "string"},
      {"id": "C_DA", "type": "short"},
      {"id": "C_PAD", "type": "short"},

      {"id": "C_M203_ID", "type": "short"},
      {"id": "C_M203_LEN", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "31.7.0", "type": "short", "scaler": 2},
      {"id": "51.7.0", "type": "short", "scaler": 2},
      {"id": "71.7.0", "type": "short", "scaler": 2},
      {"id": "C_A_SF", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "32.7.0", "type": "short", "scaler": 1},
      {"id": "52.7.0", "type": "short", "scaler": 1},
      {"id": "72.7.0", "type": "short", "scaler": 1},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_V_SF", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_HZ_SF", "type": "short"},
      {"id": "power.active", "type": "short", "scaler": 0},
      {"id": "power.active.l1", "type": "short", "scaler": 0},
      {"id": "power.active.l2", "type": "short", "scaler": 0},
      {"id": "power.active.l3", "type": "short", "scaler": 0},
      {"id": "C_W_SF", "type": "short"},
      {"id": "9.7.0", "type": "short", "scaler": 0},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_VA_SF", "type": "short"},
      {"id": "power.reactive", "type": "short", "scaler": 0},
      {"id": "power.reactive.l1", "type": "short", "scaler": 0},
      {"id": "power.reactive.l2", "type": "short", "scaler": 0},
      {"id": "power.reactive.l3", "type": "short", "scaler": 0},
      {"id": "C_VAR_SF", "type": "short"},
      {"id": "13.7.0", "type": "short", "scaler": 3},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_NI16", "type": "short"},
      {"id": "C_PF_SF", "type": "short"},
      {"id": "2.8.0", "type": "int", "scaler": 3},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "1.8.0", "type": "int", "scaler": 3},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_WH_SF", "type": "short"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_VAH_SF", "type": "short"},
      {"id": "5.8.0", "type": "int", "scaler": 3},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "6.8.0", "type": "int", "scaler": 3},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "7.8.0", "type": "int", "scaler": 3},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "8.8.0", "type": "int", "scaler": 3},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_NACC32", "type": "int"},
      {"id": "C_VARH_SF", "type": "short"},
      {"id": "C_EVT", "type": "int"},

      {"id": "C_END_MODEL", "type": "short"},
      {"id": "C_END_LEN", "type": "short"}
    ]
  }
]

Applying a Template

To load any template into /api/v1/modbus, post the chosen JSON file directly:

curl -i -H 'Content-Type: application/json' \
  --data-binary @template.json \
  http://<whatwattGoIP>/api/v1/modbus

To inspect the resulting calculated addresses and register sizes:

curl -s 'http://<whatwattGoIP>/api/v1/modbus?address_format=dec'

Any SunSpec client that supports Modbus TCP discovery can be used to validate SunSpec templates. pySunSpec2 is one external option.