Modbus write register settings sma battery invertor using service modbus.write_register

Heres what i’m trying to do

SMA SBS5 battery invertor, to instruct invertor to charge battery from grid.

I am successfully reading using modbus various modbus register addresses getting all sorts of data on the battery invertor including charge%, charge/discharge wattage, current running mode, temperature of invertor etc etc

Where i am stuck is trying to fathom the modbus.write register service in Hassio and how to configure

I have been given the following write register information from SMA the invertor manufacturer

----snip----
To enable manual charging set points you need to do the following.

  1. Using register 40151 and enabling the function to charge via modbus.
    Value ranges as follows
    802: Active (Act)
    803: Inactive (Ina)

2.Using register 40149 and entering the value, positive for discharge and negative for charging
----snip----

I have tried the following in the service dev tool

service: modbus.write_register
data:
  address: 40151
  hub: thames23ss
  value: 802
  unit: 3

not sure whether i am on the right track here, and whether the values themselves are correct

  • the hub name is defined in configuration.yaml.
  • the unit value in service dev tool suggests this is the “address of the modbus unit”, so i assume this is the slave address?
  • address i assume is the holding register address?
  • value i assume is the value defined above in the explanation

In my log with the above values when i attempt to call the service, i get an error in the log as follows
Pymodbus: Exception Response(134, 6, IllegalAddress)

so something is amiss in my configuration on the service dev tool

Anyone with some experience in utilising modbus write registers able to point me in the right direction?

Why am i trying to achieve this?
In winter i would like to charge battery from grid during off peak tariff of 11c kwh, and stop charging once shoulder tariff of 18ckwh, only if the ac is running.

Ive got all the pieces of the puzzle in place,

  1. I can see the ac is running from its pwoer consumption being greter than 400w
  2. I can read all the modbus values of the battery invertor, eg: soc (state of charge %) and charge or discharge load
  3. i have a temperature sensor of the room so that ac only kicks in when below threshold temperature

however am stuck on the modbus write register for the battery invertor to instruct it to go into charge if all my conditions above are met.

eg: ac running during off peak tariff (before 7am), charge for 12 minutes at 5000w until shoulder period, then stop charging battery and allow to discharge once shoulder period commences at 7am.

Maybe you are supposed to convert the register number to an address. Modbus - Wikipedia says this:

holding register numbers start with 4 and span from 40001 to 49999.

For holding registers starting at number 40100, address will be 99.

So I guess this should work:

service: modbus.write_register
data:
  address: 150
  hub: thames23ss
  value: 802
  unit: 3

However, I have no experience with Modbus. If you decide to try my example above, you are doing so at your own risk. You could potentially write the value to an incorrect register.

Hi !

Did you success to write value to your SMA inverter ?

I am stuck with the same issue. I can read but not write.

Thank you for your answer,

I’ve found a solution. Need to write an array instead of a value to fill the two 16 bits register of the inverter address :

service: modbus.write_register
data:
  address: 40723
  slave: 3
  value:
    - 0
    - 50
  hub: sma
1 Like

@adrien.schouleur

awesome, glad you got it working. I let this one slide a while ago as i found the sbs invertor had “perfoirmance profiles” which i ended up configuring, however i never really let this one go from the back of my mind.

I assume when you say you found a solution, did you have to write register 40151 to activate charge / discharge function first? and is this a onetime write command, or must it happen everytime? and then deactivate afterwards to return battery invertor to normal standalone operation?

and then define a charge / discharge value for register 40723?

Can i ask which battery invertor you are using?

and 2 more things -

I note you are writing value 40723, which in my modbus definition from sma states “Minimum width of backup power area”, which i assume means you are making the battery have a minimum charge of 50% ?

I guess this could work in my use case, but do you have to write a value of 0 again at a later stage else battery only ever discharges to 50% after you have sent you write register of 50?

@adrien.schouleur

This looks to be a far more elegant solution the way you’ve implemented, on further research i believe the modbus register values i was looking at before (40151 & 40149) are for external charge / discharge values being pushed through modbus to the invertor, rather than relying on the storage server invertor doing its own charge / discharge values, in conjunction with the sma smart meter with its nbt broadcast of feed in or purchase values.

Your solution allows me to create 2 automations with the following description.
At 5am, if battery charge is less than 11%, set minimum charge for battery to be 25%, and the battery will kick in and charge itself to 25%. nice

The second automation will set the min charge value back to 0% at 5:50am. Which means i’ve injected some charge into the battery if its low at off peak rate (10 cents a kWh) to then be used during shoulder period at shoulder rate (16 cents a kWh)

for the purposes of sharing, i will paste the automation i am using with the relevant modbus write register call

to charge at 5am

alias: SunnyStorage_charge_when_min_value_below_threshold
description: >-
  Sunny Storage set min threshold charge value to 20%  & charge battery
  at 5am - condition batt charge is below 11% at 5am
trigger:
  - platform: time
    at: "05:00:00"
condition:
  - condition: numeric_state
    entity_id: sensor.modbus_ss_charge_level
    below: 11
action:
  - service: modbus.write_register
    data:
      hub: thames23ss
      value:
        - 0
        - 20
      slave: 3
      address: 40723
mode: single

to stop charging at 5:50am

alias: SunnyStorage_charge_when_min_value_below_threshold
description: >-
  Sunny Stoarge set min threshold charge value to 0%  at 5:50am
trigger:
  - platform: time
    at: "05:50:00"
action:
  - service: modbus.write_register
    data:
      hub: thames23ss
      value:
        - 0
        - 0
      slave: 3
      address: 40723
mode: single

Hi all,

I have a SMA Sunnyboy storage 5 with a BYD HVM 11kWh battery

I am looking for a way to manualy charge/discharge the battery contolled by HA looking to dynamic prices in Belgium. The goal is to charge from the grid at low price and to discharge at high prices.
I’ve managed to get the dynamic prices in HA & I’ve managed to get all the data from the SMA SBS integration in to HA, but there is minimal to none control of the battery.
I think it could be controled by modbus, but I don’t find the codes in the modbus list.

I would like to program 4 modes:

  • automatic (full auto self consumption like it is now)
  • manualy charge @ xxxx W (xxxx needs to be configurable)
  • manualy discharge @ xxxx W (xxxx needs to be configurable)
  • manualy off (stay standby)

could anyone help me with this or point me in the right direction?

Tnx in advance

Thanks for getting this working. I have this running now, too. However i had a hard time with the 40723 register not accepting values. Turns out you can only set it to max. 90, everything beyond that will be silently ignored by the inverter (modbus will not return any error!). So its only possible to charge upto 90% with this method - but its fine with me.

@jonas21 , maybe its a limitation of your particular battery invertor model?
I just tested my SBS5-10 running Firmware version: 4.4.3.R
and i can set mine to be 95%

I now also read using register 40723 to get the current set min backup % value (note i only scan every 31 secs for this value) which allws me to display a sensor of the current min value set

- type: tcp
  host: redacted
  port: 502
  name: redacted
  sensors:
    - name: Modbus SS min backup value
      unit_of_measurement: "%"
      slave: 3
      address: 40723
      count: 2
      data_type: int32
      precision: 0
      scan_interval: 31

yes, might be possible. Using a Sunny Island 6.0H11 here (older gen, no GUI, just modbus/speedwire).
I can only set 40723 to 90% using modbus (everything else is ignored, as said). However with SMA’s software (sunny explorer) i can set it above 90% - that software uses speedwire instead of modbus.

I dont really need to read the value. I’ve made a automation which checks tibber’s price for kW/h and if its negative then it sets 40723 to 90% (max), so if i get money for using grid then charge the battery no matter what :slight_smile:

Hi,

Did you get it working like described or get some feedback somewhere?

Greetings

Hello all,

I hope this feed is still alive.
I mannaged to get the chargefunctionality by modbus operational.
But something strange is happening.
When my homebattery is charging, exactly every 30min it is deactivated.
I monitor if the battery is charging, deactivate it by modbus when ´not´ and activate it again for max. 30min.

Does anyone know how to change this ´rare´ behavior in the parametersettings somewhere?

Greetings