Glad it worked for you. No beer needed. Seeing that my little documentation helped others is more than enough.
I could also need some help unfortunately.
Im using a ESP32 and a RS485 adapter
and I have used your yaml code from GitHub @rstcologne
ESP32 boots up correctly, web interface works - but I don’t get any data from the Fairland pump and I can’t communicate with it.
I have tried to first flip the RX/TX cables between the RS485 and the ESP32 but I got a massive amount of modbus errors that then disappeared when I moved them back to the original RX/TX ports.
I have also tried to change position of the A and B cabled from the RS485 to the fairland pump but that doesn’t make any difference… I still get the same loggs in the web interface.
This is how it looks like. I don’t get any good readings of temperature as an example. I have tried to flip power switch on and off and I can see in the log that the ESP32 is trying to send the command OFF/ON - but nothing is happening.
Any suggestions on how I should move on with troubleshooting?
ok so in my attempts to get this working I suspected that maybe the fairland pump don’t use the modbus address 0001 so I took some help with ChatGPT and built another ESP32 to a modbus scanner and scanned the pump on all modbus addresses.
I got no respons on any channel, which is very strange. So I plugged in the original wifi unit and that works - so the pump works as it should.
could anyone be kind to test the modbus scanner config so I can make sure that it works?
esphome:
name: modbus-scanner
friendly_name: Modbus Scanner
on_boot:
priority: -10
then:
- script.execute: scan_addresses
esp32:
board: esp32dev
framework:
type: esp-idf
# Enable logging
logger:
level: DEBUG
# Enable Home Assistant API
api:
encryption:
key: "***********"
ota:
- platform: esphome
password: "*********"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Modbus-Scanner Fallback Hotspot"
password: "**************"
captive_portal:
uart:
id: mod_bus
tx_pin: TX
rx_pin: RX
baud_rate: 9600
stop_bits: 1
parity: NONE
modbus:
id: modbus1
#flow_control_pin: GPIO4 # Change to your wiring
modbus_controller:
- id: scanner_device
address: 1
modbus_id: modbus1
update_interval: never # we'll trigger updates manually
# A simple test register to read. Change to an input register if needed.
sensor:
- platform: modbus_controller
modbus_controller_id: scanner_device
name: "Scanner Test Register"
id: test_reg
register_type: holding # try 'input' if your device exposes only input regs
address: 0x0000 # change to a known-good register if you have one
value_type: U_WORD
accuracy_decimals: 0
on_value:
then:
- lambda: |-
ESP_LOGI("scanner", "✅ Found responding device at address %d", id(current_addr));
globals:
- id: scan_index
type: int
restore_value: no
initial_value: '1' # start at address 1
- id: current_addr
type: int
restore_value: no
initial_value: '1'
script:
- id: scan_addresses
then:
- logger.log: "🔍 Starting Modbus address scan (1..247)..."
- while:
condition:
lambda: 'return id(scan_index) <= 247;'
then:
- lambda: |-
id(current_addr) = id(scan_index); // remember for logging
id(scanner_device).set_address(id(current_addr));
- component.update: scanner_device # poll controller (reads test_reg)
- delay: 300ms
- lambda: 'id(scan_index) += 1;'
- logger.log: "✅ Scan finished."
I guess that next step is to try a different 485 board to see if that solves it…
anyone know if there is a way to test and verify it?
thanks
Hi Everyone,
I am a solar installer and Sigenergy Inverters can switch on SG Ready heat pumps using their DO port as described here: https://drive.google.com/file/d/1PLkny0YojKDxslZx-K8HUSDfTHJV6z7v/view?usp=sharing. Can anyone advise which port on the heat pump control board the DO1 and DO2 wires should connect to? I am guessing the BAG +12V port and specifically the DO1 would go to A and the DO2 would go to B but I wonder if anyone has any experience with this? Or should they be going to a different port altogether - perhaps what is labelled as remote controller on this wiring diagram
Hallo Alex ,
ich heiße Roman, bin auch aus Deutschland und habe auch die selbe Wärmepumpe wie du. Ich heize auch den Haus mit der Pumpe nur die Wärmepumpe hat zu viel Leistung und schaltet nach zu oft aus , meine Idee ist Leistung von der Pumpe zu regeln anhand Kompressor Frequenz . Hast du vielleicht eine Idee wie ich das realisieren kann?
Hallo, das Problem habe ich auch regel das zurzeit über den Modbus mit Super Silence (max 28% )oder Silence (Max 80%).
Läuft gut aber schöner wäre das direkt die Kompressorfrequenz zu steuern.
Ich war eine Zeitlang bei den China Anbietern unterwegs um informationen zu bekommen.
Bin aber aus familiären zeitlichen Gründen noch nicht weiter gekommen.
Ich habe noch ein paar Modbus Register bekommen direkt für den DC Inverter. Bringt aber nicht viel den Kompressor zu regeln wenn das EEV von der Hauptplatine bei mir MWH 298 geregelt wird.
Aber sobald ich mehr zeit habe, werde ich mich hier auch wieder melden.
LG
Ich habe zwar für ein Leistungstärkeres Board diese Modbus Informationen bekommen.
Aber es sollten die gleichen sein.
So könnte man ja den Kompressor direkt ansteuern wenn man sich zwischen Hauptplatine und DC board klemmt. Den Modbussteckplatz sieht man ja in der PDF.
I did receive these Modbus details for a more powerful board,
but they should be identical.
This would allow the compressor to be controlled directly if you tap in between the main board and the DC board.
The Modbus connector can be seen in the PDF.
Thanks for the info in this topic!
I have a Fairland Inver-X Vertical heatpump and added a m5stack atom lite + tail485. Imo this is a really easy solution as you only need 1 cable to connect everything.
This is what I used:
- m5stack atom lite: ATOM Lite ESP32 IoT Development Kit– m5stack-store
- m5stack tail485: ATOM Tail485 - RS485 Converter for ATOM– m5stack-store
- JST-XH 3S 4-pins cable: https://www.amazon.com.be/dp/B07JF651PG?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1
I followed this guide to configure the atom using home assistant ESPHome Builder: https://docs.m5stack.com/en/homeassistant/light/atom_lite_light
Then I installed this Yaml on the esp32. This one is giving all relevant sensor data. Temperatures are in Celsius. Edit the HIDDEN strings to correspond with your data.
esphome:
name: warmtepomp-fairland
friendly_name: Fairland Inver-X
esp32:
board: m5stack-atom
flash_size: 4MB
framework:
type: esp-idf
logger:
baud_rate: 0 # Disabled — UART needed for Modbus
api:
encryption:
key: "HIDDEN"
ota:
- platform: esphome
password: "*****************"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Fairland Fallback Hotspot"
password: "HIDDEN"
captive_portal:
# --- UART for RS485 (Tail485 pins) ---
uart:
id: mod_bus
tx_pin: GPIO26
rx_pin: GPIO32
baud_rate: 9600
stop_bits: 1
parity: NONE
data_bits: 8
modbus:
id: modbus1
uart_id: mod_bus
modbus_controller:
- id: fairland
address: 0x01
modbus_id: modbus1
update_interval: 10s
command_throttle: 100ms # 100ms between requests, well above 60ms minimum
# ============================================================
# BINARY SENSORS
# ============================================================
binary_sensor:
# --- Atom Lite Button ---
- platform: gpio
pin:
number: GPIO39
mode: INPUT
inverted: true
name: "Atom Button"
id: atom_button
filters:
- delayed_on: 50ms
- delayed_off: 50ms
on_multi_click:
- timing:
- ON for at most 0.8s
- OFF for at most 0.5s
- ON for at most 0.8s
- OFF for at least 0.2s
then:
- logger.log: "Double Clicked"
- light.turn_on:
id: atom_light
red: 100%
blue: 50%
green: 20%
brightness: 50%
- timing:
- ON for at least 0.8s
then:
- logger.log: "Single Long Clicked"
- light.turn_on:
id: atom_light
green: 100%
blue: 50%
red: 30%
brightness: 100%
# --- Warmtepomp status ---
- platform: modbus_controller
modbus_controller_id: fairland
name: "Status ON/OFF"
register_type: discrete_input
address: 0
force_new_range: true
- platform: modbus_controller
modbus_controller_id: fairland
name: "Ontdooien Actief"
register_type: discrete_input
address: 1
force_new_range: true
- platform: modbus_controller
modbus_controller_id: fairland
name: "Storing / Beveiliging"
register_type: discrete_input
address: 16
force_new_range: true
# ============================================================
# LED
# ============================================================
light:
- platform: esp32_rmt_led_strip
rgb_order: GRB
pin: GPIO27
num_leds: 1
chipset: SK6812
name: "Atom RGB Light"
id: atom_light
restore_mode: RESTORE_DEFAULT_OFF
effects:
- random:
name: "Random"
transition_length: 1s
update_interval: 1s
# ============================================================
# SENSORS (Input Registers FC04)
# Temperature type 1: °C = (raw - 60) / 2 → filters: multiply 0.5, offset -30
# Temperature type 2: °C = raw / 2 → filters: multiply 0.5 only
# All values arrive in HA already converted to °C
# ============================================================
sensor:
- platform: modbus_controller
modbus_controller_id: fairland
name: "Compressor Snelheid"
register_type: read
address: 0
force_new_range: true
unit_of_measurement: "%"
state_class: measurement
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: fairland
name: "PFC Spanning"
register_type: read
address: 2
force_new_range: true
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: fairland
name: "Inlaatwater Temperatuur"
id: pwp_inlet_water_temperature
register_type: read
address: 3
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5
- offset: -30
- platform: modbus_controller
modbus_controller_id: fairland
name: "Uitlaatwater Temperatuur"
register_type: read
address: 4
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5
- offset: -30
- platform: modbus_controller
modbus_controller_id: fairland
name: "Buitentemperatuur"
register_type: read
address: 5
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5
- offset: -30
- platform: modbus_controller
modbus_controller_id: fairland
name: "Gas Uitlaat Temperatuur"
register_type: read
address: 6
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5 # Type 2 — no offset
- platform: modbus_controller
modbus_controller_id: fairland
name: "Buitenspoel Temperatuur"
register_type: read
address: 7
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5
- offset: -30
- platform: modbus_controller
modbus_controller_id: fairland
name: "Gas Retour Temperatuur"
register_type: read
address: 8
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5
- offset: -30
- platform: modbus_controller
modbus_controller_id: fairland
name: "Binnenspoel Temperatuur"
register_type: read
address: 9
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5
- offset: -30
- platform: modbus_controller
modbus_controller_id: fairland
name: "Compressor Frequentie"
register_type: read
address: 10
force_new_range: true
unit_of_measurement: "Hz"
state_class: measurement
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: fairland
name: "Compressor Stroom"
register_type: read
address: 11
force_new_range: true
unit_of_measurement: "A"
device_class: current
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: fairland
name: "Koelplaat Temperatuur"
register_type: read
address: 12
force_new_range: true
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
value_type: U_WORD
filters:
- multiply: 0.5 # Type 2 — no offset
- platform: modbus_controller
modbus_controller_id: fairland
name: "EEV Opening"
register_type: read
address: 13
force_new_range: true
state_class: measurement
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: fairland
name: "DC Ventilator Snelheid"
register_type: read
address: 14
force_new_range: true
unit_of_measurement: "RPM"
state_class: measurement
value_type: U_WORD
# ============================================================
# SWITCH
# ============================================================
switch:
- platform: modbus_controller
modbus_controller_id: fairland
name: "Warmtepomp Aan/Uit"
register_type: coil
address: 0
# ============================================================
# SELECT (mode control)
# ============================================================
select:
- platform: modbus_controller
modbus_controller_id: fairland
name: "Functie Selectie"
address: 0
value_type: U_WORD
optionsmap:
"Auto": 0
"Verwarmen": 1
"Koelen": 2
- platform: modbus_controller
modbus_controller_id: fairland
name: "Werkingsmodus"
address: 1
value_type: U_WORD
optionsmap:
"Smart": 0
"Stil": 1
"Turbo": 3
- platform: modbus_controller
modbus_controller_id: fairland
name: "Waterpomp Modus"
address: 5
value_type: U_WORD
optionsmap:
"Continu": 0
"Watertemperatuur Gestuurd": 1
"Tijd + Watertemperatuur": 2
# ============================================================
# NUMBERS
# Raw registers hidden, template entities show clean °C
# Conversion: °C = (raw - 60) / 2 | raw = (°C × 2) + 60
# ============================================================
number:
# --- Hidden raw Modbus registers ---
- platform: modbus_controller
modbus_controller_id: fairland
id: fairland_verwarmen_raw
internal: true
address: 3
register_type: holding
value_type: U_WORD
min_value: 96
max_value: 140
step: 2
- platform: modbus_controller
modbus_controller_id: fairland
id: fairland_koelen_raw
internal: true
address: 4
register_type: holding
value_type: U_WORD
min_value: 84
max_value: 120
step: 2
- platform: modbus_controller
modbus_controller_id: fairland
name: "Waterpomp Werktijd"
address: 6
register_type: holding
value_type: U_WORD
min_value: 10
max_value: 120
step: 5
unit_of_measurement: "min"
# --- Human-readable °C template entities ---
- platform: template
name: "Verwarmen Doeltemperatuur"
unit_of_measurement: "°C"
device_class: temperature
min_value: 18
max_value: 40
step: 0.5
lambda: |-
return (id(fairland_verwarmen_raw).state - 60.0) / 2.0;
set_action:
- number.set:
id: fairland_verwarmen_raw
value: !lambda return (x * 2.0) + 60.0;
- platform: template
name: "Koelen Doeltemperatuur"
unit_of_measurement: "°C"
device_class: temperature
min_value: 12
max_value: 30
step: 0.5
lambda: |-
return (id(fairland_koelen_raw).state - 60.0) / 2.0;
set_action:
- number.set:
id: fairland_koelen_raw
value: !lambda return (x * 2.0) + 60.0;
To open the Inver-X Vertical: first unscrew 3 screws on the top back of the heatpump to remove the top cover. Then unscrew all screws securing the front plate (multiple on the bottom, multiple on the top hidden under the top cover, also one or 2 on the right side behind the cover where the power cable enters the heatpump). After all screws of the front plate are unscrewed, you can lift the front cover, being carefull as the control screen is connected with a cable, just move it to the side a bit.
Then you can easily connect the atom:
I just left the atom in the enclosure and it had enough WiFi range to connect to my access point which is a couple of meters away.
I didn’t change anything on the dip switches:
In case some else is looking for a suitable 4 pin plug to use instead of opening up the heatpump. This one was a perfect match and is identical to the wifi module plug (4Pin, 0.3mm2). https://nl.aliexpress.com/item/1005011641408936.html Do double check the size references on your own unit.





