XY-ST30-W Temp Controller

I am using this Temperature Controller Module for my Bambu Lab Chamber heater. I would like to use ESPHome on it, instead of Sinilink App
I have flashed the ESP8285 without a problem to ESPHome.

Does someone already has write a program to read/write the modus data.

Model: XY-ST30-W or XY-ST10-W

If you can’t find the modbus registers for the device, you have to probe little bit.
I managed to get all registers from another XY-device:
slave address 1
Uart 115200 bps, 8N1
single holding registers starting from 0x0000

I have found a semi similar product. At the end of the datasheet the Modbus data structure is described.

I have no experience in programming, hopefully someone can help with a basic code then I can start testing the each registers.

Did you flash the chip through the pin header? I mean do you know the uart pins used there?

Yes, I flashed through the pin header holes.

Try if you get any response:

uart:
  tx_pin: GPIO1
  rx_pin: GPIO3
  baud_rate: 115200

modbus:
  id: modbus1

modbus_controller:
- id: modbus_device
  address: 0x1   ## address of the Modbus slave device on the bus
  modbus_id: modbus1
  
sensor:
- platform: modbus_controller
  modbus_controller_id: modbus_device
  name: "Temp"
  register_type: holding
  address: 0x0003    ## address of the register inside the Modbus slave device
  unit_of_measurement: "C"
  value_type: S_WORD

and set logger baudrate to 0

logger:
  baud_rate: 0

Temp sensor is working, actual temp on display is 21.2

afbeelding

Nice.

Add this to your temp sensor:

filters:
  - multiply: 0.1

Then just copy/paste the sensors for addresses you are interested in (hoping that the registers of your device are same with the one you linked).

Most of the sensors I have working.
But I am struggeling getting the relay to work in HA, I tried lots of different codes but notting works.
If I manual press the relay On/Off button on the device it show the correct status in HA.

afbeelding
afbeelding

switch:
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0x0000
    name: "Relay"
    skip_updates: 5
    use_write_multiple: false
    bitmask: 1
    icon: "mdi:toggle-switch"

Is that bitmask required?
If you want to see what’s going on, add debug to your uart config and see what is sent when you change the state in HA and what’s received when you change state on the device.

uart:
  baud_rate: 115200
  debug:
    direction: BOTH

UART Debug when Pressing ON/OFF Button on Device.
[20:48:43.390][D][switch:065]: ‘Relay’: Sending state ON
[20:48:43.390][D][uart_debug:114]: <<< 01:03:02:00:01:79:84
[20:48:48.366][D][uart_debug:114]: >>> 01:03:00:00:00:01:84:0A
[20:48:48.481][D][uart_debug:114]: <<< 01:03:02:00:01:79:84
[20:48:54.339][D][uart_debug:114]: >>> 01:03:00:00:00:01:84:0A
[20:48:54.354][D][switch:065]: ‘Relay’: Sending state OFF
[20:48:54.454][D][uart_debug:114]: <<< 01:03:02:00:00:B8:44

UART Debug when Pressing ON/OFF Button in HA.
[20:50:30.135][D][switch:022]: ‘Relay’ Turning ON.
[20:50:30.137][D][switch:065]: ‘Relay’: Sending state ON
[20:50:30.242][D][uart_debug:114]: >>> 01:06:00:00:FF:FF:88:7A
[20:50:30.500][D][uart_debug:114]: >>> 01:06:00:00:FF:FF:88:7A
[20:50:30.694][D][uart_debug:114]: >>> 01:06:00:00:FF:FF:88:7A
[20:50:30.709][D][uart_debug:114]: <<< 01:06:00:00:FF:FF:88:7A
[20:50:30.823][D][uart_debug:114]: >>> 01:03:00:00:00:01:84:0A
[20:50:31.001][D][uart_debug:114]: >>> 01:03:00:00:00:01:84:0A
[20:50:31.014][D][switch:065]: ‘Relay’: Sending state OFF
[20:50:31.116][D][uart_debug:114]: <<< 01:03:02:00:00:B8:44

The problem is when switch to ON in HA it immediately turn OFF again without switching the relay.

No, the problem is that it never sends ON request to the device. Your visual switch state on HA is completely irrelevant.

This is incorrect:

it should be 01:06:00:00:00:01…

Can’t get it to work.

switch:
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0x0000
    name: "Relay"
    skip_updates: 5
    use_write_multiple: false 
    write_lambda: |-
      payload.push_back(0x01);
      payload.push_back(0x06);
      payload.push_back(0x00);
      payload.push_back(0x00);
      
      if (x) {
        payload.push_back(0x00);
        payload.push_back(0x01);
      } else {
        payload.push_back(0x00);
        payload.push_back(0x00);
      }
      return true;
    lambda: |-
      return (x == 1);

UART Log:
[switch:022]: ‘Relay’ Turning ON.
[switch:065]: ‘Relay’: Sending state ON
[uart_debug:114]: >>> 01:06:00:00:00:01:48:0A
[uart_debug:114]: >>> 01:06:00:00:00:01:48:0A
[uart_debug:114]: >>> 01:06:00:00:00:01:48:0A
[uart_debug:114]: <<< 01:06:00:00:00:01:48:0A
[uart_debug:114]: >>> 01:03:00:00:00:01:84:0A
[switch:065]: ‘Relay’: Sending state OFF

Too vague.
Explain what happens. And post the logs always with timing.

What we really know is that device replies to read request with 0x0000 (off) and 0x0001(on).
Now your lambda matches to that. Before your switch was using FFFF for ON (esphome default).

But we don’t know for sure if that register is accepting write request in the first place.
Or there is some weird logic on that device that it is looking for different write command that it uses for response. Could be FFFF, FF00, 000A for example.
Ideally any other than 0000 would be ON, but world is not ideal…

Finally find some time to troubleshoot.
I have made it working, the ON/OFF address is: 0x0011

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Relay Control"
    address: 0x0011
    register_type: holding
    use_write_multiple: false
    icon: "mdi:power-cycle"
     # SENDING the command to 0x0011
    write_lambda: |-
      payload.push_back(0x01);
      payload.push_back(0x06);
      payload.push_back(0x00);
      payload.push_back(0x11); 

      if (x) {
        payload.push_back(0x00);
        payload.push_back(0x00);
      } else {
        payload.push_back(0x00);
        payload.push_back(0x01);
      }
      return true;
    # MATCHING the UI toggle to the status at 0x0000
    lambda: |-
      return (id(relay_raw_state).state > 0);

That makes sense! :+1: