Fronius Symo Gen 24 plus Batteries

I have a Fronius Symo Gen 24 with BYD HVM batteries and wonder if someone could write an “how to” that describes the command to charge/discharge the battery? I have searched here and on other places and I think there is a way to do it via Modbus, but I’m not that smart to understand how one does it.

There is other topics about how to get the values in via Modbus and I can get that working. I would live to be able to charge when the energy price is low and sell when the energy prices are high via an automation. And if you know this cannot be done then please let me know. Thanks :slight_smile:

hi @Klangen82 - I’m disabling battery discharge if a car is charging:

# disable battery disscharge if the car is plugged in 
- alias: CarChargingWRBatteryOff
  trigger:
    platform: state
    entity_id: sensor.wallbox_car_state
    to: "2"
  action:
    service: modbus.write_register
    data:
       unit: 1
       hub: fronius1
       address: 40365
       value: '0'
       
# enable battery discharge if the car is fully charged
- alias: CarChargingWRBatteryOn
  trigger:
    platform: state
    entity_id: sensor.wallbox_car_state
    from: "2"
  action:
    service: modbus.write_register
    data:
       unit: 1
       hub: fronius1
       address: 40365
       value: '4500'

Charging of the battery can be managed through register 40366 if I remember correctly (best to check against the Fronius Modbus Documentation). The specific values must be adapted to your battery type.

Cheers, Oscar

1 Like

Thanks Oscar,

Will play around with this and share some Node-RED examples as soon as I find time for it.

I see in the example from the manual I need to set the InWRTw = -50% but when I try to inject negative values I get error “RangeError: The value of “value” is out of range. It must be >= 0 and <= 65535. Received -5000”

So how does one do to send negative values?

image

I have made the following Node-RED test setup but I don’t get it to charge from the power grid or discharge to the power grid.

[{"id":"39a3ea19badb7a7f","type":"tab","label":"Fronius","disabled":false,"info":"","env":[]},{"id":"f75297d93960df81","type":"group","z":"39a3ea19badb7a7f","name":"Check Battery info","style":{"label":true},"nodes":["0b901412575e77de","025e55e4cd9d8bb2","a28d80d962da8e74"],"x":34,"y":659,"w":592,"h":82},{"id":"24ca5fdbc91db29f","type":"group","z":"39a3ea19badb7a7f","style":{"stroke":"#3a3a3a","stroke-opacity":"1","fill":"#1e1e1e","fill-opacity":"0.5","label":true,"label-position":"nw","color":"#cccccc"},"nodes":["777c42f0e984e8c8","ca8ddbbf183247be","bbbed64d84c3e57c","814f2404114806e9","7ca251d534666024","00ba5db7448fe338","1611cb73f11453da","a5a577e982c10fa3","79b2e232f28181df","cb475883eacf824e","143db3428fa337ce","e44cdc136ef05cd0","290c98a0ee7f62ff","99f5ccb527936a73","47907f82d4b0d24f","bb7e4e3771e109e1","619f3f5cef3e3acf","d2ed4f29c2ddb272","b94439aaa72d2c0e"],"x":34,"y":19,"w":872,"h":522},{"id":"0326af1f3381f0d2","type":"group","z":"39a3ea19badb7a7f","name":"Check Battery info RW only","style":{"label":true},"nodes":["4a3f86cd842388ab","37f2edd293b98175","0f748ebda2d8ea29"],"x":34,"y":559,"w":592,"h":82},{"id":"0b901412575e77de","type":"modbus-read","z":"39a3ea19badb7a7f","g":"f75297d93960df81","name":"Battery info","topic":"40354","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40353","quantity":"26","rate":"10","rateUnit":"m","delayOnStart":false,"startDelayTime":"","server":"bcc4229c.180ac","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":150,"y":700,"wires":[["a28d80d962da8e74"],[]]},{"id":"025e55e4cd9d8bb2","type":"debug","z":"39a3ea19badb7a7f","g":"f75297d93960df81","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":700,"wires":[]},{"id":"a28d80d962da8e74","type":"function","z":"39a3ea19badb7a7f","g":"f75297d93960df81","name":"RAW to JSON","func":"var data = msg.payload;\nvar raw = {\n    'ID': data[0],\n    'L': data[1],\n    'WChaMax': data[2],\n    'WChaGra': data[3],\n    'WDisChaGra': data[4],\n    'StorCtl_Mod': data[5],\n    'VAChaMax': data[6],\n    'MinRsvPct': data[7],\n    'ChaState': data[8],\n    'StorAval': data[9],\n    'InBatV': data[10],\n    'ChaSt': data[11],\n    'OutWRte': data[12],\n    'InWRte': data[13],\n    'InOutWRte_WinTms': data[14],\n    'InOutWRte_RvrtTms': data[15],\n    'InOutWRte_RmpTms': data[16],\n    'ChaGriSet': data[17],\n    'WChaMax_SF': data[18],\n    'WChaDisChaGra_SF': data[19],\n    'VAChaMax_SF': data[20],\n    'MinRsvPct_SF': data[21],\n    'ChaState_SF': data[22],\n    'StorAval_SF': data[23],\n    'InBatV_SF': data[24],\n    'InOutWRte_SF': data[25],\n}\n\n\nvar VFactor = 0.01;\nvar AFactor = 0.01;\nvar WFactor = 0.01;\nvar WHFactor = 1;\n\n\nvar result = {\n    'S1_V': VFactor * raw.S1_DCV,\n    'S1_A': AFactor * raw.S1_DCA,\n    'S1_W': WFactor * raw.S1_DCW,\n    'S1_WH': WHFactor * raw.S1_DCWH,\n    'S1_TimeStamp': raw.S1_Tms,\n    'S1_T': raw.S1_Tmp,\n    'S1_State': raw.S1_DCSt,\n\n    'S2_V': VFactor * raw.S2_DCV,\n    'S2_A': AFactor * raw.S2_DCA,\n    'S2_W': WFactor * raw.S2_DCW,\n    'S2_WH': WHFactor * raw.S2_DCWH,\n    'S2_TimeStamp': raw.S2_Tms,\n    'S2_T': raw.S2_Tmp,\n    'S2_State': raw.S2_DCSt,\n}\nmsg.payload = {\n    data : data,\n    raw : raw,\n    result : result\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":700,"wires":[["025e55e4cd9d8bb2"]]},{"id":"777c42f0e984e8c8","type":"modbus-flex-write","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"Fronius-Storage","showStatusActivities":true,"showErrors":true,"server":"bcc4229c.180ac","emptyMsgOnFail":true,"keepMsgProperties":true,"x":600,"y":60,"wires":[["814f2404114806e9"],[]]},{"id":"ca8ddbbf183247be","type":"function","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"OutWRte=","func":"msg.payload = { \n    'value': msg.payload,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40365,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":60,"wires":[["777c42f0e984e8c8"]]},{"id":"bbbed64d84c3e57c","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"10000","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"10000","payloadType":"num","x":130,"y":60,"wires":[["ca8ddbbf183247be"]]},{"id":"814f2404114806e9","type":"modbus-response","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"","registerShowMax":20,"x":790,"y":60,"wires":[]},{"id":"7ca251d534666024","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"0","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"0","payloadType":"num","x":130,"y":100,"wires":[["ca8ddbbf183247be"]]},{"id":"00ba5db7448fe338","type":"function","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"InWRte=","func":"msg.payload = { \n    'value': msg.payload,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40366,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":180,"wires":[["777c42f0e984e8c8"]]},{"id":"1611cb73f11453da","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"10000","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"10000","payloadType":"num","x":130,"y":180,"wires":[["00ba5db7448fe338"]]},{"id":"a5a577e982c10fa3","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"0","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"0","payloadType":"num","x":130,"y":220,"wires":[["00ba5db7448fe338"]]},{"id":"79b2e232f28181df","type":"function","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"StorCtl_Mod=","func":"msg.payload = { \n    'value': msg.payload,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40358,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":300,"wires":[["777c42f0e984e8c8"]]},{"id":"cb475883eacf824e","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"0x03 = 3","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"3","payloadType":"num","x":140,"y":420,"wires":[["79b2e232f28181df"]]},{"id":"143db3428fa337ce","type":"function","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"InOutWRte_RvrtTms=","func":"msg.payload = { \n    'value': msg.payload,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40368,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":460,"wires":[["777c42f0e984e8c8"]]},{"id":"e44cdc136ef05cd0","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"0","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"0","payloadType":"num","x":130,"y":460,"wires":[["143db3428fa337ce"]]},{"id":"290c98a0ee7f62ff","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"0","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"0","payloadType":"num","x":130,"y":300,"wires":[["79b2e232f28181df"]]},{"id":"99f5ccb527936a73","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"-10000","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"-10000","payloadType":"str","x":130,"y":140,"wires":[["ca8ddbbf183247be"]]},{"id":"47907f82d4b0d24f","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"5000","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"5000","payloadType":"num","x":130,"y":260,"wires":[["00ba5db7448fe338"]]},{"id":"bb7e4e3771e109e1","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"1","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"1","payloadType":"num","x":130,"y":340,"wires":[["79b2e232f28181df"]]},{"id":"619f3f5cef3e3acf","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"2","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"2","payloadType":"num","x":130,"y":380,"wires":[["79b2e232f28181df"]]},{"id":"d2ed4f29c2ddb272","type":"function","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"ChaGriSet=","func":"msg.payload = { \n    'value': msg.payload,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40370,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":500,"wires":[["777c42f0e984e8c8"]]},{"id":"b94439aaa72d2c0e","type":"inject","z":"39a3ea19badb7a7f","g":"24ca5fdbc91db29f","name":"1","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"1","payloadType":"num","x":130,"y":500,"wires":[["d2ed4f29c2ddb272"]]},{"id":"4a3f86cd842388ab","type":"modbus-read","z":"39a3ea19badb7a7f","g":"0326af1f3381f0d2","name":"Battery info","topic":"40354","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40353","quantity":"26","rate":"10","rateUnit":"m","delayOnStart":false,"startDelayTime":"","server":"bcc4229c.180ac","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":150,"y":600,"wires":[["0f748ebda2d8ea29"],[]]},{"id":"37f2edd293b98175","type":"debug","z":"39a3ea19badb7a7f","g":"0326af1f3381f0d2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":600,"wires":[]},{"id":"0f748ebda2d8ea29","type":"function","z":"39a3ea19badb7a7f","g":"0326af1f3381f0d2","name":"RAW to JSON","func":"var data = msg.payload;\nvar raw = {\n    'StorCtl_Mod': data[5],\n    'MinRsvPct': data[7],\n    'OutWRte': data[12],\n    'InWRte': data[13],\n    'InOutWRte_RvrtTms': data[15],\n    'ChaGriSet': data[17],\n}\n\n\nvar VFactor = 0.01;\nvar AFactor = 0.01;\nvar WFactor = 0.01;\nvar WHFactor = 1;\n\n\nvar result = {\n    'S1_V': VFactor * raw.S1_DCV,\n    'S1_A': AFactor * raw.S1_DCA,\n    'S1_W': WFactor * raw.S1_DCW,\n    'S1_WH': WHFactor * raw.S1_DCWH,\n    'S1_TimeStamp': raw.S1_Tms,\n    'S1_T': raw.S1_Tmp,\n    'S1_State': raw.S1_DCSt,\n\n    'S2_V': VFactor * raw.S2_DCV,\n    'S2_A': AFactor * raw.S2_DCA,\n    'S2_W': WFactor * raw.S2_DCW,\n    'S2_WH': WHFactor * raw.S2_DCWH,\n    'S2_TimeStamp': raw.S2_Tms,\n    'S2_T': raw.S2_Tmp,\n    'S2_State': raw.S2_DCSt,\n}\nmsg.payload = {\n    data : data,\n    raw : raw,\n    result : result\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":600,"wires":[["37f2edd293b98175"]]},{"id":"bcc4229c.180ac","type":"modbus-client","name":"Fronius","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":false,"tcpHost":"192.168.5.182","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":200,"commandDelay":1,"clientTimeout":1000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true}]'

So after doing some testing/digging etc. I think I found out some things that maybe can help someone else.

I have a Symo Gen 24 8kW so maybe you will need to change the values if you have a smaller/bigger inverter. WChaMax divide by 2 to get your maximum watt that you can charge/discharge, or look it up on the spec of the inverter. (in my case 8250w)

Node-RED code below to import what worked for me:

[{"id":"082d1a6d7f9f4ee6","type":"tab","label":"Charge Controll Fronius Battery","disabled":false,"info":"","env":[]},{"id":"990a82509790982d","type":"group","z":"082d1a6d7f9f4ee6","style":{"stroke":"#3a3a3a","stroke-opacity":"1","fill":"#1e1e1e","fill-opacity":"0.5","label":true,"label-position":"nw","color":"#cccccc"},"nodes":["01b27fd4c6df709e","a14e060aa8b357d3"],"x":1114,"y":99,"w":412,"h":82},{"id":"45acb5295fb1f6dc","type":"group","z":"082d1a6d7f9f4ee6","name":"Charge 100%","style":{"label":true},"nodes":["884f2c943fb25d0a","b83174f039a2d5e6","78bf6418bd324a42","4ddfd89be5bfedf9","fe05816fcd28a90d","20b1eff7b4967a95"],"x":14,"y":19,"w":492,"h":162},{"id":"4f3ffe065555c0fe","type":"group","z":"082d1a6d7f9f4ee6","name":"Discharge 100%","style":{"label":true},"nodes":["90fccb5e6388880a","9891a0a6eb033160","92d5124fc68884d0","c5c98e12a75471fa","8bd4d58fbd889f99","29977cc08b49350b"],"x":14,"y":199,"w":492,"h":162},{"id":"2b3f222be46c2490","type":"group","z":"082d1a6d7f9f4ee6","name":"Normal operation","style":{"label":true},"nodes":["ea00b2d2947c7047","f64bcb1810827035"],"x":554,"y":19,"w":392,"h":82},{"id":"6cefe547798fa70b","type":"group","z":"082d1a6d7f9f4ee6","name":"No charge/discharge","style":{"label":true},"nodes":["56971e07f5b82a9d","301cc5bfd5441a20","5e1aed5ce6c7b5ae","321d182f3a1d142b","7c0bb5afc650da96","159b084e75e7ebe6"],"x":554,"y":199,"w":492,"h":162},{"id":"c40948974576ca28","type":"group","z":"082d1a6d7f9f4ee6","name":"Check Battery info","style":{"label":true},"nodes":["6af939f8557606d0","33f657511e9659a2","9d2b7e0d8afa516b"],"x":14,"y":479,"w":592,"h":82},{"id":"f899bcc02c1725fc","type":"group","z":"082d1a6d7f9f4ee6","name":"Check Battery info RW only","style":{"label":true},"nodes":["bb3812291ebfcfb9","ef1f47997f40e6e5","18f4782d041591d2"],"x":14,"y":379,"w":592,"h":82},{"id":"01b27fd4c6df709e","type":"modbus-response","z":"082d1a6d7f9f4ee6","g":"990a82509790982d","name":"","registerShowMax":20,"x":1410,"y":140,"wires":[]},{"id":"a14e060aa8b357d3","type":"modbus-flex-write","z":"082d1a6d7f9f4ee6","g":"990a82509790982d","name":"Fronius-Storage","showStatusActivities":true,"showErrors":true,"server":"bcc4229c.180ac","emptyMsgOnFail":true,"keepMsgProperties":true,"x":1220,"y":140,"wires":[["01b27fd4c6df709e"],[]]},{"id":"884f2c943fb25d0a","type":"delay","z":"082d1a6d7f9f4ee6","g":"45acb5295fb1f6dc","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":290,"y":100,"wires":[["fe05816fcd28a90d"]]},{"id":"b83174f039a2d5e6","type":"delay","z":"082d1a6d7f9f4ee6","g":"45acb5295fb1f6dc","name":"1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":270,"y":140,"wires":[["20b1eff7b4967a95"]]},{"id":"78bf6418bd324a42","type":"inject","z":"082d1a6d7f9f4ee6","g":"45acb5295fb1f6dc","name":"Charge 100%","props":[{"p":"outwrte","v":"60933","vt":"num"},{"p":"inwrte","v":"4603","vt":"str"},{"p":"storctl_mod","v":"2","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","x":130,"y":60,"wires":[["4ddfd89be5bfedf9","884f2c943fb25d0a","b83174f039a2d5e6"]]},{"id":"4ddfd89be5bfedf9","type":"function","z":"082d1a6d7f9f4ee6","g":"45acb5295fb1f6dc","name":"InWRte","func":"msg.payload = { \n    'value': msg.inwrte,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40366,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":60,"wires":[["a14e060aa8b357d3"]]},{"id":"fe05816fcd28a90d","type":"function","z":"082d1a6d7f9f4ee6","g":"45acb5295fb1f6dc","name":"OutWRte","func":"msg.payload = { \n    'value': msg.outwrte,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40365,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":100,"wires":[["a14e060aa8b357d3"]]},{"id":"20b1eff7b4967a95","type":"function","z":"082d1a6d7f9f4ee6","g":"45acb5295fb1f6dc","name":"StorCtl_Mod","func":"msg.payload = { \n    'value': msg.storctl_mod,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40358,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":140,"wires":[["a14e060aa8b357d3"]]},{"id":"90fccb5e6388880a","type":"delay","z":"082d1a6d7f9f4ee6","g":"4f3ffe065555c0fe","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":290,"y":280,"wires":[["8bd4d58fbd889f99"]]},{"id":"9891a0a6eb033160","type":"delay","z":"082d1a6d7f9f4ee6","g":"4f3ffe065555c0fe","name":"1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":270,"y":320,"wires":[["29977cc08b49350b"]]},{"id":"92d5124fc68884d0","type":"inject","z":"082d1a6d7f9f4ee6","g":"4f3ffe065555c0fe","name":"Discharge 100%","props":[{"p":"outwrte","v":"4603","vt":"num"},{"p":"inwrte","v":"60933","vt":"str"},{"p":"storctl_mod","v":"1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","x":140,"y":240,"wires":[["c5c98e12a75471fa","90fccb5e6388880a","9891a0a6eb033160"]]},{"id":"c5c98e12a75471fa","type":"function","z":"082d1a6d7f9f4ee6","g":"4f3ffe065555c0fe","name":"InWRte","func":"msg.payload = { \n    'value': msg.inwrte,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40366,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":240,"wires":[["a14e060aa8b357d3"]]},{"id":"8bd4d58fbd889f99","type":"function","z":"082d1a6d7f9f4ee6","g":"4f3ffe065555c0fe","name":"OutWRte","func":"msg.payload = { \n    'value': msg.outwrte,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40365,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":280,"wires":[["a14e060aa8b357d3"]]},{"id":"29977cc08b49350b","type":"function","z":"082d1a6d7f9f4ee6","g":"4f3ffe065555c0fe","name":"StorCtl_Mod","func":"msg.payload = { \n    'value': msg.storctl_mod,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40358,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":320,"wires":[["a14e060aa8b357d3"]]},{"id":"ea00b2d2947c7047","type":"inject","z":"082d1a6d7f9f4ee6","g":"2b3f222be46c2490","name":"Normal operation","props":[{"p":"storctl_mod","v":"0","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","x":680,"y":60,"wires":[["f64bcb1810827035"]]},{"id":"f64bcb1810827035","type":"function","z":"082d1a6d7f9f4ee6","g":"2b3f222be46c2490","name":"StorCtl_Mod","func":"msg.payload = { \n    'value': msg.storctl_mod,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40358,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":850,"y":60,"wires":[["a14e060aa8b357d3"]]},{"id":"56971e07f5b82a9d","type":"delay","z":"082d1a6d7f9f4ee6","g":"6cefe547798fa70b","name":"500ms","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":830,"y":280,"wires":[["7c0bb5afc650da96"]]},{"id":"301cc5bfd5441a20","type":"delay","z":"082d1a6d7f9f4ee6","g":"6cefe547798fa70b","name":"1s","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":810,"y":320,"wires":[["159b084e75e7ebe6"]]},{"id":"5e1aed5ce6c7b5ae","type":"inject","z":"082d1a6d7f9f4ee6","g":"6cefe547798fa70b","name":"No charge/discharge","props":[{"p":"outwrte","v":"0","vt":"num"},{"p":"inwrte","v":"0","vt":"str"},{"p":"storctl_mod","v":"3","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","x":690,"y":240,"wires":[["321d182f3a1d142b","56971e07f5b82a9d","301cc5bfd5441a20"]]},{"id":"321d182f3a1d142b","type":"function","z":"082d1a6d7f9f4ee6","g":"6cefe547798fa70b","name":"InWRte","func":"msg.payload = { \n    'value': msg.inwrte,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40366,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":240,"wires":[["a14e060aa8b357d3"]]},{"id":"7c0bb5afc650da96","type":"function","z":"082d1a6d7f9f4ee6","g":"6cefe547798fa70b","name":"OutWRte","func":"msg.payload = { \n    'value': msg.outwrte,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40365,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":280,"wires":[["a14e060aa8b357d3"]]},{"id":"159b084e75e7ebe6","type":"function","z":"082d1a6d7f9f4ee6","g":"6cefe547798fa70b","name":"StorCtl_Mod","func":"msg.payload = { \n    'value': msg.storctl_mod,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40358,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":320,"wires":[["a14e060aa8b357d3"]]},{"id":"6af939f8557606d0","type":"modbus-read","z":"082d1a6d7f9f4ee6","g":"c40948974576ca28","name":"Battery info all values","topic":"40354","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40353","quantity":"26","rate":"10","rateUnit":"m","delayOnStart":false,"startDelayTime":"","server":"bcc4229c.180ac","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":160,"y":520,"wires":[["9d2b7e0d8afa516b"],[]]},{"id":"33f657511e9659a2","type":"debug","z":"082d1a6d7f9f4ee6","g":"c40948974576ca28","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":510,"y":520,"wires":[]},{"id":"9d2b7e0d8afa516b","type":"function","z":"082d1a6d7f9f4ee6","g":"c40948974576ca28","name":"RAW to JSON","func":"var data = msg.payload;\nvar raw = {\n    'ID': data[0],\n    'L': data[1],\n    'WChaMax': data[2],\n    'WChaGra': data[3],\n    'WDisChaGra': data[4],\n    'StorCtl_Mod': data[5],\n    'VAChaMax': data[6],\n    'MinRsvPct': data[7],\n    'ChaState': data[8],\n    'StorAval': data[9],\n    'InBatV': data[10],\n    'ChaSt': data[11],\n    'OutWRte': data[12],\n    'InWRte': data[13],\n    'InOutWRte_WinTms': data[14],\n    'InOutWRte_RvrtTms': data[15],\n    'InOutWRte_RmpTms': data[16],\n    'ChaGriSet': data[17],\n    'WChaMax_SF': data[18],\n    'WChaDisChaGra_SF': data[19],\n    'VAChaMax_SF': data[20],\n    'MinRsvPct_SF': data[21],\n    'ChaState_SF': data[22],\n    'StorAval_SF': data[23],\n    'InBatV_SF': data[24],\n    'InOutWRte_SF': data[25],\n}\n\n\nmsg.payload = {\n    data : data,\n    raw : raw,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":520,"wires":[["33f657511e9659a2"]]},{"id":"bb3812291ebfcfb9","type":"modbus-read","z":"082d1a6d7f9f4ee6","g":"f899bcc02c1725fc","name":"Battery info RW values","topic":"40354","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40353","quantity":"26","rate":"10","rateUnit":"m","delayOnStart":false,"startDelayTime":"","server":"bcc4229c.180ac","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":160,"y":420,"wires":[["18f4782d041591d2"],[]]},{"id":"ef1f47997f40e6e5","type":"debug","z":"082d1a6d7f9f4ee6","g":"f899bcc02c1725fc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":510,"y":420,"wires":[]},{"id":"18f4782d041591d2","type":"function","z":"082d1a6d7f9f4ee6","g":"f899bcc02c1725fc","name":"RAW to JSON","func":"var data = msg.payload;\nvar raw = {\n    'StorCtl_Mod': data[5],\n    'MinRsvPct': data[7],\n    'OutWRte': data[12],\n    'InWRte': data[13],\n    'InOutWRte_RvrtTms': data[15],\n    'ChaGriSet': data[17],\n}\n\nmsg.payload = {\n    data : data,\n    raw : raw,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":420,"wires":[["ef1f47997f40e6e5"]]},{"id":"bcc4229c.180ac","type":"modbus-client","name":"Fronius","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":false,"tcpHost":"192.168.5.182","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":"200","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true}]

Also this helped me understand how the inverter operates:

0 (normal operation)
1 (bit 1 activates charge limit, bit pattern: 01)
2 (activates discharge limit, bit pattern: 10)
3 (activate both limit values, bit pattern: 11)

2 Likes

I’m trying to charge a Gen24-connected battery, too.
You got me a little left-handed with this post saying to use register 40365. According to the latest Fronius Gen24 docs I downloaded (you warned about getting the latest) 40365 is ChaSt, Charge Status of storage device. Can you please check back ?
But this may be part of the problem: what is the latest register list, and which models does it apply to. I find the Fronius docs to be confusing. Lots of excel tables but no proper explanation of what is what.
(e.g. why is there different tables for float and int+sf ? what do I need to configure to use one or the other ?)

Which registers do I need to set when I want to (dis)charge with xxx watts ?

I’d appreciate if you could do a wrap up of how to force charging and discharging of the battery. Thanks in advance !

Hi @mstormi,

good points.
I hope I can shed some light into this topic. Disclaimer: I must admit that I do not understand why some details in the implementation are different than you might expect them from the documentation - but with more qualified feedback in this forum we might be able to find it out :wink:

You will need the following registers:
Discharge: OutWRte (40366)
Charge: InWRte (40367)
Charge Control: StorCtl_Mod (40359)

Important remark on the addresses:
Because of differences in the modbus implementation - in particular the Modbus Base Adress - you have to apply an address offset of -1 when using HA with the Fronius inverter → Background Information.

Effectively you will need to use the following addresses in HA:
Discharge: OutWRte becomes 40365
Charge: InWRte becomes 40366
Charge Control: StorCtl_Mod becomes 40358

Which registers do I need to set when I want to (dis)charge with xxx watts ?

StorCtl_Mod set to 3 (binary 11) to allow charge + discharge (this should be the default!)
OutWRte set to XXXX (where XXXX is the numeric value of your desired battery output in Watt, e.g. 200 will result in a discharge of 200W and 4500 in a maximum output of 4,5kW - note: depending on the size of your batteries, different scaling factors might apply )

Managing the charge behaviour works similarly.

Giving the concrete value in Watts is a mismatch between the implementation and the documentation, in my opinion.

Hope this helps - if there are further questions, please add them here.

2 Likes

Thanks a lot.
With the -1 offset in mind, this seems to match my excel table for “float”.
Do you also know why that is used and not the int+sf representation - is float the default ?
Or respectively what do I have to configure to be able to use the int+SF representation ?
I’m having trouble to read the values you mention in the first place, getting a Modbus error 4 Slave failure.
I noticed the int+SF representation uses mostly the same registers but the number is 10 lower so I changed there and now I get to read the values. So seems my inverter was “on int+SF”.
That now means I also have to read register 40369 (or 40368, actually) and do the proper *10^x multiplication to obtain the proper value.

I think on wattages, there’s windows defined by yet more parameters than those you listed, that’s possibly why you don’t get exactly what you expect.
So you only used those registers you mentioned but no other ?

And when I’m done force-charging, how do I reset the inverter to standard mode (i.e. charge excess or run from battery if needed) ? I’d guess setting InWRte = OutWRte = 0 will not be the answer as that’s a static value.

You can set the “float” or the “int-SF” in the inverters web interface:

I use float in node-red examples.

storctl_mod = 0 = normal operation
storctl_mod = 1 = discharge
storctl_mod = 2 = charge
storctl_mod = 3 = no charge/discharge (battery not in use)

So I have done the following:

  • Charging EV = storctl_mod 3 Battery disabled and I charge my EV from the Grid
  • Lowest prises 24h = outwrte = 60933, inwrte = 4603, storctl_mod = 2 Charge the battery if the sun have not been able to charge it
  • Highest prices 24h = outwrte = 4603, inwrte = 60933, storctl_mod = 1 Discharge the battery and sell to the grid if I have energy to share
  • When none of these above are active I have sent storctl_mod = 0 putting the battery into normal operation

I have made some setting that suites my home when to charge/discharge etc. that I have not shared above it’s just to give a rough idea what I have configured.

3 Likes

Hi all,

Apparently the node_red/Homeassistant modbus write and flex_write are only allowing for positive (uint) values during the write. I checked the Fronius examples in their documentation (like example 6) and that worked fine when using QModMaster as client. So, the documentation is correct.
Reported a bug for the node red modbus. https://github.com/BiancoRoyal/node-red-contrib-modbus/issues/340

Cheers, Rick

EDIT: Some findings but one remaining question.

In[Out]WRte are actually just percentages to apply to the WChaMax value, register 40356, which is readonly and magically set to some value on my inverter (it’s 7680 W for me and matches my battery’s capacity but that might be coincidence).
So if you want to (dis)charge a specific amount of power you have to do the math first and set In[Out]WRte to <intended value> / WChaMax * 100 * (10^InOutWRteSF).
You need to set both, OutWRte AND InWRte, to the same value (but one of them * (-1)) to instruct a fixed value instead of allowing for a window, and set StorCtlMode to 3 (= bit pattern 11 to have both limits apply).
Attention, even for inverters in float mode (which I have set now), there is a scale factor InOutWRteSF register 40379 that you have to take into account, too. It’s readonly and showing -2 for me.
If you set InWRte or OutWRte to say 200 (%), then it’s overridden to 2 (%) after some seconds (possibly right away but it takes some seconds to read it back again).

I still wonder which register to read to obtain the current (dis)charge power value from/to battery, to validate if what I am instructing the inverter to do is actually happening.
According to your linked post reading_inverter_multiple_raw is reading 88 registers starting @40265.
Comments say #15 and #19 are battery charge+discharge, so minding offset, that would be registers 40281 and 40285, correct ?
40285 according to Fronius docs is MPPT1 Power which is PV input. Fronius says MPPT2 is for storage. That would mean to use 40305, wouldn’t it ?
I have come across Fronius Hybrid with Modbus TCP - loxwiki en - LoxWiki essentially saying there isn’t any such register to directly read and explaining how to compute the charge value, also using 2_DCW. But the values that 2_DCW shows don’t seem to be right. The value for the last string 4_DCW is a possible match. But it’s pure guessing of mine, I have not seen any mentioning in Fronius docs.

Greate thread and thanks @Klangen82 for the Node-Red flows. This acutally allowed me to setup basic battery management in a glance after ModBus had been activated yesterday evening in my Gen24 Inverter.

However, I am searching a possibility to set the Own Consumption Optimisation (Eigenverbrauchs-Optimierung, see screenshot) via Home Assistant/ModBus:

I did not find anything about that in Fronius’ Modbus documentation, neither for the Smart Meter nor for the Inverter, so I assume it can only be changed via the Inverter’s WebInterface - or did I miss something? Thanks!

I did not find anything in the modbus register about controlling this either, sorry that I don’t know the answer how to do this.

Hey guys,

my goal is to disabled battery discharge if I want to load my car by grid. I am using Fronius Symo Gen24 Plus 8.0 and Byd HVS 10.2. My modbus is on int + SF.

I thought about setting “SoC Minimum” to 99 or 100 for car grid charge and if that is finished putting it back to 5.

With the following configuration it works, so the overview page tells that “minimum SoC is reached”. The only thing that confuses me is that the setting within Fronius is not showing it. It stays with old value. Why is that the case?

modbus:
- type: tcp
  host: 192.168.178.5
  port: 502
  name: gen24
  sensors:
    - name: reading_battery_settings
      slave: 1
      count: 24
      address: 40345
      scan_interval: 5
      data_type: custom
      structure: ">10H2h4H8h"

service: modbus.write_register
data:
  slave: 1
  address: 40350
  value: 500
  hub: gen24

service: modbus.write_register
data:
  slave: 1
  address: 40350
  value: 9900
  hub: gen24
1 Like

Solved it with:

#disable battery usage
  - service: modbus.write_register
    data:
      slave: 1
      address: 40348
      value: 2
      hub: gen24
  - service: modbus.write_register
    data:
      slave: 1
      address: 40355
      value: 0
      hub: gen24

#enable battery usage
  - service: modbus.write_register
    data:
      slave: 1
      address: 40355
      value: 10000
      hub: gen24
  - service: modbus.write_register
    data:
      slave: 1
      address: 40348
      value: 0
      hub: gen24
2 Likes

@dm82m I can’t get the same configuration to work on Symo GEN24 10.0 Plus with BYD 11 kWh. It changes the values, and I have contact with it for read/write, but nothing happens - it just keeps on charging even if I change the values you posted. Did you use some debug tool?

Also does anyone know how to reset the Modbus to default values?

Thank you in advance!

just restart the fronius, this will reset all modbus settings to default.

I have a Symo Gen24 10.0 Plus with BYD 10.2. Not used any debug tool. It just showed me a message on the web interface of the Symo within the battery. Cant test it currently as my battery reached minsoc…

1 Like

As you don’t use node-red I can show you what I do to charge, hope it’s clear on the picture. To charge I send on value 4603 to 40366 wait 500ms then send value 60933 to 40365 wait 500ms send value 2 to 40358.


image

If you want normal operation then you send value 0 to 40358

1 Like

Aah, ok, that’s great info!

How do I force the inverter to be on 24/7 then? It seems like it goes in to “Standby” or something and then restarts during night. Yesterday when I tried, it took like 3 minutes for it to boot up, and before that it said “Off” here:

Strange and I don’t know, mine is on 24/7…