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

  • siemens_pac2200.json - Siemens PAC2200-compatible layout. This matches the default firmware layout used when no custom Modbus configuration is stored.
  • carlo_gavazzi_em24_e1.json - Carlo Gavazzi EM24_E1-compatible layout with lsw word order for 32-bit values.
  • sunspec_model_1_203.json - SunSpec Common Model 1 plus meter Model 203 using int16 and int32 values with scale factors.
  • sunspec_model_1_213.json - SunSpec Common Model 1 plus meter Model 213 using float32 values.

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.
  • 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, sunspec_model_1_203.json, and sunspec_model_1_213.json 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.
  • 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.

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.