Skip to content
View in the app

A better way to browse. Learn more.

Power Forum - Renewable Energy Discussion

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

8Kw SunSynk with ESP32 and RS485 not communicating.

Featured Replies

Hi All

I have been at this for weeks and have never been this frustrated with a project in my life. I just don't seem to be getting a response from my inverter to the ESP32 Dev board in ESPHome. I have tried multiple ESP boards with multiple RS485 TTL boards and RJ45 cables and cable pinouts.

Please someone out there save my marriage!!

I have followed "Solar Integration" Channel with Slipx06 yaml files and pinned out accordingly with all the troubleshooting steps. These are the logs and yaml config. Modbus on the inverter is set to 1

substitutions:
  settings_skipped_updates: "30"
  devicename: sunsynk
  device_description: "Sunsynk RS485 Logger"
  friendly_name: "SunSynk"
 
esphome:
  name: $devicename
  comment: '${device_description}'
 
esp32:
  board: esp32dev
  framework:
    type: arduino
 
# Enable logging
logger:
  baud_rate: 0
  level: DEBUG
 
# Enable Home Assistant API
api:
  encryption:
    key: !secret api_key
 
ota:
 
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
 
# Optional manual IP
  manual_ip:
    static_ip: 192.168.1.46
    gateway: 192.168.1.1
    subnet: 255.255.255.0
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-9Ce5D0"
    password: ""
 
  fast_connect: true
  power_save_mode: none
 
captive_portal:

time:
  - platform: homeassistant
    id: homeassistant_time
     
uart:
  id: mod_bus
  tx_pin: 17
  rx_pin: 16
  baud_rate: 9600
  stop_bits: 1
  parity: EVEN
  data_bits: 8
 
modbus:
  id: sunsynk_modbus
  flow_control_pin: 4
  #send_wait_time: 500ms
 
modbus_controller:
  - id: sunsynk
    address: 1
    modbus_id: sunsynk_modbus
    setup_priority: -10
    update_interval: "15s"
    command_throttle: "50ms"

 

Logs 1.JPG

Logs 2.JPG

Logs 3.JPG

ESP32 Pins.JPG

Breadboard.jpg

Hi @frankthetank just to confirm, you removed the R7 resistor? 

Are you in Joburg? If so you are welcome to stop by my house and I will have a look at it for you. 

It looks like you have a communication problem to the inverter. 

If memory serves me correctly it looks like you have the Orange & Orange/White cables the wrong way around, have you tried the other way? 

I would also check that you have your TX/RX and flow control cables the correct way around (looks like you do but is difficult to be 100% sure)

Check your ethernet plug is correctly wired and it is plugged into the correct port on the inverter. 

Some inverters require a splitter for the RS485 port and the Canbus connection for the battery

  • Author

Hi @ScOObs

Thanks for the response, I'm in Durban.

Yeah, I have 2 x RS485 boards one with and one without the R7.

I have tried the following cabling options on both CAT 5e and CAT 6 

1 O/ to B

2 O to A

and visa versa

2 O and 7 B/ to A

1 O/ and 8 B to B

and visa versa

I have used pinouts GPIO1 and GPIO3 and swapped and also GPIO17 and GPIO16 and swapped. Flow control of GPIO4

I have put a volt meter on the RJ45 cables and getting around 3-4v when connected to the RS485 port on the inverter. It then drops down to around 1.2v once wired into the RS485 - TTL board. 

The 8kw Sunsynk has an RS485 port and I think only the 5Kw might have shared a port with the CANBUS buy I could be wrong. I also tried 2 different ESP32 boards. 

I agree that there is a communication issue from the inverter just cannot for the life of me figure out why. 

My other option is to run a longer network cable directly into my HA box which is running bare metal on a spare laptop. 

RJ45 Looks like this image.jpeg.dab1d1b6217522326bf7e523eaaa4f95.jpeg

@frankthetank I know that the  ESP32 can be very frustrating to get working and is difficult to diagnose where the fault is. 

I have also spent a lot of time trying to figure out where the problem was with my one. 

One of the comments on my video was that the MAX485 board that we have been using is a 5v board and that we should actually be using a 3.3v board

I think that I may try one of these and see if they are less finicky,

https://www.keebot.com/product/ttl-to-rs485-module-hardware-automatic-flow-control-module-serial-uart-level-mutual-converter-power-supply-module-3-3v-5v/ 

 

Hi @Sc00bs & @frankthetank 

Thanks for opening this thread and shedding some light on this. I would like to know if you have managed to solve the issue with reading the RS485 from the sunsynk with the ESP32. 
I am looking at a similar use case. 
My friend has started a small solar business where is going to be charging his customers a monthly fee for the solar equipment. 
What I have done so far is all external to the sunsynk, we have queried the accuracy of the kwh data present on the sunsynk and its accuracy, so I build him a current sensor using 2 x 100 amp CT on the input (eskom power) and the output( out of the inverter) at its working well, we found that the sunsynk is accurate. All of this data is collected using an ESP32 and transmits the data to a Thingsboard dashboard.  Now the next thing that we would like to achieve is to turn on and off the power from the solar and the batteries, this is coming into the inverter. The reason is for 'bad payers',  if the clients don't pay, we want to limit the inverter only to eskom mains. 

I was wondering if this can be done by making the inverter a slave and the ESP32 the master and then turning on and off the inputs (solar and battery)? 

What I am looking to gain from this is, if there is any documentation online about the sunsynk's rs485 transmission data and if you are able to control it, or if it is purely for monitoring and data logging purposes? 

Looking for any advice / comments questions. 

Thanks in advance. 

 
 

 

I was wondering if this can be done by making the inverter a slave and the ESP32 the master and then turning on and off the inputs (solar and battery)?

No need to change slave/master settings.

You simply need to write the settings you require via the sunsynk modbus protocol.

This post has a ton of info on how to use the sunsynk modbus protocol to both read data and write settings.

 

 

Hi All

I have been at this for weeks and have never been this frustrated with a project in my life. I just don't seem to be getting a response from my inverter to the ESP32 Dev board in ESPHome. I have tried multiple ESP boards with multiple RS485 TTL boards and RJ45 cables and cable pinouts.

Please someone out there save my marriage!!

I have followed "Solar Integration" Channel with Slipx06 yaml files and pinned out accordingly with all the troubleshooting steps. These are the logs and yaml config. Modbus on the inverter is set to 1

substitutions:
  settings_skipped_updates: "30"
  devicename: sunsynk
  device_description: "Sunsynk RS485 Logger"
  friendly_name: "SunSynk"
 
esphome:
  name: $devicename
  comment: '${device_description}'
 
esp32:
  board: esp32dev
  framework:
    type: arduino
 
# Enable logging
logger:
  baud_rate: 0
  level: DEBUG
 
# Enable Home Assistant API
api:
  encryption:
    key: !secret api_key
 
ota:
 
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
 
# Optional manual IP
  manual_ip:
    static_ip: 192.168.1.46
    gateway: 192.168.1.1
    subnet: 255.255.255.0
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-9Ce5D0"
    password: ""
 
  fast_connect: true
  power_save_mode: none
 
captive_portal:
 
time:
  - platform: homeassistant
    id: homeassistant_time
     
uart:
  id: mod_bus
  tx_pin: 17
  rx_pin: 16
  baud_rate: 9600
  stop_bits: 1
  parity: EVEN
  data_bits: 8
 
modbus:
  id: sunsynk_modbus
  flow_control_pin: 4
  #send_wait_time: 500ms
 
modbus_controller:
  - id: sunsynk
    address: 1
    modbus_id: sunsynk_modbus
    setup_priority: -10
    update_interval: "15s"
    command_throttle: "50ms"

 

Logs 1.JPG

Logs 2.JPG

Logs 3.JPG

ESP32 Pins.JPG

Breadboard.jpg

 I followed @Sc00bs video and got it working, and it's been working for a while, today I updated ESPHome to 2023.9.0 and it broke!

I now keep getting this:image.thumb.png.edeb35d84ef5b70763e689fa436250d3.png

I've reverted ESPHome to 2023.8.3 and reloaded the board, and it's still not reading, doesn't make sense! 

Next step is to revert Home Assistant to a previous backup. (Will advise if that fixes it)

Anyone have any ideas what to look for?

I Fixed it! (sort of)

Somehow the connections on the RS485 board came loose, so I reconnected it and it's reading again!

Here's my connections

 

IMG_7797.thumb.JPG.9ed6b24014a3b4d0f3459ca0aebde3e6.JPG

image.thumb.jpeg.93650ecbb60a252d29bb05700dbf4579.jpeg

Black wire is GND

Blue is Pin5 > RE

Yellow is RX > R0

Green is TX >DI

Code on the ESP32 - 

uart:
id: mod_bus
tx_pin: GPIO1
rx_pin: GPIO3
baud_rate: 9600
stop_bits: 1
 
modbus:
id: deye_modbus
flow_control_pin: GPIO5

Am looking for an easier way of getting the ESP32 working as it is rather tricky with a number of moving parts that can make diagnosing where the problem is difficult.

I am going to try using a different TTL-RS485 board and ESP32 Board and see if that makes it a bit easier. 

Will keep you guys posted

@Ar135 Glad you got your problem sorted 🙂 

  • Author

Hi @Ar135

Just to confirm are you running any power from the ESP32 to the RS485 or only the GND? I have red and black going to the RS485. I have tried with the 5v and the 3.3v which lights up the LED on the RS485 and then also tried no power only the GND which then the LED on the RS485 flashes dimly. 

@frankthetank No power to the RS485 only GND.

When I had the red and black I got nothing but errors, I accidentally removed the red and it started reading!

I also have Brown/White & Orange connected to 1 and Orange/White & Brown connected to the other 

with the R7 removed, all connected to a Deye 5KW so I'm not sure if there's going to be a difference.

 

image.thumb.jpeg.7b1fca92a82ff95c9b908744f7bc462a.jpeg

 

That RS485 module must be powered from 5V. But the ESP32 GPIO's are not 5V tolerant, so you need level converter between them. Which may be as easy as resistor dividers.

What do you mean by  " the ESP32 GPIO's are not 5V tolerant " ? 

 

What do you mean by  " the ESP32 GPIO's are not 5V tolerant " ? 

The ESP32 is powered by 3.3V . As a result its GPIO inputs are also on 3.3V logic specs . Feeding a ESP32 input with 5V logic is non-deterministic and may eventually lead to damage.  However there are 3.3V microcontrollers that are 3.3v but are 5V tolerant , meaning there inputs has been designed to entertain the higher levels of 5V logic. Also there outputs is guaranteed to meet the minimum 5V high  logic level spec.  Otherwise its just trouble ,  But the ESP32 is not 5V tolerant.

 

The ESP32 is powered by 3.3V . As a result its GPIO inputs are also on 3.3V logic specs . Feeding a ESP32 input with 5V logic is non-deterministic and may eventually lead to damage.  However there are 3.3V microcontrollers that are 3.3v but are 5V tolerant , meaning there inputs has been designed to entertain the higher levels of 5V logic. Also there outputs is guaranteed to meet the minimum 5V high  logic level spec.  Otherwise its just trouble ,  But the ESP32 is not 5V tolerant.

My son this weekend installed for me 2 x ESP32's powered with 5V, while the Max RS 232 converter connected to it uses the 3.3V, so I was just curious what you are meaning.  They are connected to 2 different Voltronic inverters (Max 1 and King II ) and sends data to Home Assistant, which also updates a local database,   and from where a Grafana dashboard can be viewed for both inverters. 

He also had an initial problem communicating with the newer model King II , with no replies received, but in the end it was a coding error on the ESP which didn't know how to interpret the responses that came in back from the newer King II which differed from the earlier model King I responses.

 

  • Author

@Ar135 

1. I can only assume your Deye is supplying the RS485 board which has a working voltage of 5v. I have tested with a meter and my inverter supplies just under 4v from the RS485 port and when connected to the A and B on the board it drops down to around 1.2v hence the dim flashing on the RS485 module. 

2. When I plug the red in as well either 5v or 3.3v it really lights up and stays solid. 

3. There seems to be no consistency with a setup as for some people it works with only 2 cables and some works with 4, some without power and some with. I have read some people removed the GND and it started working!!

I end up spending hours a day trying different combinations of pinouts and cabling and always the same results. The only thing that changes is the colour and thread count of my hair.

Maybe someone can post an example of what the working logs in ESPHome look like?

Quick Spec

  • Onboard MAX485 chip provides a low power consumption for RS-485 communication.
  • Onboard 5.08 (mm) pitch 2P terminals, to facilitate the RS-485 communication wiring.
  • All of the pins have been led by the MCU control operations
  • Working voltage: 5V
  • Board size: 44 x14mm
 

@Ar135 

1. I can only assume your Deye is supplying the RS485 board which has a working voltage of 5v. I have tested with a meter and my inverter supplies just under 4v from the RS485 port and when connected to the A and B on the board it drops down to around 1.2v hence the dim flashing on the RS485 module. 

2. When I plug the red in as well either 5v or 3.3v it really lights up and stays solid. 

3. There seems to be no consistency with a setup as for some people it works with only 2 cables and some works with 4, some without power and some with. I have read some people removed the GND and it started working!!

I end up spending hours a day trying different combinations of pinouts and cabling and always the same results. The only thing that changes is the colour and thread count of my hair.

Maybe someone can post an example of what the working logs in ESPHome look like?

Quick Spec

  • Onboard MAX485 chip provides a low power consumption for RS-485 communication.
  • Onboard 5.08 (mm) pitch 2P terminals, to facilitate the RS-485 communication wiring.
  • All of the pins have been led by the MCU control operations
  • Working voltage: 5V
  • Board size: 44 x14mm

May be a silly suggestion but I recall when I tried to get this to work, I mixed up the pairs on the ethernet cable (Type B Config) going to the RS485 to TTL converter - switched these over and the same modbus error disappeared and it started working. I removed the R7 resistor and doubled up the ethernet pairs as seen below.

Here's a pic of a ESP32 Dev board that I made for a colleague - powered using a cellphone charger into the micro USB port

WhatsAppImage2023-06-19at19_42_34.thumb.jpeg.65a40b1a16b1d59b975e12224ece4952.jpegWhatsAppImage2023-06-19at23_00_22.thumb.jpeg.150999f523c6e8d6151d602aff97e683.jpeg

If I recall correctly, the brown jumper is power 5V from the ESP32 and the white jumper is ground (ran out of red and black jumpers). Used a wago type connector to bridge the DE & RE pins on the RS485 converter.

And here's my code courtesy of @slipx

esphome:
  name: sunsynk

substitutions:
  settings_skipped_updates: "30"

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:
    baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: 

ota:
  password: 

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  fast_connect: true
  manual_ip:
    static_ip: 192.168.0.135
    gateway: 192.168.1.1
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Sunsynk Fallback Hotspot"
    password: "W88biQV6RGjF"

captive_portal:

# Enable time component to reset energy at midnight
# https://esphome.io/components/time.html#home-assistant-time-source
time:
  - platform: homeassistant
    id: homeassistant_time
     
uart:
 id: mod_bus
 tx_pin: 17
 rx_pin: 16
 baud_rate: 9600
 stop_bits: 1
 
modbus:
 id: sunsynk_modbus
 flow_control_pin: 4
 
modbus_controller:
 - id: sunsynk
   address: 0x01
   modbus_id: sunsynk_modbus
   setup_priority: -10
   update_interval: "15s"
   command_throttle: "50ms"

############################################### BINARY SENSORS ###############################################

binary_sensor:           
  - platform: modbus_controller            # 194 Grid Connected Status
    modbus_controller_id: sunsynk
    name: "Grid Connected Status"
    id: grid_connected_status
    register_type: holding
    address: 194

############################################### SENSORS ###############################################
sensor:
  - platform: modbus_controller            # 013 Firmware Control Board
    modbus_controller_id: sunsynk
    name: "Firmware Control Board"
    id: sunsynk_esphome_firmware_control_board
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 13

  - platform: modbus_controller            # 014 Firmware Comms Board
    modbus_controller_id: sunsynk
    name: "Firmware Comms Board"
    id: sunsynk_esphome_firmware_comms_board
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 14

  - platform: modbus_controller            # 070 Battery Charge Day
    modbus_controller_id: sunsynk
    name: "Battery Charge Day"
    id: sunsynk_esphome_battery_charge_day
    register_type: holding
    address: 70
    unit_of_measurement: "kWh"
    accuracy_decimals: 1
    device_class: energy
    state_class: total_increasing
    filters: #GOOD
      - lambda: |-
            x = x / 10;
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
  - platform: modbus_controller            # 071 Battery Discharge Day
    modbus_controller_id: sunsynk
    name: "Battery Discharge Day"
    id: sunsynk_esphome_battery_discharge_day
    register_type: holding
    address: 71
    unit_of_measurement: "kWh"
    accuracy_decimals: 1
    device_class: energy
    state_class: total_increasing
    filters: #GOOD
      - lambda: |-
            x = x / 10;
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
  - platform: modbus_controller            # 072 Battery Charge Energy Total
    modbus_controller_id: sunsynk
    name: "Total Battery Charge (kWh)"
    id: total_battery_charge_kwh
    register_type: holding
    address: 72
    unit_of_measurement: "kWh"
    accuracy_decimals: 1
    device_class: energy
    state_class: total_increasing
    value_type: U_DWORD_R
    filters:
     - multiply: 0.1


  - platform: modbus_controller            # 074 Battery Discharge Energy Total
    modbus_controller_id: sunsynk
    name: "Total Battery Discharge (kWh)"
    id: total_battery_discharge_kwh
    register_type: holding
    address: 74
    unit_of_measurement: "kWh"
    accuracy_decimals: 0
    device_class: energy
    state_class: total_increasing
    value_type: U_DWORD_R
    filters:
     - multiply: 0.1

  - platform: modbus_controller            # 076 Grid Import Day (Buy)
    modbus_controller_id: sunsynk
    name: "Grid Import Day (Buy)"
    id: sunsynk_esphome_grid_import_day
    register_type: holding
    address: 76
    unit_of_measurement: "kWh"
    accuracy_decimals: 1
    device_class: energy
    state_class: total_increasing
    filters: # GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) / 10;
            else return x /10;
  - platform: modbus_controller            # 078 Grid Import Energy Total (Buy)
    modbus_controller_id: sunsynk
    name: "Total Grid Import (kWh)"
    id: total_grid_import_kwh
    register_type: holding
    address: 78
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.1

  - platform: modbus_controller            # 079 Grid Frequency
    modbus_controller_id: sunsynk
    name: "Grid Frequency"
    id: sunsynk_esphome_grid_frequency
    register_type: holding
    address: 79
    unit_of_measurement: "hz"
    accuracy_decimals: 2
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /100;
            else return (x) /100;
    #device_class: none
    state_class: measurement


  - platform: modbus_controller            # 081 Grid Export Energy Total (Sell)
    modbus_controller_id: sunsynk
    name: "Total Grid Export (kWh)"
    id: total_grid_export_kwh
    register_type: holding
    address: 81
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    device_class: energy
    state_class: total_increasing
    filters:
      - lambda: |-
            if (x > 32767) return (x - 65535) / 10;
            else return x /10;
  - platform: modbus_controller            # 084 Daily Load
    modbus_controller_id: sunsynk
    name: "Daily Load Power (kWh)"
    id: daily_load_power_kwh
    register_type: holding
    address: 84
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.1

  - platform: modbus_controller            # 085 Total Load
    modbus_controller_id: sunsynk
    name: "Total Load Power (kWh)"
    id: total_load_power_kwh
    register_type: holding
    address: 85
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    device_class: energy
    state_class: total_increasing
    value_type: U_DWORD_R
    filters:
      - multiply: 0.1

  - platform: modbus_controller            # 090 DC Transformer Temperature
    modbus_controller_id: sunsynk
    name: "SS DC Transformer Temperature"
    id: sunsynk_esphome_dctransformer_temperature
    register_type: holding
    address: 090
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement
    filters: # GOOD
      - lambda: |-
            if (x > 32767) return ((x - 65535)-1000) / 10;
            else return ((x)-1000) / 10;
  - platform: modbus_controller            # 091 Radiator Temperature
    modbus_controller_id: sunsynk
    name: "SS DC Radiator Temperature"
    id: sunsynk_esphome_radiator_temperature
    register_type: holding
    address: 091
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement
    filters: # GOOD
      - lambda: |-
            if (x > 32767) return ((x - 65535)-1000) / 10;
            else return ((x)-1000) / 10;
  - platform: modbus_controller            # 096 PV Energy Total
    modbus_controller_id: sunsynk
    name: "Total PV Power (kWh)"
    id: total_pv_power_kwh
    register_type: holding
    address: 96
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.1


  - platform: modbus_controller            # 108 Day PV Power
    modbus_controller_id: sunsynk
    name: "Daily PV Power (kWh)"
    id: daily_pv_power_kwh
    register_type: holding
    address: 108
    unit_of_measurement: "kWh"
    accuracy_decimals: 1
    device_class: energy
    state_class: total_increasing
    filters:
      - multiply: 0.1


  - platform: modbus_controller            # 109 DC1 Voltage
    modbus_controller_id: sunsynk
    name: "DC1 Voltage"
    id: sunsynk_esphome_dc1_voltage
    register_type: holding
    address: 109
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    filters:
      - multiply: 0.1

  - platform: modbus_controller            # 111 DC2 Voltage
    modbus_controller_id: sunsynk
    name: "DC2 Voltage"
    id: sunsynk_esphome_dc2_voltage
    register_type: holding
    address: 111
    unit_of_measurement: "V"
    filters:
      - multiply: 0.1
    device_class: voltage
    state_class: measurement

  - platform: modbus_controller            # 110 DC1 Output Current
    modbus_controller_id: sunsynk
    name: "DC1 Current"
    id: sunsynk_esphome_dc1_current
    register_type: holding
    address: 110
    unit_of_measurement: "A"
    accuracy_decimals: 1
    device_class: current
    state_class: measurement
    filters:
      - multiply: 0.1

  - platform: modbus_controller            # 112 DC2 Output Current
    modbus_controller_id: sunsynk
    name: "DC2 Current"
    id: sunsynk_esphome_dc2_current
    register_type: holding
    address: 112
    unit_of_measurement: "A"
    accuracy_decimals: 1
    device_class: current
    state_class: measurement
    filters:
      - multiply: 0.1

  - platform: modbus_controller            # 154 Grid Inverter Voltage
    modbus_controller_id: sunsynk
    name: "Grid Inverter Voltage"
    id: sunsynk_esphome_grid_inverter_voltage
    register_type: holding
    address: 154
    unit_of_measurement: "V"
    accuracy_decimals: 1
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /10;
            else return (x) /10;
    device_class: voltage
    state_class: measurement

  - platform: modbus_controller            # 164 Inverter Output Current
    modbus_controller_id: sunsynk
    name: "Inverter Output Current"
    id: sunsynk_esphome_inverter_output_current
    register_type: holding
    address: 164
    unit_of_measurement: "A"
    accuracy_decimals: 1
    device_class: current
    state_class: measurement
    value_type: S_WORD
    filters:
      - multiply: 0.01

  - platform: modbus_controller            # 166 Aux Output Power
    modbus_controller_id: sunsynk
    name: "Aux Output Power"
    id: sunsynk_esphome_aux_output_power
    register_type: holding
    address: 166
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
  - platform: modbus_controller             # 169 (167+168) Grid Power
    modbus_controller_id: sunsynk
    name: "Grid Power"
    id: grid_power
    register_type: holding
    address: 169
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    #value_type: S_WORD
    filters: #GOOD
      - lambda: |-
              float MIN_VALUE = -10000.0;
              float MAX_VALUE = 10000.0;
              if (MIN_VALUE <= x && x <= MAX_VALUE) return x;
              else return {};
  - platform: modbus_controller            # 172 Grid External Power
    modbus_controller_id: sunsynk
    name: "Grid External Power"
    id: grid_external_power
    register_type: holding
    address: 172
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    #value_type: S_WORD
    filters: #GOOD
      - lambda: |-
              float MIN_VALUE = -10000.0;
              float MAX_VALUE = 10000.0;
              if (MIN_VALUE <= x && x <= MAX_VALUE) return x;
              else return {};
  - platform: modbus_controller            # 175 Inverter Output Power
    modbus_controller_id: sunsynk
    name: "Inverter Output Power"
    id: sunsynk_esphome_inverter_output_power
    register_type: holding
    address: 175
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    value_type: S_WORD
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (0 - x + 65535) /-1;
            else return (0 - x) /-1;
  - platform: modbus_controller            # 176 Load Power
    modbus_controller_id: sunsynk
    name: "Load Power 176"
    id: ss_load_power_176
    register_type: holding
    address: 176
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    value_type: S_WORD
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65536) /1;
            else return (x) /1;
  - platform: modbus_controller            # 177 Load Power
    modbus_controller_id: sunsynk
    name: "Load Power 177"
    id: ss_load_power_177
    register_type: holding
    address: 177
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    value_type: S_WORD
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65536) /1;
            else return (x) /1;
  - platform: modbus_controller            # 178 Load Power
    modbus_controller_id: sunsynk
    name: "Load Power"
    id: load_power
    register_type: holding
    address: 178
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    value_type: S_WORD
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65536) /1;
            else return (x) /1;
  
  - platform: modbus_controller            # 182 Battery Temperature
    modbus_controller_id: sunsynk
    name: "SS Battery Temperature"
    id: sunsynk_esphome_battery_temperature
    register_type: holding
    address: 182
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement
    filters: # GOOD
      - lambda: |-
            if (x > 32767) return ((x - 65535)-1000) / 10;
            else return ((x)-1000) / 10;
  - platform: modbus_controller            # 183 Battery Voltage
    modbus_controller_id: sunsynk
    name: "Battery Voltage"
    id: sunsynk_esphome_battery_voltage
    register_type: holding
    address: 183
    unit_of_measurement: "V"
    accuracy_decimals: 1
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) / 100;
            else return x / 100;
    device_class: voltage
    state_class: measurement

  - platform: modbus_controller            # 184 Battery SOC
    modbus_controller_id: sunsynk
    name: "Battery SOC"
    id: battery_soc
    register_type: holding
    address: 184
    unit_of_measurement: "%"
    accuracy_decimals: 0
    device_class: battery
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
  - platform: modbus_controller            # 186 PV1 Power
    modbus_controller_id: sunsynk
    name: "PV1 Power"
    id: pv1_power
    register_type: holding
    address: 186
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    
  - platform: modbus_controller            # 187 PV2 Power
    modbus_controller_id: sunsynk
    name: "PV2 Power"
    id: pv2_power
    register_type: holding
    address: 187
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement

  - platform: template                   # Sum of PV1 and PV2 to get total PV Power
    name: "SS Total Solar"
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    state_class: measurement
    lambda: |-
      return (id(pv1_power).state + id(pv2_power).state);
    update_interval: 5s

  - platform: modbus_controller            # 190 Battery Output Power
    modbus_controller_id: sunsynk
    name: "Battery Output Power"
    id: sunsynk_esphome_battery_output_power
    register_type: holding
    address: 190
    unit_of_measurement: "W"
    accuracy_decimals: 0
    device_class: power
    value_type: S_WORD
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65536) /1;
            else return (x) /1;
  - platform: modbus_controller            # 191 Battery Output Current
    modbus_controller_id: sunsynk
    name: "Battery Output Current"
    id: sunsynk_esphome_battery_output_current
    register_type: holding
    address: 191
    unit_of_measurement: "A"
    accuracy_decimals: 1
    device_class: current
    state_class: measurement
    value_type: S_WORD
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65536) / 100;
            else return x / 100;
  - platform: modbus_controller            # 192 Load Frequency
    modbus_controller_id: sunsynk
    name: "Load Frequency"
    id: sunsynk_esphome_load_frequency
    register_type: holding
    address: 192
    unit_of_measurement: "hz"
    accuracy_decimals: 2
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /100;
            else return (x) /100;
    #device_class: none
    state_class: measurement

  - platform: modbus_controller            # 216 Battery Charging Efficiency
    modbus_controller_id: sunsynk
    name: "Battery Charging Efficiency"
    id: battery_charging_efficiency
    register_type: holding
    address: 216
    unit_of_measurement: "%"
    accuracy_decimals: 1
    device_class: battery
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /10;
            else return (x) /10;
  - platform: modbus_controller            # 217 Battery Capacity Shutdown
    modbus_controller_id: sunsynk
    name: "Battery Capacity Shutdown"
    id: sunsynk_battery_capacity_shutdown
    register_type: holding
    address: 217
    unit_of_measurement: "%"
    accuracy_decimals: 0
    device_class: battery


################################################ READ SETTINGS ################################################
  - platform: modbus_controller          # 250 Settings Timezone1
    modbus_controller_id: sunsynk
    name: "Setting Timezone1"
    id: sunsynk_esphome_setting_timezone1
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 250
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
    icon: "mdi:clock"

  - platform: modbus_controller          # 251 Settings Timezone2
    modbus_controller_id: sunsynk
    name: "Setting Timezone2"
    id: sunsynk_esphome_setting_timezone2
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 251   
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
    icon: "mdi:clock"


  - platform: modbus_controller          # 252 Settings Timezone3
    modbus_controller_id: sunsynk
    name: "Setting Timezone3"
    id: sunsynk_esphome_setting_timezone3
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 252
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
    icon: "mdi:clock"

  - platform: modbus_controller          # 253 Settings Timezone4
    modbus_controller_id: sunsynk
    name: "Setting Timezone4"
    id: sunsynk_esphome_setting_timezone4
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 253
    icon: "mdi:clock"

  - platform: modbus_controller          # 254 Settings Timezone5
    modbus_controller_id: sunsynk
    name: "Setting Timezone5"
    id: sunsynk_esphome_setting_timezone5
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 254
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
    icon: "mdi:clock"

  - platform: modbus_controller          # 255 Settings Timezone6
    modbus_controller_id: sunsynk
    name: "Setting Timezone6"
    id: sunsynk_esphome_setting_timezone6
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 255
    filters: #GOOD
      - lambda: |-
            if (x > 32767) return (x - 65535) /1;
            else return (x) /1;
    icon: "mdi:clock"


  - platform: modbus_controller          # 268 Settings SoC Timezone1
    modbus_controller_id: sunsynk
    name: "Setting SoC Timezone1"
    id: sunsynk_esphome_setting_soc_timezone1
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 268
    value_type: U_WORD

  - platform: modbus_controller          # 269 Settings SoC Timezone2
    modbus_controller_id: sunsynk
    name: "Setting SoC Timezone2"
    id: sunsynk_esphome_setting_soc_timezone2
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 269
    value_type: U_WORD

  - platform: modbus_controller          # 270 Settings SoC Timezone3
    modbus_controller_id: sunsynk
    name: "Setting SoC Timezone3"
    id: sunsynk_esphome_setting_soc_timezone3
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 270
    value_type: U_WORD

  - platform: modbus_controller          # 271 Settings SoC Timezone4
    modbus_controller_id: sunsynk
    name: "Setting SoC Timezone4"
    id: sunsynk_esphome_setting_soc_timezone4
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 271
    value_type: U_WORD

  - platform: modbus_controller          # 272 Settings SoC Timezone5
    modbus_controller_id: sunsynk
    name: "Setting SoC Timezone5"
    id: sunsynk_esphome_setting_soc_timezone5
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 272
    value_type: U_WORD

  - platform: modbus_controller          # 273 Settings SoC Timezone6
    modbus_controller_id: sunsynk
    name: "Setting SoC Timezone6"
    id: sunsynk_esphome_setting_soc_timezone6
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 273
    value_type: U_WORD

  - platform: modbus_controller          # 274 Settings Grid Charge Timezone1
    modbus_controller_id: sunsynk
    name: "Setting Grid Charge Timezone1"
    id: sunsynk_esphome_setting_grid_charge_timezone1
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 274

  - platform: modbus_controller          # 275 Settings Grid Charge Timezone2
    modbus_controller_id: sunsynk
    name: "Setting Grid Charge Timezone2"
    id: sunsynk_esphome_setting_grid_charge_timezone2
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 275
    
  - platform: modbus_controller          # 276 Settings Grid Charge Timezone3
    modbus_controller_id: sunsynk
    name: "Setting Grid Charge Timezone3"
    id: sunsynk_esphome_setting_grid_charge_timezone3
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 276
    
  - platform: modbus_controller          # 277 Settings Grid Charge Timezone4
    modbus_controller_id: sunsynk
    name: "Setting Grid Charge Timezone4"
    id: sunsynk_esphome_setting_grid_charge_timezone4
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 277
    
  - platform: modbus_controller          # 278 Settings Grid Charge Timezone5
    modbus_controller_id: sunsynk
    name: "Setting Grid Charge Timezone5"
    id: sunsynk_esphome_setting_grid_charge_timezone5
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 278
    
  - platform: modbus_controller          # 279 Settings Grid Charge Timezone6
    modbus_controller_id: sunsynk
    name: "Setting Grid Charge Timezone6"
    id: sunsynk_esphome_setting_grid_charge_timezone6
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    address: 279

################################################ WRITE SETTINGS ################################################

switch:
  - platform: modbus_controller          # 248 Toggle System Timer
    use_write_multiple: true
    modbus_controller_id: sunsynk
    name: "Toggle System Timer" 
    id: sunsynk_esphome_toggle_Time_of_Use
    register_type: holding
    address: 248
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 243 Priority Load
    use_write_multiple: true
    modbus_controller_id: sunsynk
    name: "Toggle Priority Load" 
    id: sunsynk_esphome_toggle_priority_load
    register_type: holding
    address: 243
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 274 Toggle Grid Charge Timezone1
    use_write_multiple: true
    modbus_controller_id: sunsynk
    name: "Toggle Grid Charge Timezone1"
    id: sunsynk_esphome_toggle_grid_charge_timezone1
    register_type: holding
    address: 274
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 275 Toggle Grid Charge Timezone2
    modbus_controller_id: sunsynk
    use_write_multiple: true
    name: "Toggle Grid Charge Timezone2"
    id: sunsynk_esphome_toggle_grid_charge_timezone2
    register_type: holding
    address: 275
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 276 Toggle Grid Charge Timezone3
    modbus_controller_id: sunsynk
    use_write_multiple: true
    name: "Toggle Grid Charge Timezone3"
    id: sunsynk_esphome_toggle_grid_charge_timezone3
    register_type: holding
    address: 276
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 277 Toggle Grid Charge Timezone4
    modbus_controller_id: sunsynk
    use_write_multiple: true
    name: "Toggle Grid Charge Timezone4"
    id: sunsynk_esphome_toggle_grid_charge_timezone4
    register_type: holding
    address: 277
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 278 Toggle Grid Charge Timezone5
    modbus_controller_id: sunsynk
    use_write_multiple: true
    name: "Toggle Grid Charge Timezone5"
    id: sunsynk_esphome_toggle_grid_charge_timezone5
    register_type: holding
    address: 278
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

  - platform: modbus_controller          # 279 Toggle Grid Charge Timezone6
    modbus_controller_id: sunsynk
    use_write_multiple: true
    name: "Toggle Grid Charge Timezone6"
    id: sunsynk_esphome_toggle_grid_charge_timezone6
    register_type: holding
    address: 279
    bitmask: 1
    entity_category: config
    icon: "mdi:toggle-switch"

number:
  - platform: modbus_controller         # 268 Settings SoC Timezone1
    use_write_multiple: true
    modbus_controller_id: sunsynk
    id: sunsynk_esphome_set_soc_timezone1
    name: "Set SoC Timezone1"
    unit_of_measurement: "%"
    address: 268
    min_value: 0
    max_value: 100
    step: 5
    value_type: U_WORD  

  - platform: modbus_controller         # 269 Settings SoC Timezone2
    use_write_multiple: true
    modbus_controller_id: sunsynk
    id: sunsynk_esphome_set_soc_timezone2
    name: "Set SoC Timezone2"
    unit_of_measurement: "%"
    address: 269
    min_value: 0
    max_value: 100
    step: 5
    value_type: U_WORD  

  - platform: modbus_controller         # 270 Settings SoC Timezone3
    use_write_multiple: true
    modbus_controller_id: sunsynk
    id: sunsynk_esphome_set_soc_timezone3
    name: "Set SoC Timezone3"
    unit_of_measurement: "%"
    address: 270
    min_value: 0
    max_value: 100
    step: 5
    value_type: U_WORD  

  - platform: modbus_controller         # 271 Settings SoC Timezone4
    use_write_multiple: true
    modbus_controller_id: sunsynk
    id: sunsynk_esphome_set_soc_timezone4
    name: "Set SoC Timezone4"
    unit_of_measurement: "%"
    address: 271
    min_value: 0
    max_value: 100
    step: 5
    value_type: U_WORD  

  - platform: modbus_controller         # 272 Settings SoC Timezone5
    use_write_multiple: true
    modbus_controller_id: sunsynk
    id: sunsynk_esphome_set_soc_timezone5
    name: "Set SoC Timezone5"
    unit_of_measurement: "%"
    address: 272
    min_value: 0
    max_value: 100
    step: 5
    value_type: U_WORD  

  - platform: modbus_controller         # 273 Settings SoC Timezone6
    use_write_multiple: true
    modbus_controller_id: sunsynk
    id: sunsynk_esphome_set_soc_timezone6
    name: "Set SoC Timezone6"
    unit_of_measurement: "%"
    address: 273
    min_value: 0
    max_value: 100
    step: 5
    value_type: U_WORD  

################################################ TEMPLATE SENSORS ################################################

text_sensor:
  - platform: modbus_controller            # 059 Overall State
    modbus_controller_id: sunsynk
    name: "Overall State"
    id: sunsynk_overall_state
    register_type: holding
    skip_updates: ${settings_skipped_updates}
    raw_encode: HEXBYTES
    address: 59
    lambda: |- 
      uint16_t value = modbus_controller::word_from_hex_str(x, 0);
      switch (value) {
        case 0: return std::string("standby");
        case 1: return std::string("selftest");
        case 2: return std::string("normal");
        case 3: return std::string("alarm");
        case 4: return std::string("fault");
        default: return std::string("unknown");
      }
  - platform: template
    name: "Sunsynk Time Slot 1"
    id: sunsynk_time_slot_1
    lambda: |-
        int minutes, hours;
        if (id(sunsynk_esphome_setting_timezone1).state) {
        minutes = static_cast<int>(id(sunsynk_esphome_setting_timezone1).state) % 100;
        hours = static_cast<int>(id(sunsynk_esphome_setting_timezone1).state) / 100;
        } else {
          minutes = 0;
          hours = 0;
        }
        char formatted_time[6];
        snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d", hours, minutes);
        return esphome::optional<std::string>(formatted_time);
  - platform: template
    name: "Sunsynk Time Slot 2"
    id: sunsynk_time_slot_2
    lambda: |-
        int minutes, hours;
        if (id(sunsynk_esphome_setting_timezone2).state) {
        minutes = static_cast<int>(id(sunsynk_esphome_setting_timezone2).state) % 100;
        hours = static_cast<int>(id(sunsynk_esphome_setting_timezone2).state) / 100;
        } else {
          minutes = 0;
          hours = 0;
        }
        char formatted_time[6];
        snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d", hours, minutes);
        return esphome::optional<std::string>(formatted_time);
  - platform: template
    name: "Sunsynk Time Slot 3"
    id: sunsynk_time_slot_3
    lambda: |-
        int minutes, hours;
        if (id(sunsynk_esphome_setting_timezone3).state) {
        minutes = static_cast<int>(id(sunsynk_esphome_setting_timezone3).state) % 100;
        hours = static_cast<int>(id(sunsynk_esphome_setting_timezone3).state) / 100;
        } else {
          minutes = 0;
          hours = 0;
        }
        char formatted_time[6];
        snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d", hours, minutes);
        return esphome::optional<std::string>(formatted_time);
  - platform: template
    name: "Sunsynk Time Slot 4"
    id: sunsynk_time_slot_4
    lambda: |-
        int minutes, hours;
        if (id(sunsynk_esphome_setting_timezone4).state) {
        minutes = static_cast<int>(id(sunsynk_esphome_setting_timezone4).state) % 100;
        hours = static_cast<int>(id(sunsynk_esphome_setting_timezone4).state) / 100;
        } else {
          minutes = 0;
          hours = 0;
        }
        char formatted_time[6];
        snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d", hours, minutes);
        return esphome::optional<std::string>(formatted_time);
  - platform: template
    name: "Sunsynk Time Slot 5"
    id: sunsynk_time_slot_5
    lambda: |-
        int minutes, hours;
        if (id(sunsynk_esphome_setting_timezone5).state) {
        minutes = static_cast<int>(id(sunsynk_esphome_setting_timezone5).state) % 100;
        hours = static_cast<int>(id(sunsynk_esphome_setting_timezone5).state) / 100;
        } else {
          minutes = 0;
          hours = 0;
        }
        char formatted_time[6];
        snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d", hours, minutes);
        return esphome::optional<std::string>(formatted_time);
  - platform: template
    name: "Sunsynk Time Slot 6"
    id: sunsynk_time_slot_6
    lambda: |-
        int minutes, hours;
        if (id(sunsynk_esphome_setting_timezone6).state) {
        minutes = static_cast<int>(id(sunsynk_esphome_setting_timezone6).state) % 100;
        hours = static_cast<int>(id(sunsynk_esphome_setting_timezone6).state) / 100;
        } else {
          minutes = 0;
          hours = 0;
        }
        char formatted_time[6];
        snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d", hours, minutes);
        return esphome::optional<std::string>(formatted_time);
  - platform: template
    name: "Sunsynk Battery Capacity"
    lambda: |-
      if (!id(grid_connected_status).state) {
        float value = id(sunsynk_battery_capacity_shutdown).state;
        char buffer[10];
        dtostrf(value, 6, 0, buffer);
        return std::string(buffer);
      } else {
               
        // Get the current date and time
        time_t now = id(homeassistant_time).now().timestamp;
        tm* currentTime = localtime(&now);
        std::string timeSlot1 = id(sunsynk_time_slot_1).state;
        std::string timeSlot2 = id(sunsynk_time_slot_2).state;
        std::string timeSlot3 = id(sunsynk_time_slot_3).state;
        std::string timeSlot4 = id(sunsynk_time_slot_4).state;
        std::string timeSlot5 = id(sunsynk_time_slot_5).state;
        std::string timeSlot6 = id(sunsynk_time_slot_6).state;
        int hour, minute;
        // Convert timeSlot1 to sellTime1Epoch
        sscanf(timeSlot1.c_str(), "%d:%d", &hour, &minute);
        currentTime->tm_hour = hour;
        currentTime->tm_min = minute;
        currentTime->tm_sec = 0;
        time_t sellTime1Epoch = mktime(currentTime);
        // ESP_LOGD("DEBUG", "sellTime1Epoch: %ld, now: %ld", sellTime1Epoch, now);
        // Convert timeSlot2 to sellTime2Epoch
        sscanf(timeSlot2.c_str(), "%d:%d", &hour, &minute);
        currentTime->tm_hour = hour;
        currentTime->tm_min = minute;
        currentTime->tm_sec = 0;
        time_t sellTime2Epoch = mktime(currentTime);
        // ESP_LOGD("DEBUG", "sellTime2Epoch: %ld, now: %ld", sellTime2Epoch, now);
        // Convert timeSlot3 to sellTime3Epoch
        sscanf(timeSlot3.c_str(), "%d:%d", &hour, &minute);
        currentTime->tm_hour = hour;
        currentTime->tm_min = minute;
        currentTime->tm_sec = 0;
        time_t sellTime3Epoch = mktime(currentTime);
        // Convert timeSlot4 to sellTime4Epoch
        sscanf(timeSlot4.c_str(), "%d:%d", &hour, &minute);
        currentTime->tm_hour = hour;
        currentTime->tm_min = minute;
        currentTime->tm_sec = 0;
        time_t sellTime4Epoch = mktime(currentTime);
        // Convert timeSlot5 to sellTime5Epoch
        sscanf(timeSlot5.c_str(), "%d:%d", &hour, &minute);
        currentTime->tm_hour = hour;
        currentTime->tm_min = minute;
        currentTime->tm_sec = 0;
        time_t sellTime5Epoch = mktime(currentTime);
        // Convert timeSlot6 to sellTime6Epoch
        sscanf(timeSlot6.c_str(), "%d:%d", &hour, &minute);
        currentTime->tm_hour = hour;
        currentTime->tm_min = minute;
        currentTime->tm_sec = 0;
        time_t sellTime6Epoch = mktime(currentTime);
        if (now >= sellTime1Epoch && now < sellTime2Epoch)  {
          float value = static_cast<float>(id(sunsynk_esphome_set_soc_timezone1).state);
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
        } else if (now >= sellTime2Epoch && now < sellTime3Epoch) {
          float value = static_cast<float>(id(sunsynk_esphome_set_soc_timezone2).state);
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
        } else if (now >= sellTime3Epoch && now < sellTime4Epoch) {
          float value = static_cast<float>(id(sunsynk_esphome_set_soc_timezone3).state);
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
        } else if (now >= sellTime4Epoch && now < sellTime5Epoch) {
          float value = static_cast<float>(id(sunsynk_esphome_set_soc_timezone4).state);
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
        } else if (now >= sellTime5Epoch && now < sellTime6Epoch) {
          float value = static_cast<float>(id(sunsynk_esphome_set_soc_timezone5).state);
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
        } else if (now >= sellTime6Epoch && now < sellTime1Epoch) {
          float value = static_cast<float>(id(sunsynk_esphome_set_soc_timezone6).state);
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
        } else {
          float value = id(sunsynk_battery_capacity_shutdown).state;
          char buffer[10];
          dtostrf(value, 6, 0, buffer);
          return std::string(buffer);
          }
      }

    

 

Edited by Muttley
added info

I was experiencing the same issues as most of you on this topic. It just wouldn't work. Then I did an upgrade of the Firmware. After this, it magically came right. I notice that most of the wirings show that the two RS485 lines from the RJ45 connector connected together. This is not necessary. If there are actually two RS485 ports, then you are sending and receiving from both at the same time. It will probably work, but you will most likely get read errors when the timing of these two ports is a bit different. Note also that for the ESP32 you have to bring the 5V down to 3.3 for the RX. This can be achieved with a 200Ohm Resistor and a 3.3v Zener.

To update the firmware, you have to log a ticket with Synsynk. I was surprised that they did it within a hour of me posting the ticket on a Saturday. So be ready for the Inverter to reboot.

 

  • 6 months later...

Hi all.

 

I'm in need of some opinions. I when through all the forums, did the setup on me ESP32, using Max485 and a Deye 8k. My setup looks similar to 

I also removed R7 since it messed with the comms. I added the 200Ohm resistor and 3.3v zener to drop the Rx voltage to 3.3 range for the ESP32 (as the Max485 module does 5v). I also used pin 7&8 on Rj45 (since the Deye manual shows RS485 to be on 7 & 8). I get comms, values coming through for abour 5 min, the the values becomes bigger than the expected ranges. Then a few cycles later they are as expected. Below is a graph of the frequency, which should stay around 50Hz and not 300Hz... This is just one of the signals that does this (my batt SOC sometimes goes to -2000%, etc)

image.png.7ce597c13e3d5f54aa4247c376938981.png

 

I also get this in between on the logs:

image.thumb.png.6962d3393188f54aa5a93d81864933c2.png

 

Any suggestions on what to look for?

 

Edited by BugsRSA

5 hours ago, BugsRSA said:

Hi all.

 

I'm in need of some opinions. I when through all the forums, did the setup on me ESP32, using Max485 and a Deye 8k. My setup looks similar to 

I also removed R7 since it messed with the comms. I added the 200Ohm resistor and 3.3v zener to drop the Rx voltage to 3.3 range for the ESP32 (as the Max485 module does 5v). I also used pin 7&8 on Rj45 (since the Deye manual shows RS485 to be on 7 & 8). I get comms, values coming through for abour 5 min, the the values becomes bigger than the expected ranges. Then a few cycles later they are as expected. Below is a graph of the frequency, which should stay around 50Hz and not 300Hz... This is just one of the signals that does this (my batt SOC sometimes goes to -2000%, etc)

image.png.7ce597c13e3d5f54aa4247c376938981.png

 

I also get this in between on the logs:

image.thumb.png.6962d3393188f54aa5a93d81864933c2.png

 

Any suggestions on what to look for?

 

My suggestion @BugsRSAis to just buy one of the ESP32's with the RS485 Shield from smarthomeintegrations.co.za and load ESPHome onto it. 

Costs R438 and is money well spent IMO. 

No issues with soldering, has a 3.3v RS485 and you can power the whole thing from the 12V power in your inverter. 

https://smarthomeintegrations.co.za/product/smartdeyedonglev4-intl-shipment/

I posted a video on it some time ago and it just works 

 

 

 

@Sc00bs you mention in the video that you have a Deye 8kW and use pin1+2. In Deye manual, pin1+2 is marked as RS485+Meter_Com while pin 7+8 is marked as Rs485A+B. Will that make aa difference?

Note: If i can get an RS485 shield only, that would be great. 🙂

 

Haha. Also using a buck converter. But saw some didnt connect the +5v to the max485 pin, so didnt connect. I connected it now and that seemed to help. Also changed refresh rate to 10s but updated the throttle to 75ms. So far so good. Will monitor....

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.