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

Be Aware Warning aganst using RW registers with cyclical writing warning

as a follow up to this thread, yesterday i had an issue when attempting to write modbus registers to my sma invertor using address 40723. The error on the invtertor was

error 10120 Currently permitted number of parameterizations exceeded

This has been functioning for close on 3 years, writing modbus registers at least twice on a daily basis.

After spending the best part of a day on the phone with SMA Support, i found out the following information. “Most” of the registers are RO read only, however some of them can also be written RW.

I have the “MODBUS-HTML_SBS3.7-6.0-10_GG10-V13” modbus spec which is available for download from the SMA website.

In the “Access SMA” column you will notice the registers with a RW value are registers that can be written. Note however some of them have a yellow excalamation mark beside “RW” as shown in screenshot “Warning-sma-rw-cyclical.jpg”. When you hover your mouse over, note there is a warning popup stating “Warning against cyclical writing”

Take care, not all registers are meant to be changed continuously, but only to be set once (sma calls this “cyclical writing” changes). Changing them on a continuous basis will destroy flash memory. SMA has this documented in their modbus register documents.

Therefore, register 40723 now that i have had this issue with my invertor i have had to disable, as it stopped working regardless with the above error. For the moment i have returned to using the inbuilt “performance profiles” setting in the invertor to inject charge into my battery on a fixed daily basis. However these values are fixed, and i no longer have the ability of looking at weather forecasts and then choosing the value to charge the battery during off peak periods using register 40723 (as its one of the registers with a cyclical writing warning)

I took a look back through my original post and note the following which original information i received from SMA

----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----

Both registers 40151 & 40149 are WO (which i assume means write only), and these 2 values do NOT have the cyclical warning error. So my plan is to implement same charging using the above 40151 & 40149 values once i have my SBS5 invertor back to a stable state

1 Like

Ok had a chance to test this this morning and the following is working for me, and these 2 registers 40151 & 40149 do not have the cyclical warning associated in the SBS5 modbus definition file

Charge at 5000w - By default this should charge for 30 minutes, there is a timeout value for external control in sbs, which i changed to be 60 minutes from the default of 30 minutes. Note register 40151 with entry 803 is to stop external control via modbus after 1 hour. It didn’t reset itself for me, so i added the following to disable charging via modbus after a 1 hour delay

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

# enable charge via modbus
- service: modbus.write_register
  data:
    hub: redacted
    address: 40151
    slave: 3
    value:
      - 0
      - 802
- delay:
    hours: 0
    minutes: 0
    seconds: 5
    milliseconds: 0
# set charge rate at 5000w
- service: modbus.write_register
  data:
    hub: redacted
    address: 40149
    slave: 3
    value:
      - 65535
      - 60535
# allow to run / charge for 1 hour
- delay:
    hours: 1
    minutes: 0
    seconds: 0
    milliseconds: 0
# disable charge via modbus
- service: modbus.write_register
  data:
    hub: redacted
    address: 40151
    slave: 3
    value:
      - 0
      - 803

The charge/discharge value is a delta between the two values. This has to do with the way in which negative or positive values ​​are transmitted to modbus via HA in this case

for example, to charge at rate of 500w use the following values

  data:
    hub: redacted
    address: 40149
    slave: 3
    value:
      - 65535
      - 65035

or 1000w

value:
  - 65535
  - 64535

I believe if you are using registers 40151 & 40149, there is a setting in the SBS that is by default 30 minutes for external charge control. You can change this value, I was able to change this to 60 minutes in my case

This didnt seem to reset for me, therefore using register 40151 and value 803 disabled the charge via modbus external control setting and allowed the invertor to once again discharge

Update to Firmware 2.14.1x.R of Sunny Home Manager (SHM2) will Most likely break the ability to control inverters via Modbus.
Don’t ask me how I know.

Update: SHM Firmware 2.15.4.R fixes that issue. Currently in testing and not yet available for everyone.

1 Like

Hi Peterho, do you know (approximately) how many time we can write data on such addresses with a warning sign? I am using Core1 STP50-41 PV String inverter and some of the addresses has the same warning times. and I need to change the PV Inverter SP from 0 - 100% in a step of 5 or 10%. Atleast 2 times in a day.

Toshi

The advice i was given from SMA in relation to registers with cyclical warning exclamation in the modbus register spreadsheet was as follows

“The register you are changing is not supposed to be changed frequently, if this continues the flash memory of the inverter will be damaged and cannot be fixed.”

I got around 3 years writing twice a day before i started seeing the error “10120 Currently permitted number of parameterizations exceeded”

You have been warned. Do what i did and find a register or a method whereby this cyclical warning message does not appear against the modbus register. I had to go through quite a bit of pain to get my invertor back up and running once i started receiving this error (firmware / software updates, reset to default etc on the invertor)

Please can you tell me what modbus register you used to change the timeout value or indeed what you did to change it. I have the same issue.

Many thanks

Steve