kellerza / sunsynk

Deye/Sunsynk Inverter Python library and Home Assistant OS Addon
https://kellerza.github.io/sunsynk/
MIT License
209 stars 88 forks source link

Compatibility with Sunsynk 12kw 3-phase inverter? #63

Closed lubster85 closed 1 year ago

lubster85 commented 2 years ago

Hi there

I recently had a Sunsynk 12kw 3-phase inverter installed, but I'm a little unsure if this integration works with this model. I purchased a USB-RS485 cable from Solar-Assistant (https://solar-assistant.io/shop/products/sunsynk_rs485) and tried starting up the integration.

I've tried a few ports on the inverter with no success yet, but I was hoping to sense-check myself here as I don't recall the 3-phase inverter being included in the list of tested inverters.

IMG_1743

My understanding is that the "Meter-485" port could be used for monitoring and also the "BMS" port.

Referencing Solar Assistant, they claim there was a firmware change recently.

The inverter manufacturer released a firmware update which changed the port to read the inverter via RS485. An RJ45 splitter can be used to allow SolarAssistant to read the inverter while the inverter is also reading a battery via CAN.

Is there perhaps something else I may be missing or should try? If not, I'll try find a splitter and confirm if that makes a difference.

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] done.
[services.d] starting services
[services.d] done.
2022-09-24 08:45:31,191 INFO    Loading HASS OS configuration
2022-09-24 08:45:31,264 INFO    Filter *last used for battery_soc, total_battery_charge, total_battery_discharge, total_grid_export, total_grid_import, total_pv_power
2022-09-24 08:45:31,273 INFO    Protocol made connection.
2022-09-24 08:45:31,274 INFO    Connected to /dev/ttyUSB0
2022-09-24 08:45:41,286 ERROR   Timeout reading: 
2022-09-24 08:45:41,287 INFO    ############################################################
2022-09-24 08:45:41,287 INFO    No response on the Modbus interface, try checking the wiring to the Inverter, the USB-to-RS485 converter, etc
2022-09-24 08:45:41,287 INFO    ############################################################
2022-09-24 08:45:41,288 CRITICAL This Add-On will terminate in 30 seconds, use the Supervisor Watchdog to restart automatically.
[cmd] ./run.py exited 0
[cont-finish.d] executing container finish scripts...
[cont-finish.d] done.
[s6-finish] waiting for services.
[s6-finish] sending all processes the TERM signal.
duanemck commented 1 year ago

WSL (Windows Subsystem for Linux) is also great for running unix shell tools on Windows. https://learn.microsoft.com/en-us/windows/wsl/install

archi commented 1 year ago

I used brendanvz' register map to update some numbers in the definitions.py. Since my Deye 12k only has grid+modbus connected as of now, I can not really test this - but it's a first step. At least the numbers I saw are now more sane (read: 0). Maybe someone with some PV and a battery connected to the inverter wants to check+improve this ;-)

https://github.com/archi/sunsynk/blob/deye12k/sunsynk/definitions.py

n.b.: I know you wanted to put this into a file of its own, but for testing this was the easiest way ;-)

kababoom commented 1 year ago

@archi looks a lot like mine, I replaced mostly with same registers. it's a first step but not perfect, need more time and some debug options would be nice.

archi commented 1 year ago

@kababoom great to hear! is yours on github? Else, feel free to comment on my commit, or even open a PR to my fork.

Regarding debugging, the addon can be run locally:

  1. I checked out the repo on my Arch Linux machine
  2. symlinked the sunsynk folder into hass-addon-sunsynk-dev
  3. ran ./run.py in there and since that failed
  4. installed missing python packages (some from the official Arch Linux repos, some using pip an non-root) until the program started, but complained about missing parameters.
  5. Changed the example config.yaml (PORT, DEVICE, SUNSYNK_ID, SENSOR_PREFIX, MQTT_USERNAME)
  6. Run ./run.py my.mqtt.server.tld topsecretpassword and see what happens

The run.py will always expect a MQTT server and password on the command line when run that way, so that's why these are passed. It also sets debug to 1. You can change that in run.py at lines 226 to 228 (I didn't try, but will do so later).

Edit: Added link to my commit.

kababoom commented 1 year ago

@archi some version is on git but not latest (not enough time, hope this weekend).

Thank you for describing these steps, do you use ip or plug the usb in your dev machine?

archi commented 1 year ago

I use this Modbus Gateway. But USB should work as well, though I didn't try that.

kababoom commented 1 year ago

@archi Was able to debug with USB connected to my MBPro but have ordered the Wave tcp gateway anyway. Bit chilly in the garage...

Have added the system program settings and have tested the write functionality (simple time change), which seems to work just fine. I'm not sure about the 'Prog mode' options though, is that 1phase specific? or firmware specific, I'm still on C027 waiting for an update. Mine just got the general 'Time of use' checkbox and: Grid charge - Gen charge - Time from - Time to - Power - Voltage/Soc%

There are still some unknown registers and not yet translated ones, I have reused your comment: # 12k??

Todo: test and add the following as RW Export limit 143 Bat max charge 108 Bat max discharge 109 Use timer 146

Also noticed, although in several lists, anything in 200 range returns 0 from my inverter.

Here's a link to the definitions file, when I've sorted more I will send pull. https://github.com/kababoom/sunsynk/blob/main/sunsynk/definitions.py

Here's a list of the sensors and the one skipped:

- battery_soc
- battery_voltage
- battery_power
- battery_current
- inverter_power
- inverter_l1_power
- inverter_l2_power
- inverter_l3_power
- inverter_voltage
- inverter_frequency

- grid_frequency
- grid_power
- grid_l1_power
- grid_l2_power
- grid_l3_power
- grid_frequency
- grid_power
- grid_current
- grid_ct_power

- gen_power
- gen_l1_power
- gen_l2_power
- gen_l3_power

# - rated_power
- device_type
# - fault
# - overal_state
# - sd_states
- serial
- dc_transformer_temperature
- environment_temperature
# - radiator_temperature
# - grid_connected_status

# - control_mode
- grid_charge_battery_current
- grid_charge_enabled
# - battery_charging_voltage
- bat1_soc
# - bat1_cycle
# - battery_equalization_voltage
# - battery_absorption_voltage
# - battery_float_voltage
# - battery_shutdown_capacity
# - battery_restart_capacity
# - battery_low_capacity
# - battery_shutdown_voltage
# - battery_restart_voltage
# - battery_low_voltage

- priority_mode
- load_limit

- prog1_time
- prog2_time
- prog3_time
- prog4_time
- prog5_time
- prog6_time

- prog1_power
- prog2_power
- prog3_power
- prog4_power
- prog5_power
- prog6_power

- prog1_capacity
- prog2_capacity
- prog3_capacity
- prog4_capacity
- prog5_capacity
- prog6_capacity

- prog1_charge    
- prog2_charge    
- prog3_charge    
- prog4_charge    
- prog5_charge    
- prog6_charge    

# - prog1_mode
# - prog2_mode
# - prog3_mode
# - prog4_mode
# - prog5_mode
# - prog6_mode

- prog1_voltage
- prog2_voltage
- prog3_voltage
- prog4_voltage
- prog5_voltage
- prog6_voltage
archi commented 1 year ago

Hey, great :) I will screenshot my settings for the gateway - I found some of the stuff a bit counterintuitive. Since I only have the 3 phase inverter, I don't know. Maybe kellerza has an idea? I don't have a lot of time for testing right now (many more house improvements to be done, including getting the electrical work up to code), but once my battery arrives I'll try to see if can setup a small temporary solar array for offgrid testing. Though testing configuration parameters match the display might already be possible (I did not yet dare playing with that, read-only is safer and personally enough for me).

kababoom commented 1 year ago

Hmm prog mode is the combination of gen charge - grid charge..

kellerza commented 1 year ago

Hmm prog mode is the combination of gen charge - grid charge..

Yes, but if you define your own, you can also separate the using a bitmask=xx on the sensor definition

sebmueller commented 1 year ago

@sebmueller I did import on a new flow and got 'gate' and 'cycle' not found hence could not deploy and assumed it was non-ha version.

@kababoom : You have to install the add ons for gate and cycle in HA.

image image

archi commented 1 year ago

Ah, @kababoom nice work on the PR :) Looking forward to test it.

Regarding the Waveshare: Keep in mind the non-PoE variant is lacking any isolation, while the PoE variant is isolated both on the Ethernet port and on RS485. The think the chance of the inverter unloading into the modbus is pretty slim, but in case of a lightning strike I didn't want to take any chances (plus, I have PoE anyway).

I can also report the configuration software runs well on my Linux machine (using wine). I did not test the automatic scan (the gateway has its own subnet and now strictly firewalled), but manually adding by IP worked well.

kababoom commented 1 year ago

@sebmueller I did import on a new flow and got 'gate' and 'cycle' not found hence could not deploy and assumed it was non-ha version.

@kababoom : You have to install the add ons for gate and cycle in HA.

image image

@sebmueller Thank you, packages could not be found but got it working by adding the packages to the config of nodered. Looks good..

yksxjan commented 1 year ago

Here is a ESP32-Deye project, if you look at the yaml file, it lists the 3P modbus registries in quite readable format, so might be useful to have a look

https://github.com/klatremis/esphome-for-deye

bruceborrett commented 1 year ago

Can anyone confirm how to use the definitions file added in #93? Do I have to create a local copy of the addon and rename definitions3ph.py to definitions.py? I tried doing exactly this and unfortunately it still tries to query the registers from the original definitions file, Im not where it is reading them from since I removed the original file.

kellerza commented 1 year ago

@bruceborrett you have to modify the addon’s Dockerfile.

There is a script called copy2local that does this and copies the files to the correct folder (modify for your target HASS IP/samba share. You will need msys to run it on windows (for sed)

bruceborrett commented 1 year ago

@kellerza Im running Linux and dont have any experience with Windows scripts, but will figure it out, thanks.

kellerza commented 1 year ago

Even better. that means you have all the linux command-line tools available already. The script will just show you what needs to go where

bruceborrett commented 1 year ago

Managed to get it all working and it is now reading the correct registers :partying_face: Thank you

kellerza commented 1 year ago

The first version of the MULTI addon should be ready.

You can now select a "three-phase" inverter though config & even add your own custom sensors

And new docs :wink: https://kellerza.github.io/sunsynk/reference/definitions

The definitions3ph.py file was contributed by @kababook & @archi and hopefully they keep it up to date,- PRs always welcome

NismoBoy34 commented 1 year ago

2023.03.19-0.3.1 running the new version as ive been waiting to test for a while and have been running on node red instead using flows for the longest time .. two issues come up alot firstly in the logs connectivity is not stable usually takes a few tries to get the addon reading rs485 .. no other applications using the port as ive disabled node red from starting totally .

2023-03-21 10:24:20,573 INFO options Loading HASS OS configuration 2023-03-21 10:24:20,599 INFO Using three phase sensor definitions. 2023-03-21 10:24:20,602 INFO Added hidden sensors as other sensors depend on it: 2023-03-21 10:24:20,604 INFO Connecting to serial:///dev/ttyUSB0 2023-03-21 10:24:20,630 INFO Reading startup sensors serial, rated_power 2023-03-21 10:24:30,700 ERROR Read Error: (1,3,5) 'Serial' object has no attribute 'host' 2023-03-21 10:24:30,722 INFO ############################################################ 2023-03-21 10:24:30,722 INFO No response on the Modbus interface serial:///dev/ttyUSB0, try checking the wiring to the Inverter, the USB-to-RS485 converter, etc 2023-03-21 10:24:30,722 INFO ############################################################ 2023-03-21 10:24:30,723 CRITICAL This Add-On will terminate in 30 seconds, use the Supervisor Watchdog to restart automatically.

NismoBoy34 commented 1 year ago

Second issue is if i run the single phase definitions i dont get any errors . ... but if i run the 3 phase definitions selection i get this and other errors constantly ... [s6-init] making user provided files available at /var/run/s6/etc...exited 0. [s6-init] ensuring user provided files have correct perms...exited 0. [fix-attrs.d] applying ownership & permissions fixes... [fix-attrs.d] done. [cont-init.d] executing container initialization scripts... [cont-init.d] done. [services.d] starting services [services.d] done. 2023-03-21 10:28:51,735 INFO options Loading HASS OS configuration 2023-03-21 10:28:51,764 INFO Using three phase sensor definitions. 2023-03-21 10:28:51,766 INFO Added hidden sensors as other sensors depend on it: 2023-03-21 10:28:51,767 INFO Connecting to serial:///dev/ttyUSB0 2023-03-21 10:28:51,782 INFO Reading startup sensors serial, rated_power 2023-03-21 10:28:51,894 INFO ############################################################ 2023-03-21 10:28:51,894 INFO Inverter serial number '2##############' 2023-03-21 10:28:51,895 INFO ############################################################ 2023-03-21 10:28:51,897 INFO MQTT: Connecting to homeassistant@core-mosquitto:1883 2023-03-21 10:28:52,937 INFO MQTT: Connection successful 2023-03-21 10:30:04,339 ERROR Read Error: (1,516,4) 'Serial' object has no attribute 'host'

And more digging im finding that its to do with the Definitions file ..

2023-03-21 10:38:44,427 INFO Removing HASS MQTT discovery info homeassistant/sensor/2208077352/total_grid_export/config 2023-03-21 10:38:44,429 INFO Removing HASS MQTT discovery info homeassistant/sensor/2208077352/total_grid_import/config 2023-03-21 10:38:55,152 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:38:55,173 INFO Retrying individual sensors: ['pv1_power', 'load_power', 'load_l1_power', 'load_l2_power', 'load_l3_power', 'gen_power', 'inverter_power', 'inverter_l1_power', 'inverter_l2_power', 'inverter_l3_power', 'total_pv_energy', 'total_battery_charge', 'total_battery_discharge', 'battery_soc'] 2023-03-21 10:39:05,327 ERROR Read ErrorLoad power: (1,653,1) 'Serial' object has no attribute 'host' 2023-03-21 10:39:15,436 ERROR Read ErrorLoad L1 power: (1,650,1) 'Serial' object has no attribute 'host' 2023-03-21 10:39:25,559 ERROR Read ErrorLoad L2 power: (1,651,1) 'Serial' object has no attribute 'host' 2023-03-21 10:39:35,840 ERROR Read ErrorInverter power: (1,636,1) 'Serial' object has no attribute 'host' 2023-03-21 10:39:46,166 ERROR Read ErrorTotal PV Energy: (1,534,2) 'Serial' object has no attribute 'host' 2023-03-21 10:39:46,428 WARNING Load power:step:mean: should not be None 2023-03-21 10:39:46,429 WARNING Load L1 power:step:mean: should not be None 2023-03-21 10:39:46,432 WARNING Load L2 power:step:mean: should not be None 2023-03-21 10:39:46,438 WARNING Inverter power:step:mean: should not be None 2023-03-21 10:39:46,442 WARNING Total PV Energy:last: should not be None 2023-03-21 10:40:02,524 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:40:12,604 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:40:24,718 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:40:36,812 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:40:48,907 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:41:01,000 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:41:13,090 ERROR Read Error: (1,650,4) 'Serial' object has no attribute 'host' 2023-03-21 10:41:25,189 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:41:37,280 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:41:49,376 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:42:01,470 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:42:13,564 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:42:25,651 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host' 2023-03-21 10:42:35,736 ERROR Read Error: (1,633,4) 'Serial' object has no attribute 'host'

kellerza commented 1 year ago

Can you try using mbusd? This seems more like there is an issue with the serial driver

I don't have the capability to test the serial driver, maybe I should just force everyone to go via mbusd

NismoBoy34 commented 1 year ago

ok

Can you try using mbusd? This seems more like there is an issue with the serial driver

I don't have the capability to test the serial driver, maybe I should just force everyone to go via mbusd

Ok installed and configured and no errors you were right thank you for that . seems to be working okay .

kellerza commented 1 year ago

Great, I’m not actively using the 3ph definitions, but PRs are welcome to that file

Will see if I can setup a test env to test the serial drivers& update pymodbus to the latest release as well. There seems to be some new development happening there (there was a blocking issue with async before pymodbus 3, and the reason why I included umodbus). Umodbus seems to be very quiet recently

I have my doubts if umodbus is reliable on usb interfaces

archi commented 1 year ago

I've also got it running now, with a small test PV deployment attached to the inverter. It currently runs in a screen session on my home server, and seemed rock solid. The reported data looks correct (didn't check all, but many), and I can even control lots of things in the inverter. N.b.: I'll probably put the "addon" into a systemd service on my host machine, since it works really nice even without home assistant - I really like how you went with the MQTT approach!

What I noticed:

  1. "Battery Capacity current" is given in A, but should be Ah (and drop the "current"); I'm not sure what keyword to use there instead of AMPS.
  2. "Grid Charge enabled" is a (0,1) switch, which translates to "ON" and "OFF" in Home Assistant, while many other options/switches use "On" and "Off". This inconsistency is a bit annoying for automations, since Grid Charge enabled needs special handling (I implemented a "force charge" switch in node-red to test the balancer)
  3. Currently we don't get data reported from the BMS, like CAN connection status, single cell voltages or permitted charge/discharge current. I'm not sure if these can even be read via RS485, but I'll take a look. Would probably also benefit the 1ph inverters.
  4. For some of the RWSensors I personally would prefer to monitor them, but not allow editing them in Home Assistant (like charge/discharge current). I can just patch my local definitions, but IMHO being able to set this per-option in the yaml would be neat. [Obviously this is an suggestion for a separate issue, just let me know if I should open one or if this has been considered and deemed "not on your todo list" ;-)]

For 1&2 I guess you have to decide if these changes are okay, Johann. I'll then open a PR.

For 3. I'll try to take a look once I find some spare time.

For 4. it's up to you as well; I know how painful random user "helpful suggestions" can be for FOSS maintainers and can totally live with a local workaround.

kellerza commented 1 year ago

I'll probably put the "addon" into a systemd service on my host machine, since it works really nice even without home assistant - I really like how you went with the MQTT approach!

Great, glad you got it working! Do you run it natively, or do you still use Docker/Podman?

  1. "Battery Capacity current" is given in A, but should be Ah (and drop the "current"); I'm not sure what keyword to use there instead of AMPS.

This does seem incorrect, especially with a max of 2000A. For "Ah" there is no specific keyword (only voltage/current/energy have these to try and enforce some consistency)

PR welcome. I'm not too concerned about adding deprecated version, but you can always add the _deprecated logic from the 1ph definitions.py file.

  1. "Grid Charge enabled" is a (0,1) switch, which translates to "ON" and "OFF" in Home Assistant, while many other options/switches use "On" and "Off". This inconsistency is a bit annoying for automations, since Grid Charge enabled needs special handling (I implemented a "force charge" switch in node-red to test the balancer)

MQTT Switch is not something I've tested extensively. Today it is simply a special case of a MQTT select entity, but might need to check the MQTT discovery docs again.

What exactly does the "Force charge" switch do?

  1. Currently we don't get data reported from the BMS, like CAN connection status, single cell voltages or permitted charge/discharge current. I'm not sure if these can even be read via RS485, but I'll take a look. Would probably also benefit the 1ph inverters.

This will really depend on the inverter - see also #59 for another place to read up on these modbus registers

  1. For some of the RWSensors I personally would prefer to monitor them, but not allow editing them in Home Assistant (like charge/discharge current). I can just patch my local definitions, but IMHO being able to set this per-option in the yaml would be neat. [Obviously this is an suggestion for a separate issue, just let me know if I should open one or if this has been considered and deemed "not on your todo list" ;-)]

If you are willing to do a PR I'll consider this, maybe through some modifier, like the filters, say sensor:RO

My approach is to add it to the UI as an entity. Then you have to first click on it and you can change in a popup. But I fully agree that some things you don't want to set in the UI. (At the end of #59 there is one, something completely hidden from the sunsynk UI). In the normal definitions file, I have tried to steer away from what I consider dangerous settings (like changing the grid frequency, - although a user suggested you can nicely disconnect from the grid if this is wrong. It's a neat use case, but I might be a bit conservative to test it)

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: entity
        entity: select.ss_prog1_time
        name: '1'
      - type: entity
        entity: select.ss_prog1_charge
        name: ' '
        state_color: false
      - type: gauge
        entity: number.ss_prog1_capacity
        needle: false
        name: ' '
  - type: horizontal-stack
    cards:
      - type: entity
        entity: select.ss_prog2_time
        name: '2'
      - type: entity
        entity: select.ss_prog2_charge
        name: ' '
      - type: gauge
        entity: number.ss_prog2_capacity
        needle: false
        name: ' '
image image
archi commented 1 year ago

Great, glad you got it working! Do you run it natively, or do you still use Docker/Podman?

Native execution inside a screen session. Since it runs well with python 3.10 from the Arch Linux repositories, I don't see a reason to put inside a container which I'd then need to update manually. If I find some time, I'll probably write a package file.

What exactly does the "Force charge" switch do?

Set the target capacity in the "time of use" config to 100% and enable grid charging. This will then fully charge the battery. I used this to charge the battery for initial balancing.

[...] but I might be a bit conservative to test it)

haha, I feel very much the same :)

Regarding the other points, I'll try to look into these once I have some time on my hands :) Though with the current state I'm already very happy.

kellerza commented 1 year ago

What exactly does the "Force charge" switch do?

Set the target capacity in the "time of use" config to 100% and enable grid charging. This will then fully charge the battery. I used this to charge the battery for initial balancing.

This seems like a combination of the writable sensors grid_charge_enabled and prog1_capacity..prog6_capacity

kellerza commented 1 year ago

The MULTI addon allows you to use the three-phase definitions - https://kellerza.github.io/sunsynk/reference/definitions#three-phase-inverter-sensor-definitions

For any specific issues on the 3ph definitions, please open a PR/new issue

khems commented 1 year ago

Which port did you guys plug into in the end? Meter 485? Or did you have to split the BMS port in the end?