Skip to content

Instantly share code, notes, and snippets.

@NathanAdhitya
Last active August 18, 2025 15:07
Show Gist options
  • Select an option

  • Save NathanAdhitya/802082031d52c8e22f7cf517a371f0b9 to your computer and use it in GitHub Desktop.

Select an option

Save NathanAdhitya/802082031d52c8e22f7cf517a371f0b9 to your computer and use it in GitHub Desktop.
ESPHome YAML snippet for Eliwell EWPlus 974 EO Modbus interface
# This snippet is incomplete, make sure to fill the rest to your needs
# This snippet is made with the assumption:
# - You are using the ESP32-C3 SuperMini
# - You have a 5V <-> 3.3V TTL converter hooked up on GPIO0 and GPIO1
# - GPIO1 (converted) is attached to the RX pin of the EWPlus (TX side of ESP32)
# - GPIO0 (converted) is attached to the TX pin of the EWPlus (RX side of ESP32)
# - Your EWPlus 974 EO is set to use Modbus with device address of 1 (check your device settings)
# By github.com/NathanAdhitya
# Author note:
# - The datasheet parameter table addresses seems to be accurate
# - The datasheet's client table addresses seems to be incorrect on my device, therefore addresses of Pb1 and Pb2 is obtained from reverse engineering.
esp32:
board: esp32-c3-devkitm-1
framework:
type: esp-idf
uart:
- id: uart_modbus_client
tx_pin: 1
rx_pin: 0
baud_rate: 9600
modbus:
- uart_id: uart_modbus_client
id: modbus_client
modbus_controller:
- id: modbus_eliwell
modbus_id: modbus_client
address: 0x1
update_interval: 1s
sensor:
# Warning, this is tricky. Reading 2 registers at once outputs the correct values, but if you read them individually,
# it returns a garbled output.
- platform: modbus_controller
id: eliwell_analog_pb1
modbus_controller_id: modbus_eliwell
# 0x01: address
# 0x03: read holding regs
# 0x0163: start address
# 0x0002: length
custom_command: [ 0x01, 0x03, 0x01, 0x63, 0x00, 0x02 ]
name: "Pb1"
address: 356
device_class: temperature
value_type: S_WORD
unit_of_measurement: C
accuracy_decimals: 1
register_count: 2
lambda: |-
int16_t raw = data[item->offset + 1] << 8 | data[item->offset];
return raw * 0.1f;
- platform: modbus_controller
id: eliwell_analog_pb2
modbus_controller_id: modbus_eliwell
# 0x01: address
# 0x03: read holding regs
# 0x0163: start address
# 0x0002: length
custom_command: [ 0x01, 0x03, 0x01, 0x63, 0x00, 0x02 ]
name: "Pb2"
address: 356
device_class: temperature
value_type: S_WORD
unit_of_measurement: C
accuracy_decimals: 1
register_count: 2
lambda: |-
int16_t raw = data[item->offset + 3] << 8 | data[item->offset + 2];
return raw * 0.1f;
number:
- platform: modbus_controller
id: eliwell_setpoint
modbus_controller_id: modbus_eliwell
name: "Setpoint"
address: 16416
value_type: S_WORD
multiply: 10
device_class: temperature
step: 0.1
unit_of_measurement: C
select:
- platform: modbus_controller
id: eliwell_selection_of_main_display_value
modbus_controller_id: modbus_eliwell
name: "Selection of main display value"
address: 49240
value_type: U_WORD
optionsmap:
"Setpoint": 0
"Pb1": 1
"Pb2": 2
"Pb3": 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment