ESPHome IEC 62056-21 Component
IEC 62056-21 is an international standard for a protocol to exchange data with utility meters. Mostly for electricity but also water, thermal and other meters. It was previously known as IEC 61107.
iec62056 component allows you to read data from any compatible meter. It requires a serial port and an external optical interface. Data exchange uses an infrared optical channel. Compatible meters are equipped with a characteristic round metal plate with two opto-elements inside. The protocol could be used with other transport layers, e.g. current loop but the component was tested only with the optical interface.
It supports 4 modes of IEC 62056-21: A, B, C, and D.
The component does not support programming. Setting meter configuration parameters requires a secret password which makes it impossible to use by ordinary users.
There are other smart meter standards that use the same optical interface. Although they share some common concepts they are not compatible.
Add the following code to ESPHome YAML configuration file to reference external component.
external_components: # IEC62056 component - source: github://aquaticus/esphome@aquaticus-iec62056 components: [ iec62056 ]
Theory of operation
The component operates in 2 main modes:
Bidirectional communication with a meter. In this mode, a meter sends data only when requested. It requires an IR receiver and transmitter. This is mode A, B and C according to IEC 62056-21.
Unidirectional communication, where a meter sends data to a probe from time to time. It requires only an IR receiver. In IEC 62056-21 terminology it is mode D.
Modes A, B, C
The component reads data for the first time 15 seconds after boot-up. First, it sends an identification request at 300 bps. The meter returns the maximum baud rate it can handle. Following that, the serial port baud rate is changed to the value provided by the meter or configured by option baud_rate_max. The meter transmits data registers with associated OBIS codes.
If the transmission has failed (bad checksum or invalid format), the component will try to read data again but this time using a slower transmission speed. For every retry, the speed is decreased. The number of retires and delays can be configured.
If the meter is battery-powered, a special wake-up sequence can be applied. This happens only when battery_meter is set to
For meters operating in mode D, you only need an IR receiver as transmission to a meter is not supported. In this mode, the meter sends data every few seconds without any request. You should configure the serial port to match the meter transmission format. Unlike modes A, B, and C which is detected automatically, Mode D must be enabled manually by setting
mode_d=True in the platform configuration.
The OBIS code identifies the different readings from a meter. The code consists of up to 6 group sub-identifiers.
The code is formatted like this:
A- medium: 0=abstract objects, 1=electricity, 6=heat, 7=gas, 8=water
B- channel, 0=no channel available
C- physical value, e.g. current, voltage, temperature.
D- measurement type,
E- tariff, 0=total, 1=tariff #1, 2=tariff #2 and so on
F- billing period
F may be omitted. Codes may use hexadecimal digits, for example, code
15.8.0 could be represented
The codes are standardized but devices send a different number of codes. To get a list of codes supported by your meter enable
iec62056 component and observe the log output. Sample output:
[10:50:12][D][iec62056.component:416]: Data: '1-0:15.8.1(00000009999.567*kWh)' [10:50:12][D][iec62056.component:416]: Data: '1-0:15.8.2(00000000000.000*kWh)' [10:50:12][D][iec62056.component:416]: Data: '1-0:15.8.3(00000000000.000*kWh)' [10:50:12][D][iec62056.component:416]: Data: '1-0:15.8.4(00000000000.000*kWh)'
Sensor OBIS code must match exactly what is transmitted from a meter. This is the part before the first bracket
For a list of OBIS codes for electric meters, you can visit:
To communicate with a meter you must attach an optical interface to the serial port. The interface consists of an infrared LED and phototransistor. In addition, the device must be equipped with a ring magnet to keep it aligned with the meter.
If the meter operates in unidirectional mode D, only an IR phototransistor is required.
The standard defines the maximum dimensions of the probe that can be attached to a meter. It must be equipped with a magnet as it is the only way to keep the probe in a stable position.
To see meter data in Home Assistant you must define a sensor or text sensor with the appropriate OBIS code. Note that meters support different sets of OBIS codes. By default, the component does not define any sensors.
The component requires UART bus. The serial must be configured as 7E1 in most cases.
mode_d=True baud rate must be set to a value supported by the meter. Usually 2400 or 9600 bps. For other modes (
mode_d=False) the transmission speed is negotiated with a meter.
baud_rate is ignored and can be any value.
# Example UART configuration entry uart: rx_pin: GPIO21 tx_pin: GPIO22 baud_rate: 9600 data_bits: 7 parity: EVEN stop_bits: 1
For ESP8266 it is highly recommended to use hardware UART. Software UART cannot handle transmissions faster than 4800 bps.
You may need to disable logging if the optical probe is connected to the serial port used by the logger component.
# Set baud_rate to 0 to disable logging via UART. logger: baud_rate: 0
To use the component you must define
iec62056 platform section in the configuration file. It consists of basic settings.
# Example platform configuration entry for bidirectional communication iec62056: update_interval: 60s baud_rate: 9600 battery_meter: False
# Example platform configuration entry for unidirectional communication iec62056: mode_d: True
update_interval (Optional, Time): The interval to read data from a meter. Defaults to
neverdisables updates. In that case, a switch should be used to trigger readout. To get continuous readings use a small value like 1s.
baud_rate_max (Optional, int): LLimits the maximum transmission speed to the specified value. By default, it is set to
9600as it provides a stable connection. To disable it, set it to
0. That way you can use the maximum possible baud rate of
19200if the meter supports it. For ESP8266 use the software UART set to
receive_timeout (Optional, Time): Maximum time component waits for data from a meter before reporting transmission error. Defaults to
battery_meter (Optional, boolean): Set to true if a meter is battery-powered. That way special power-up sequence will be used.
retry_delay (Optional, Time): In case of transmission failure, time to wait before retrying transmission. Defaults to
retry_counter_max (Optional, int): In case of transmission failure, the maximum number of retries. Defaults to
uart_id (Optional, ID): Manually specify the ID of the UART Component if you want to use multiple UART buses.
mode_d (Optional, boolean): Set to
Trueif a meter sends data every few seconds. This forces the component to operate in mode D. In this mode data is never transmitted to a meter. If set, any other settings except
receive_timeoutare ignored. Don’t forget to set UART baud rate the meter is using. If you are not sure try
Battery-powered meters typically limit the number of readings to preserve energy, e.g. to 4 readings a day. If a meter does not impose the limit, frequent readings may significantly decrease battery life.
The sensor reports the first value between brackets from the record. For the following data
the sensor value is
6000.385. To get the second value (date/time in this example) use a Text Sensor.
The sensor supports only decimal values. If the record contains data in any other format you have to use Text Sensor and optionally lambda to convert it to a number.
# Example sensor configuration entries sensor: - platform: iec62056 obis: 1-0:15.8.0 name: Absolute active energy total unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: iec62056 name: Instantaneous current in phase L1 obis: 1-0:31.7.0 unit_of_measurement: A accuracy_decimals: 2 device_class: current state_class: measurement - platform: iec62056 name: Instantaneous voltage in phase L1 obis: 1-0:32.7.0 unit_of_measurement: V accuracy_decimals: 1 device_class: voltage state_class: measurement - platform: iec62056 name: Absolute active instantaneous power obis: 1-0:15.7.0 unit_of_measurement: kW accuracy_decimals: 3 device_class: energy state_class: measurement
obis (Required): OBIS code.
All other options from Sensor.
The text sensor provides readout data as a text. In contrast to Sensor, you can select which part of the readout is reported and even send the entire data record back to Home Assistant.
# Sample text sensor configuration # Data record: # 1-0:15.6.0(00000006000.385*kW)(2000-01-01 20:10:30) - platform: iec62056 obis: 1-0:15.6.0 group: 2 # "2000-01-01 20:10:30" name: Date time - platform: iec62056 obis: 1-0:15.6.0 group: 1 # "00000006000.385" name: Value - platform: iec62056 obis: 1-0:15.6.0 group: 0 # "1-0:15.6.0(00000006000.385*kW)(2000-01-01 20:10:30)" name: The entire record
obis (Required): OBIS code. You may define multiple text sensors with the same OBIS but a different group.
group (Optional, int): Value group,
2. Defaults to
1. If set to
0, the entire data record is reported including OBIS code.
1reports the first value,
2the second one.
All other options are from Text Sensor.
If a meter reports data as a non-decimal value you can convert it automatically using a template sensor and lambda. Let’s assume the meter sends a record like the following one with hex-encoded data:
First, create a template sensor that will publish data as a decimal value.
sensor: - platform: template id: hex_to_dec_sensor name: "Converted hexadecimal number"
Now create a text sensor that will receive data as a string, convert it to decimal and publish.
text_sensor: - platform: iec62056 id: hex_sensor obis: 0-0:96.8.0*255 name: Hex content internal: True on_value: lambda: |- std::string hex_str = id(hex_sensor).state; uint32_t dec=std::stoul(hex_str, nullptr, 16); ESP_LOGI("iec62056.component", "Converted HEX '%s' to %u decimal", hex_str.c_str(), dec); id(hex_to_dec_sensor).publish_state((float)dec);
Every time the text sensor receives a new value, it converts it to a decimal and publishes it using the sensor with id
internal flag prevents the sensor to be visible in Home Assistant. In the log you should see:
[I][iec62056.component:127]: Converted HEX 'ABCDEF00' to 2882400000 decimal
The same results can be obtained using Home Assistant lambdas. In this scenario, text sensor publishes hexadecimal value and Home Assistant template sensor makes conversion.
The switch provides the ability to trigger readout on request. When the state is changed from
the component initiates data transmission from a meter. You can use the switch in automation.
Configuration variables from Switch can be used.
# Sample switch configuration switch: - platform: iec62056 name: 'Readout Trigger'
You cannot trigger readout in mode D.
ON when transmission to a meter begins.
OFF when the transmission is finished.
You can use all configuration variables from Binary Sensor.
# Sample automation to turn LED on when data read from a meter switch: - platform: gpio pin: GPIO2 name: Internal LED id: led_switch internal: True binary_sensor: - platform: iec62056 id: meter_status name: Meter Connection Status on_press: then: - switch.turn_on: led_switch on_release: then: - switch.turn_off: led_switch
Make sure the probe is properly aligned with the optical elements on the meter.
Meters are usually installed in not very clean areas. You may need to remove dust from the optical interface from time to time.
If you encounter transmission and BCC checksum errors decrease the baud rate using
If your device handles multiple sensors that spend a lot of time in the update loop you may need to increase the serial port buffer size. Especially if you note transmission problems when additional sensors are enabled but not when they are disabled.