Controlling a Fairland Pool Heatpump eliminating Tuya

Hi all, I’ve been working on dropping my local Tuya config for an Esphome based control too. Your code @rstcologne has been of great help.
I’ve used devices from M5Stack, which saves you the soldering and just use out of the box solutions.

I’ve used a M5Stickc with an RS485 hat (which has a 12v-5v converter inside):

Most of the yaml is identical, I’ve just included it for future reference for others. Main difference is in the m5stickc config and the gpio ports:

esphome:
  name: pool-fairland-heatpump
  friendly_name: pool-fairland-heatpump
  
substitutions:
  ip: !secret pool_heatpump_ip

<<: !include .common.yaml

esp32:
  board: m5stick-c
  framework:
    type: arduino

# Enable logging
logger:
  baud_rate: 0
  hardware_uart: UART0
  level: INFO
  #level: VERBOSE #makes uart stream available in esphome logstream

uart:
  id: mod_bus
  tx_pin: GPIO0
  rx_pin: GPIO26
  baud_rate: 9600
  data_bits: 8
  stop_bits: 1
  parity: NONE
  # debug:
  #   direction: BOTH
  #   dummy_receiver: false
  #   after:
  #     delimiter: "\n"
  #   sequence:
  #     - lambda: UARTDebug::log_string(direction, bytes);
  
modbus:
  id: modbus1

modbus_controller:
  - id: fairland
    ## the Modbus device addr
    address: 0x0001
    modbus_id: modbus1
    update_interval: 5s
    

light:
  # Built-in Red Status LED Light. See https://esphome.io/components/light/status_led.html
  - platform: status_led
    name: "LED Light"
    restore_mode: ALWAYS_OFF
    pin:
      number: GPIO10
      inverted: true
# Built-in buttons. See https://esphome.io/components/button/
# binary_sensor:
#   - platform: gpio
#     pin:
#       number: GPIO37
#       inverted: true
#     id: button_a
#     name: Button A
#   - platform: gpio
#     pin:
#       number: GPIO39
#       inverted: true
#     id: button_b
#     name: Button B

# Built-in infrared transmitter. See https://esphome.io/components/remote_transmitter.html
# and https://m5stack.hackster.io/alessandro-polselli/turn-m5stickc-into-universal-ir-remote-home-automation-d3ec0d
remote_transmitter:
  pin: GPIO9
  carrier_duty_percent: 50%

# sensor:
#   - platform: axp192
#     address: 0x34
#     i2c_id: bus_a
#     model: M5STICKC
#     update_interval: 30s
#     battery_level:
#       name: "Battery Level"
#       id: "battery_level"

spi:
  clk_pin: GPIO13
  mosi_pin: GPIO15

i2c:
  - id: bus_a
    sda: GPIO21
    scl: GPIO22
    scan: True

# Fonts
font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 12

# builtin 80x160 TFT
display:
  - platform: st7735
    model: "INITR_MINI160X80"
    cs_pin: GPIO5
    dc_pin: GPIO23
    reset_pin: GPIO18
    device_height: 80
    device_width: 160
    row_start: 1
    col_start: 1
    rotation: 270
    update_interval: 2s
    lambda: |-
      it.print(80, 0, id(roboto), TextAlign::TOP_CENTER, "M5Stickc Fairland Pool - Modbus");



###################################################
# Elements with Modbus Operation read 01 / write 05
# coil
###################################################
# 0	Power
# 1	compulsory defrosting
# 2~47	reserve
###################################################

switch:
  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Power Switch"
    id: power_switch
    icon: "mdi:power"
    register_type: coil
    address: 0x0

###################################################
# Elements with Modbus Operation read 03 / write 06
# holding
###################################################
# address content	Range	Unit	Step length	Defaut	Illustration
# 0	mode selection 1	0~2				0:Auto,1:Heating,2:Cooling
# 1	mode selection 2	0~3		1	1	0:Normal,1:silence,2:Super silence, 3: Turbo
# 2	Temp setting under Auto mode	18~35	℃	1	25	
# 3	Temp setting under heating mode					
# 4	Temp setting under cooling mode	30~95	%	1	50	
# 5	Running mode of water pump	0~2		1	0	"0:Continuation 
# 1:Water temp control
# 2:time/water temp control
# "
# 6	Time setting of water pump (When under running mode 2)	10 ~ 120 	min	5	60	
# 7	The compressor runs continuously before defrosting enters	20~90	min	1	20	
# 8	Defrosting start temp	-10~10	℃	1	-1	
# 9	Defrosting running time	1~12	min	1	8	
# 10	Defrosting quit temp	0~30	℃	1	8	
# 11	Fixed speed mode selection					
# 12	reserve					
# 13	reserve					
# 14	Low temperature shutdown protection correction amount					
# 12	reserve					
# 13	reserve					
# 17	Electronic expansion valve overheat level(heating)	-10~20	℃	1	3	
# 18	Electronic expansion valve overheat level(cooling)	-10~20	℃	1	3	
# 19	Electronic expansion valve manual/auto	0~1		1	0	0:auto,1:Manual
# 20	Electronic expansion valve openning setting(heating)	50~240		2	100	
# 21	Electronic expansion valve openning setting(cooling)	50~240		2	100	
# 22	The medium frequency ratio selection					
# 23	reserve					
# 24	reserve					
# 25	Power off memory function	0~1		1	1	0: None;  1: Yes  
# 26	reserve					
# 27	reserve					
# 28	reserve					
# 29	reserve					
# 30	reserve					
# 31	reserve					
# 32	reserve					
###################################################

select:
  - platform: modbus_controller
    name: "Operating Mode"
    id: operating_mode
    icon: "mdi:fan"
    modbus_controller_id: fairland
    address: 0x0
    value_type: U_WORD
    optionsmap: 
      "Auto": 0
      "Heating": 1
      "Cooling": 2
    
  - platform: modbus_controller
    name: "Power Mode"
    id: power_mode
    icon: "mdi:fan"
    modbus_controller_id: fairland
    address: 0x1
    value_type: U_WORD
    optionsmap: 
      "Super Silence": 2
      "Silence": 1
      "Normal": 0
      "Turbo": 3

# Temperature Formula
# ((value - 96) / 2) + 18

number:
  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Target Temperature Heating"
    id: target_temperature_heating
    icon: "mdi:sun-thermometer-outline"
    address: 0x3
    value_type: U_WORD
    unit_of_measurement: "°C"
    min_value: 18
    max_value: 32
    lambda: "return (x-96) / 2 + 18;"
    write_lambda: |- 
      ESP_LOGD("main", "Modbus Number incoming value = %f", x);
      return ((x-18) * 2 + 96) * 1.0;

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Target Temperature Auto"
    id: target_temperature_auto
    icon: "mdi:thermometer-auto"
    register_type: holding
    address: 0x2
    value_type: U_WORD
    unit_of_measurement: "°C"
    min_value: 18
    max_value: 32
    lambda: "return (x-96) / 2 + 18;"
    write_lambda: |- 
      ESP_LOGD("main", "Modbus Number incoming value = %f", x);
      return ((x-18) * 2 + 96) * 1.0;

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Target Temperature Cooling"
    id: target_temperature_cooling
    icon: "mdi:snowflake-thermometer"
    register_type: holding
    address: 0x4
    value_type: U_WORD
    unit_of_measurement: "°C"
    min_value: 18
    max_value: 32
    lambda: "return (x-96) / 2 + 18;"
    write_lambda: |- 
      ESP_LOGD("main", "Modbus Number incoming value = %f", x);
      return ((x-18) * 2 + 96) * 1.0;




###################################################
# Elements with Modbus Operation read 04 / write NA
# read
###################################################
# 0	Percentage of speed					
# 1	Target frequency of compressor					
# 2	Voltage of PFC					
# 3	Inlet water temp					
# 4	Outlet water temp					
# 5	Ambient air temp					
# 6	Dircharge temp					
# 7	Outer coil pipe temp					
# 8	Suction temp					
# 9	Inner coil pipe tem 					
# 10	Running frequency of compressor					
# 11	Current of compressor					
# 12	Cooling plate temp					
# 13	Electronic expansion valve opening					
# 14	DC fan speed					
# 15	Lower limit of setting temp of auto mode					
# 16	Upper limit of setting temp of auto mode					
# 17	Lower limit of setting temp of heating mode					
# 18	Upper limit of setting temp of heating mode					
# 19	Lower limit of setting temp of cooling mode					
# 20	Upper limit of setting temp of cooling mode					
# 21	Motherboard version code1					ASCII code
# 22	Motherboard version code2					ASCII code
# 23	Motherboard version code3					ASCII code
# 24	Motherboard version code4					ASCII code
# 25	Motherboard version code5					ASCII code
# 26	Model code1					ASCII code
# 27	Model code2 ('C'is heating and cooling version,‘H’is heating version)					ASCII code
# 28	Model code3					ASCII code
# 29	Model code4					ASCII code
# 30	Voltage of power supply		V	1		
# 31	The remaining time of Compressor shutdown protection 		S	1		
# 32	reserve					
###################################################

sensor:

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Speed Percentage"
    id: speed_percentage
    icon: "mdi:fan-speed-1"
    register_type: read
    address: 0x0
    value_type: U_WORD
    unit_of_measurement: "%"

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Voltage of PFC"
    id: voltage_of_pfc
    icon: "mdi:flash-triangle"
    register_type: read
    address: 0x2
    value_type: U_WORD
    unit_of_measurement: "V"
    
  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Inlet water Temperature"
    id: inlet_water_temperature
    icon: "mdi:thermometer-chevron-up"
    register_type: read
    address: 0x3
    value_type: U_WORD
    unit_of_measurement: "°C"
    filters:
      - offset: -96
      - multiply: 0.5
      - offset: 18

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Outlet water Temperature"
    id: outlet_water_temperature
    icon: "mdi:thermometer-chevron-down"
    register_type: read
    address: 0x4
    value_type: U_WORD
    unit_of_measurement: "°C"
    filters:
      - offset: -96
      - multiply: 0.5
      - offset: 18

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Ambient Air Temperature"
    id: ambient_air_temperature
    icon: "mdi:home-thermometer-outline"
    register_type: read
    address: 0x5
    value_type: U_WORD
    unit_of_measurement: "°C"
    filters:
      - offset: -96
      - multiply: 0.5
      - offset: 18

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Compressor Current"
    id: compressor_current
    icon: "mdi:sine-wave"
    register_type: read
    address: 11
    value_type: U_WORD
    unit_of_measurement: "A"
    filters:
      - multiply: 0.1

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Compressor Running Frequency"
    id: compressor_running_frequency
    icon: "mdi:repeat-variant"
    register_type: read
    address: 10
    value_type: U_WORD
    unit_of_measurement: "Hz"

  - platform: template
    name: "Compressor Power"
    id: compressor_power
    icon: "mdi:lightning-bolt"
    unit_of_measurement: "W"
    lambda: |-
      if (id(compressor_current).state) {
      return id(compressor_current).state * id(voltage_of_pfc).state;
      } else {
      return 0.0;
      }    
    update_interval: 1s

###################################################
# Elements with Modbus Operation read 02 / write NA
# discrete_input
###################################################
# 0	Switch on/off
# 1	Defrosting
# 2	Temperature adjustment
# 3	Silence
# 4	Anti-freeze
# 5	Cooling mode selection
# 6	Remote controll
# 7	Water flow swtich
# 8	High pressure swtich
# 9	Low pressure swtich
# 10	Compressor
# 11	Outdorr fan motor
# 12	4-Way valve
# 13	Bypass valve
# 14	reserve
# 15	Heating element in the basis
# 16	reserve
# 17	Circulation pump
# 17~47	reserve
# 48	E0
# 49	E1
# 50	E2
# 51	E3
# 52	E4
# 53	E5
# 54	E6
# 55	E7
# 56	E8
# 57	E9
# 58	EA
# 59	EB
# 60	EC
# 61	ED
# 62	EE
# 63	EF
# 64	P0
# 65	P1
# 66	P2
# 67	P3
# 68	P4
# 69	P5
# 70	P6
# 71	P7
# 72	P8
# 73	P9
# 74	PA
# 75	PB
# 76	PC
# 77	PD
# 78	PE
# 79	PF
# 80	F0
# 81	F1
# 82	F2
# 83	F3
# 84	F4
# 85	F5
# 86	F6
# 87	F7
# 88	F8
# 89	F9
# 90	FA
# 91	FB
# 92	FC
# 93	FD
# 94	FE
# 95	FF
###################################################
binary_sensor:
  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E0"
    id: error_E0
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 48
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E1 - High Pressure Protection"
    id: error_E1
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 49
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E2 Low Pressure Protection"
    id: error_E2
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 50
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Warning E3 No Water Protection"
    id: error_E3
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 51
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E4 3 Phase Sequence Protection"
    id: error_E4
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 52
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Warning E5 Power Supply Excesses Operation Range"
    id: error_E5
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 53
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Warning E6 Insufficient Water Flow"
    id: error_E6
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 54
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E7 Water Outlet Temp too high or too low"
    id: error_E7
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 55
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E8 High Exhaust Temp Protection"
    id: error_E8
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 56
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error E9"
    id: error_E9
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 57
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error EA Evaporator overheat protection"
    id: error_EA
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 58
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Warning EB Ambient Temperature too high or too low"
    id: error_EB
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 59
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error EC"
    id: error_EC
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 60
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Warning  ED Anti-Freezing Reminder"
    id: error_ED
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 61
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error EF"
    id: error_EF
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 62
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P0 Controller Communication Failure"
    id: error_P0
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 64
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P1 Water Inlet Temp Sensor Failure"
    id: error_P1
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 65
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P2 Water Outlet Temp Sensor Failure"
    id: error_P2
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 66
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P3 Gas Exhaust Temp Sensor Failure"
    id: error_P3
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 67
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P4 Evaporator Coil Pipe Temp Sensor Failure"
    id: error_P4
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 68
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P5 Gas Return Temp Sensor Failure"
    id: error_P5
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 69
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P6 Cooling Coil Pipe Temp Sensor Failure"
    id: error_P6
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 70
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P7 Ambient Temp Sensor Failure"
    id: error_P7
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 71
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P8 Cooling Plate Sensor Failiure"
    id: error_P8
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 72
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error P9 Current Sensor Failure"
    id: error_P9
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 73
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error PA Restart Memory Failure"
    id: error_PA
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 74
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error PB"
    id: error_PB
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 75
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error PC"
    id: error_PC
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 76
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error PD"
    id: error_PD
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 77
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error PE"
    id: error_PE
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 78
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error PF"
    id: error_PF
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 79
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F0"
    id: error_F0
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 80
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F1 Compressor Drive Module Failure"
    id: error_F1
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 81
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F2 PFC Module Failure"
    id: error_F2
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 82
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F3 Compressor Start Failure"
    id: error_F3
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 83
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F4 Compressor Running Failure"
    id: error_F4
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 84
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F5 Inverter Board Over Current Protection"
    id: error_F5
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 85
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F6 Inverter Board Over Temperature Protection"
    id: error_F6
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 86
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F7 Current Protection"
    id: error_F7
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 87
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F8 Cooling Plate Overheat Protection"
    id: error_F8
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 88
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error F9 Fan Motor Failure"
    id: error_F9
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 89
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error FA PFC Module Over Current Protection"
    id: error_FA
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 90
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error FB Power Filter Plate No-Power Protection"
    id: error_FB
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 91
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error FC"
    id: error_FC
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 92
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error FD"
    id: error_FD
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 93
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error FE"
    id: error_FE
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 94
    device_class: PROBLEM

  - platform: modbus_controller
    modbus_controller_id: fairland
    name: "Error FF"
    id: error_FF
    icon: "mdi:check-circle"
    register_type: discrete_input
    address: 95
    device_class: PROBLEM

1 Like