Modbus Energy Meter Testing with a Simulator — SDM630, Carlo Gavazzi, Schneider iEM
Energy meters are among the most common Modbus devices in building automation, industrial power monitoring, and renewable energy systems. They are also among the most awkward to develop and test against: the physical meter may be locked in an energized switchboard, it may not yet be installed, or it may be at a remote site that requires a site visit to access. Testing your SCADA integration, EMS alarming logic, or power analytics pipeline against a live meter under those constraints is expensive and slow.
The practical alternative is a Modbus slave simulator configured to behave exactly like the target meter. This article covers how to do that for the three most common meter families in commercial and industrial building automation: the Eastron SDM630, Carlo Gavazzi EM series, and Schneider Electric iEM3000 series. It covers the register maps, float32 encoding, realistic data setup, software integration, alarm testing, and fault injection. The approach applies to any meter that exposes a standard Modbus RTU or Modbus TCP interface.
Why Simulate an Energy Meter Instead of Using the Real One
The case for simulation is not about avoiding hardware. Most projects will eventually test against the real meter. The case is about controlling when and under what conditions that test happens.
Meter not yet on site. Procurement lead times for three-phase energy meters — particularly for Schneider iEM3155 or Eastron SDM630-Mbus variants — can run four to twelve weeks. Meanwhile, the SCADA development, EMS configuration, and dashboard programming can start immediately if you have a reliable simulation target.
Meter is energized and inaccessible. Once installed in a live switchboard, the meter is energized at 230–415V. Connecting a laptop and probing registers requires electrical safety authorization, permits, and isolation procedures. During development, you do not want to repeat that process every time you need to test a register read.
Controlled test conditions. A real meter reflects whatever the load is doing at that moment. To test overvoltage alarm logic, you need overvoltage. To test zero-export power setpoint response, you need to control active power. A simulator lets you set any value at any time, including values that would be dangerous or impossible to produce with real hardware.
Commissioning validation before site. Factory acceptance testing (FAT) for energy management systems requires a complete test of every alarm, setpoint, and trend log against representative meter data. Running FAT with a simulated meter means no site access required until the formal site acceptance test.
Fault tolerance testing. Real meters don't fail on command. A simulator can be configured to stop responding, return exception codes, or produce corrupt values on demand, which is the only practical way to test how your SCADA or EMS handles communication failures.
Energy Meter Modbus Register Maps
The three meter families covered here share similar register layouts because they target the same market and were designed to be interchangeable. Understanding the shared pattern makes it straightforward to simulate any of them. For deeper background on register types, see Modbus register types explained.
Eastron SDM630: The Reference Layout
The Eastron SDM630 is the de facto reference for three-phase energy meter Modbus register maps. It is widely cloned and its register layout is used as the baseline for most building automation energy metering profiles. All measurement registers are Input Registers (function code 04), addressed from 30001 in 1-based notation (0x0000 in zero-based).
All values are 32-bit IEEE 754 floating-point, stored as two consecutive 16-bit registers, high word first (big-endian word order). There are no integer registers with scale factors in the measurement area — everything is float32. This is a deliberate design choice that eliminates scaling errors at the cost of requiring two-register reads for every measurement.
Carlo Gavazzi EM Series and Schneider iEM3000
Carlo Gavazzi EM112, EM300, and EM330 meters follow the same float32, two-register-per-value pattern. The register base addresses differ slightly from the SDM630 for some parameters (particularly power factor and harmonics), but voltage, current, power, and energy addresses are close enough that the same simulation approach applies.
The Schneider iEM3155 and iEM3255 use a slightly different register map but the same float32 encoding. Their Modbus map is documented in the iEM3000 series Modbus communication guide and uses Function Code 03 (Read Holding Registers) for most parameters, which is one of the key differences from the Eastron layout when configuring your simulator.
SDM630-Style Register Map: Complete Reference
The table below lists the primary measurement registers for an SDM630-compatible meter simulation. Addresses are shown in both 1-based (as printed in the Eastron documentation) and 0-based (as used in pymodbus and most software stacks). All values are float32 across two consecutive registers.
| Parameter | Address (1-based) | Address (0-based) | Registers | Type | Unit | Typical Value |
|---|---|---|---|---|---|---|
| Voltage L1–N | 30001 | 0x0000 | 2 | float32 | V | 230.0 |
| Voltage L2–N | 30003 | 0x0002 | 2 | float32 | V | 230.0 |
| Voltage L3–N | 30005 | 0x0004 | 2 | float32 | V | 230.0 |
| Current L1 | 30007 | 0x0006 | 2 | float32 | A | 12.5 |
| Current L2 | 30009 | 0x0008 | 2 | float32 | A | 12.5 |
| Current L3 | 30011 | 0x000A | 2 | float32 | A | 12.5 |
| Active Power L1 | 30013 | 0x000C | 2 | float32 | W | 2875.0 |
| Active Power L2 | 30015 | 0x000E | 2 | float32 | W | 2875.0 |
| Active Power L3 | 30017 | 0x0010 | 2 | float32 | W | 2875.0 |
| Total Active Power | 30053 | 0x0034 | 2 | float32 | W | 8625.0 |
| Power Factor L1 | 30031 | 0x001E | 2 | float32 | — | 0.95 |
| Frequency | 30071 | 0x0046 | 2 | float32 | Hz | 50.0 |
| Total Import kWh | 30073 | 0x0048 | 2 | float32 | kWh | 14523.7 |
| Total Export kWh | 30075 | 0x004A | 2 | float32 | kWh | 0.0 |
The SDM630 has over 100 input registers covering harmonics (THD voltage and current per phase), reactive energy, apparent power, and phase-to-phase voltages. For most simulation purposes, the 14 parameters in the table above cover all data points that SCADA systems and EMS software actually poll in production.
Function code note: The Eastron SDM630 uses Function Code 04 (Read Input Registers) for all measurement data. The Schneider iEM3155 uses Function Code 03 (Read Holding Registers) for most parameters. If your EMS software returns exception code 01 (Illegal Function), the function code in the poll configuration does not match what the meter expects. For more on this distinction, see Modbus register types explained.
Configuring ModbusSimulator as an SDM630-Style Energy Meter Slave
The following steps configure ModbusSimulator as a Modbus TCP slave that responds exactly as an SDM630 would to register read requests from energy monitoring software.
Step 1: Set Slave Mode and Transport
Open ModbusSimulator and switch to Slave mode. For Modbus TCP (the most common for energy monitoring software integration), set the transport to TCP and configure the listening port to 502. Set the slave ID (Unit ID) to 1, which is the SDM630 factory default. If your meter has been configured for a different slave ID, match that instead.
For RTU-connected meters (typically via RS-485 on the meter's RS-485 port), set the transport to RTU, select the appropriate COM port, and configure the serial parameters. The SDM630 factory default is 9600 baud, 8 data bits, no parity, 1 stop bit (9600 8N1). Some installations reconfigure to 19200 or 38400 — check the meter's front-panel display or DIP switch settings.
Step 2: Populate Input Registers with Float32 Values
The SDM630 uses Input Registers (FC04). In ModbusSimulator's register table, navigate to the Input Registers section. You will populate register pairs starting at address 0 (zero-based), since that is the 0-based equivalent of the 30001 1-based address.
For each float32 parameter, you need to write the correct 16-bit words into two consecutive register addresses. The encoding is IEEE 754 float32, big-endian word order (high word at the lower address). For 230.0V (a standard European nominal voltage):
230.0 as IEEE 754 float32 = 0x43660000
High word: 0x4366 → register 0 (address 30001)
Low word: 0x0000 → register 1 (address 30002)
ModbusSimulator can accept float32 values directly in the register input field without requiring manual conversion — enter the decimal value and select the float32 data type, and the tool handles the two-register encoding automatically. This is the correct workflow for all measurement registers.
Step 3: Set All Three Phases for a Balanced Load
For a realistic balanced three-phase simulation, set the following values across all three phases:
- Voltage L1, L2, L3 (addresses 0, 2, 4): 230.0 V each
- Current L1, L2, L3 (addresses 6, 8, 10): 12.5 A each — represents a moderate load
- Active Power L1, L2, L3 (addresses 12, 14, 16): 2875.0 W each — consistent with V × I × PF = 230 × 12.5 × 0.997
- Power Factor L1, L2, L3 (addresses 30, 32, 34): 0.95 each — realistic for a mixed resistive/inductive load
- Frequency (address 70): 50.0 Hz (or 60.0 Hz for North American installations)
- Total Active Power (address 52): 8625.0 W (sum of three phases)
- Total Import kWh (address 72): 14523.7 kWh — a plausible accumulated value for a meter that has been running for a few months
At this point, your master software should be able to connect to the simulator and read all primary measurement parameters with values that look exactly like a real balanced three-phase load.
Scaled Integer Values vs. Float32 Register Pairs
The Eastron SDM630 stores everything as float32, but not all energy meters follow this approach. Older meters and some budget DIN-rail meters use scaled integers: a 16-bit integer value that must be multiplied by a fixed scale factor to get the engineering unit.
For example, a scaled-integer meter might store voltage as an unsigned 16-bit integer with a scale factor of 0.1, so a register value of 2300 represents 230.0V. Current might use a scale of 0.01, so 1250 represents 12.50A. These meters use single registers per parameter, which simplifies the Modbus read but requires you to track the scale factor in your application.
When simulating scaled-integer meters in ModbusSimulator, enter the raw integer value (2300 for 230.0V) rather than the engineering value. The scale factor is applied by the master application, not the meter or simulator. This is an important distinction: get it wrong and your SCADA will display voltages 10× too high or too low, which is a common source of confusion during initial commissioning.
The SDM series uses float32 to avoid this class of error entirely. The Carlo Gavazzi EM112 is an example of a scaled-integer meter still in widespread use, particularly in cost-sensitive retrofit applications. The EM300 series moved to float32 to align with the SDM convention.
Simulating Realistic Operating Data
Setting voltage to exactly 230.0V and power to exactly 8625.0W produces a simulation that works for functional testing but does not reveal timing-related bugs in your application. Real meters produce slightly varying values on every poll because the measurement is taken at a different point in the AC cycle each time. Overly static simulation data can mask application issues that only manifest with noisy or varying inputs.
Voltage Variation
In a typical European LV distribution network, voltage fluctuates within approximately ±10% of nominal (207–253V per EN 50160). A realistic test scenario populates L1 voltage at 230.0V, L2 at 228.5V, and L3 at 231.2V — a slight imbalance that is normal in practice. For a more dynamic simulation, update the register values every 30 seconds through ModbusSimulator's register write API or by manually adjusting values while your master polls.
Power Fluctuation
Active power varies with load switching. A typical office building load profile has a morning ramp from near zero to peak between 08:00 and 10:00, a relatively flat midday period, and a drop-off in the early evening. For testing trend logging and energy analytics, step through a sequence of power values (500W, 1500W, 4000W, 8000W, 6500W, 2000W) at one-minute intervals while your EMS records the data. This verifies that trend data is being captured correctly before you trust it from a real meter.
Phase Imbalance
A balanced three-phase load is a theoretical ideal. In most commercial buildings, single-phase loads are unevenly distributed across phases. To simulate realistic imbalance, set L1 current to 18.0A, L2 to 9.5A, and L3 to 14.0A. This tests whether your energy monitoring software reports phase imbalance correctly and whether any protection relay simulation logic triggers on the imbalance threshold (typically flagged when any phase deviates more than 10% from the average).
Reading the Simulated Meter with Python pymodbus
The following Python script connects to the simulator over Modbus TCP and reads the primary measurement registers from an SDM630-style slave. It uses pymodbus 3.x, which changed the decoder API from earlier versions.
import struct
from pymodbus.client import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
# Connect to ModbusSimulator running on localhost, port 502
client = ModbusTcpClient(host="127.0.0.1", port=502)
client.connect()
SLAVE_ID = 1
def read_float32(client, address, slave_id):
"""Read a float32 value from two consecutive input registers."""
result = client.read_input_registers(
address=address,
count=2,
slave=slave_id
)
if result.isError():
raise ValueError(f"Modbus error reading address {address}: {result}")
decoder = BinaryPayloadDecoder.fromRegisters(
result.registers,
byteorder=Endian.BIG,
wordorder=Endian.BIG
)
return decoder.decode_32bit_float()
# SDM630 register addresses (zero-based, FC04 Input Registers)
registers = {
"Voltage L1 (V)": 0x0000,
"Voltage L2 (V)": 0x0002,
"Voltage L3 (V)": 0x0004,
"Current L1 (A)": 0x0006,
"Current L2 (A)": 0x0008,
"Current L3 (A)": 0x000A,
"Active Power L1 (W)": 0x000C,
"Active Power L2 (W)": 0x000E,
"Active Power L3 (W)": 0x0010,
"Power Factor L1": 0x001E,
"Total Active Power (W)": 0x0034,
"Frequency (Hz)": 0x0046,
"Total Import kWh": 0x0048,
"Total Export kWh": 0x004A,
}
print("SDM630 Modbus Register Readout")
print("-" * 40)
for name, address in registers.items():
try:
value = read_float32(client, address, SLAVE_ID)
print(f"{name:<30} {value:.3f}")
except ValueError as e:
print(f"{name:<30} ERROR: {e}")
client.close()
Run this script while ModbusSimulator is active with the register values set in the previous section. You should see output matching the values you entered. If you see 0.0 for all values, verify that ModbusSimulator is set to respond on Function Code 04 (Input Registers) rather than FC03 (Holding Registers). If you see an exception, check that the client is connecting to the correct host and port and that the slave ID matches.
To read from an SDM630 connected via RTU rather than TCP, replace the client instantiation with:
from pymodbus.client import ModbusSerialClient
client = ModbusSerialClient(
port="COM3", # adjust for your USB-RS485 adapter
baudrate=9600,
bytesize=8,
parity="N",
stopbits=1,
timeout=1
)
The rest of the code is identical — the function code and register addressing are the same regardless of transport.
Connecting Energy Monitoring Software to the Simulated Meter
Schneider EcoStruxure Building Operation
EcoStruxure Building Operation (EBO) connects to Modbus energy meters through its Modbus TCP or Modbus serial driver. To add the simulated meter as a device:
- In EBO's Device Configuration, add a new Modbus TCP device with the IP address of the machine running ModbusSimulator (127.0.0.1 for a local simulation) and port 502.
- Create point objects mapped to each register address. Set the data type to Float for SDM630-style registers. EBO handles the two-register float32 read automatically when the data type is set correctly.
- Set the polling interval to match your intended live polling rate — typically 10 or 30 seconds for energy meters in building automation.
- Trend log the Voltage L1, Total Active Power, and Total Import kWh points. Run the simulation for 15–20 minutes with varied register values to verify that trend data is captured at the correct interval and with the correct engineering values.
Custom SCADA and Historian Integration
For custom SCADA systems or historians using OPC DA/UA with a Modbus driver, the configuration approach is the same: point the Modbus driver to the simulator IP, set register addresses and data types to match the SDM630 map, and verify that the engineering values displayed in the SCADA match the values set in the simulator. Any discrepancy indicates a register address offset error, a byte/word order mismatch, or a wrong data type configuration — all of which are easier to diagnose against a simulator than a field-installed meter.
For a detailed walkthrough of connecting a Modbus slave to SCADA and master software, see the Modbus slave simulator guide.
Testing Alarm Thresholds
Energy management systems typically implement alarms for overvoltage, undervoltage, overcurrent, power factor below threshold, and kWh billing limits. Testing these alarms against a simulator is the only practical way to verify alarm logic before site commissioning.
Overvoltage Alarm
EN 50160 defines the supply voltage tolerance as 230V ±10%, giving an upper limit of 253V. Most EMS software allows configuring an overvoltage alarm threshold. To test:
- Set all three voltage registers to 230.0V in the simulator. Confirm no alarm is active in your EMS.
- Increment L1 voltage in the simulator to 250.0V. If the alarm threshold is 253V, no alarm should trigger.
- Set L1 voltage to 255.0V. The overvoltage alarm for L1 should trigger.
- Reduce L1 back to 245.0V. Verify that the alarm clears (accounting for any hysteresis configured in the EMS).
Repeat this test for each phase independently to verify that the alarm is phase-specific and does not incorrectly use a three-phase average.
Power Factor Alarm
Low power factor alarms are common in commercial buildings subject to utility power factor penalties. A typical threshold is PF < 0.85 lagging. To test:
- Set power factor registers to 0.95 (nominal). Confirm no alarm.
- Set power factor to 0.87. Alarm should not trigger (above threshold).
- Set power factor to 0.82. Alarm should trigger.
- Verify the alarm message correctly identifies the phase and the measured value.
kWh Billing Limit
Some EMS implementations support maximum kWh consumption per billing period with an alarm or demand response action at the threshold. Test this by setting the Total Import kWh register to a value just below the configured limit, then incrementing it past the threshold in steps while confirming the alarm triggers at the correct point.
Simulating Meter Communication Errors for Fault Tolerance Testing
A well-engineered SCADA or EMS handles meter communication failures gracefully: it shows a "communication lost" indication, retains the last valid value or shows a stale-data flag, and raises an alert without cascading into broader application errors. This behavior is almost never tested in practice because real meters don't fail on demand.
ModbusSimulator provides several mechanisms for injecting communication faults:
Simulating No Response (Timeout)
Stop ModbusSimulator while your master is actively polling. The master will fail to connect and should raise a communication error after its configured timeout period. Verify that:
- The SCADA display shows a "meter offline" or "communication fault" state rather than a blank or zero value.
- Alarm records show the correct fault time and clearing time when the simulator is restarted.
- Trend logs show a gap or a quality flag during the offline period rather than recording zero or the last valid value as if it were a real measurement.
Simulating Exception Responses
Configure ModbusSimulator to return a Modbus exception code for specific register addresses. Exception Code 02 (Illegal Data Address) simulates a firmware version mismatch where a register that exists in a newer meter version is addressed in an older one. Exception Code 04 (Server Device Failure) simulates an internal meter fault. Test that your application logs the exception code, displays a meaningful error message to the operator, and does not treat an exception response as a valid measurement value.
Simulating Partial Communication
Reduce the value of a subset of registers to zero while leaving others at their normal values. This simulates a partial meter communication failure — for example, a meter that returns valid voltage and current but returns zero for all energy accumulator registers. This is a known failure mode in some embedded meter firmware and should trigger data quality checks in the EMS. Verify that your application detects the implausible combination (normal voltage and current with zero kWh accumulation) and raises a data quality alarm rather than silently accepting the zero energy values.
Simulating Intermittent Communication
Alternate between stopping and starting ModbusSimulator at irregular intervals — every 20 to 45 seconds — while your SCADA polls at a 10-second interval. This tests retry logic: the master should retry a configurable number of times before declaring the meter offline, then attempt to re-establish communication once the meter is reachable again without manual intervention. Many EMS implementations have bugs in this re-connection logic that only surface during intermittent fault testing.
Configuration note: Before testing fault tolerance, document your EMS software's configured Modbus timeout, retry count, and communication-loss declaration threshold. For example, a 1-second timeout with 3 retries means the EMS should declare the meter offline approximately 3 seconds after it stops responding. Verify this timing against the actual alarm timestamps from your fault injection tests.
Frequently Asked Questions
What Modbus function code do energy meters use for reading registers?
Most energy meters, including the Eastron SDM series and Carlo Gavazzi EM series, use Function Code 04 (Read Input Registers) for measurement data such as voltage, current, power, and energy. The Schneider iEM3000 series uses Function Code 03 (Read Holding Registers) for most parameters. Using the wrong function code returns Exception Code 01 (Illegal Function). When setting up your simulator, match the function code to whatever your target meter documentation specifies.
Why do energy meter registers come in pairs?
Energy meters like the Eastron SDM630 store measurements as 32-bit IEEE 754 floating-point values. A single Modbus register is 16 bits wide, so each float32 value occupies two consecutive registers. The SDM630 uses big-endian word order: high word at the lower register address, low word at the next address. When reading, request 2 registers from the base address and combine them into a float32. For example, L1 voltage at address 30001 requires reading both 30001 and 30002.
Can I simulate a three-phase energy meter with ModbusSimulator?
Yes. Populate the register pairs for L1, L2, and L3 voltages (0-based addresses 0, 2, 4), currents (6, 8, 10), and per-phase active power (12, 14, 16). Set all three phases to equal values for a balanced load, or set them independently to simulate phase imbalance. ModbusSimulator supports live register editing, so you can change values while your master polls to simulate load changes without restarting.
What byte order does the SDM630 use for float32 registers?
The Eastron SDM630 uses big-endian byte order within each 16-bit word, and big-endian word order across the two-register pair (high word first). This is labeled as ABCD byte order in some documentation. In pymodbus, this corresponds to Endian.BIG for both byte order and word order in the BinaryPayloadDecoder. Carlo Gavazzi EM and Schneider iEM3000 use the same convention. A byte/word order mismatch produces values that are numerically nonsensical but syntactically valid float32 numbers — a subtle bug to diagnose.
How do I simulate a kWh meter rollover for testing?
Set the Total Import kWh register pair (address 30073/30074, zero-based 0x0048/0x0049) to a float32 value just below the maximum your application handles. ModbusSimulator allows live editing of register values without restarting the slave, so you can increment the kWh value in steps while your master polls continuously. Verify that your application handles the transition correctly and does not produce a negative delta when the rollover is detected.
How do I test my EMS alarm logic without physical meters?
Configure ModbusSimulator as a Modbus TCP slave matching your meter's register map. Set voltage registers to nominal (230V), then edit them to out-of-range values (260V for overvoltage, 180V for undervoltage) while your EMS polls. Verify alarms trigger at the correct thresholds. Use ModbusSimulator's live register editing to step through boundary values and confirm alarm hysteresis is implemented correctly in your application logic.
Start Testing Your Energy Meter Integration Today
ModbusSimulator runs as a Modbus TCP or RTU slave on your Windows PC. Configure it as an SDM630, Carlo Gavazzi, or any custom meter register map, set realistic float32 values, and connect your energy management software or SCADA system against it before your first site visit. One-time lifetime license, free 30-day trial.
Download Free Trial