Fronius Inverter Primo Gen24 read/write modbus

Hi Guys,

I recently installed some solar panels and battery at home and i want to read all the info from the inverter locally. I have an Fronius Primo Gen24.

I know solar web does a nice job already, but i want to add more logic than is available in de current version. Like when to charge the battery from the grid when for use during the day in winter months.

My modbus is enabled and set to int +sf and with the below i can get the info out of the inverter fine.
But the numbers don't really add up, the register addresses are correct(i think) and i applied some math for the scale factors that the inverter puts out.

But i must be missing something.

For the storage part i read starting register '40343'
To read and set the ''Setpoint for minimum reserve for storage as a percentage of the nominal maximum storage."" register '40350' is used, i can read it ok, but when i write to it the node says write ok, nothing happens on the inverter though...

This is what i currently have:

[{"id":"1f0343ab.fad34c","type":"modbus-read","z":"ae9360b4.811ac","name":"Fronius-Inverter-Solar-Panels","topic":"40253","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40253","quantity":"51","rate":"5","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"bcc4229c.180ac","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":180,"y":160,"wires":[["35bc3165.b07aae"],[]]},{"id":"35bc3165.b07aae","type":"function","z":"ae9360b4.811ac","name":"Calcs","func":"var data = msg.payload;\nvar raw = {\n    'ID' : data[0],\n    'L' : data[1],\n    'DCA_SF' : data[2],\n    'DCV_SF' : data[3],\n    'DCW_SF' : data[4],\n    'DCWH_SF' : data[5],\n    'Evt' : data[6],\n    'N' : data[8],\n    'TmsPer' : data[9],\n    \n    'S1_ID' : data[10],\n    'S1_IDStr' : data[11],\n    'S1_DCA' : data[21],\n    'S1_DCV' : data[22],\n    'S1_DCW' : data[23],\n    'S1_DCWH' : data[24],\n    'S1_Tms' : data[27],\n    'S1_Tmp' : data[28],\n    'S1_DCSt' : data[29],\n    'S1_DCEvt' : data[31],\n    \n    'S2_ID' : data[30],\n    'S2_IDStr' : data[31],\n    'S2_DCA' : data[41],\n    'S2_DCV' : data[42],\n    'S2_DCW' : data[43],\n    'S2_DCWH' : data[44],\n    'S2_Tms' : data[47],\n    'S2_Tmp' : data[48],\n    'S2_DCSt' : data[49],\n    'S2_DCEvt' : data[51],\n}\n\n\n\nfunction toShort(number) {\n  const int16 = new Int16Array(1)\n  int16[0] = number\n  return int16[0]\n}\n\n\nvar VFactor =  toShort(raw.DCV_SF);\nvar AFactor =  toShort(raw.DCA_SF);\nvar WFactor =  toShort(raw.DCW_SF);\nvar WHFactor =  toShort(raw.DCWH_SF);\n\n\n//var VFactor =  0.01;\n//var AFactor =  0.01;\n//var WFactor =  0.01;\n//var WHFactor =  1;\n\nvar result ={\n    'VFactor' :  toShort(raw.DCV_SF),\n    'AFactor' :  toShort(raw.DCA_SF),\n    'WFactor' :  toShort(raw.DCW_SF),\n    'WHFactor' :  toShort(raw.DCWH_SF),\n    \n    'S1_V' : raw.S1_DCV * Math.pow(10, VFactor),\n    'S1_A' : raw.S1_DCA * Math.pow(10, AFactor),\n    'S1_W' : raw.S1_DCW * Math.pow(10, WFactor),\n    'S1_WH' : raw.S1_DCWH * Math.pow(10, WHFactor),\n    'S1_TimeStamp' : raw.S1_Tms,\n    'S1_T' : raw.S1_Tmp,\n    'S1_State' : raw.S1_DCSt,\n    \n    'S2_V' : raw.S2_DCV * Math.pow(10, VFactor),\n    'S2_A' : raw.S2_DCA * Math.pow(10, AFactor),\n    'S2_W' : raw.S2_DCW * Math.pow(10, WFactor),\n    'S2_WH' : raw.S2_DCWH * Math.pow(10, WHFactor),\n    'S2_TimeStamp' : raw.S2_Tms,\n    'S2_T' : raw.S2_Tmp,\n    'S2_State' : raw.S2_DCSt,\n\n}\n\nmsg.payload = {\n    data : data,\n    raw : raw,\n    result : result\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":160,"wires":[["18eb5245.2c7eae","35f6f79c9017f5cf"]]},{"id":"f75cb44.fb98048","type":"ui_gauge","z":"ae9360b4.811ac","name":"UDC1","group":"25b85481.848a7c","order":1,"width":"5","height":"3","gtype":"gage","title":"UDC(1)","label":"V","format":"{{value | number:1}} V","min":0,"max":"1200","colors":["#b30000","#e6e600","#43cb3a"],"seg1":"","seg2":"","className":"","x":790,"y":60,"wires":[]},{"id":"18eb5245.2c7eae","type":"function","z":"ae9360b4.811ac","name":"Split Values","func":"var msg1V = {\n    payload : msg.payload.result.S1_V\n}\n\nvar msg1A = {\n    payload : msg.payload.result.S1_A\n}\n\nvar msg1W = {\n    payload : msg.payload.result.S1_W\n}\n\nvar msg1WH = {\n    payload : msg.payload.result.S1_WH\n}\n\nvar msg1T = {\n    payload : msg.payload.result.S1_T\n}\n\nvar msg1State = {\n    payload : msg.payload.result.S1_State\n}\n\n\n\nvar msg2V = {\n    payload : msg.payload.result.S2_V\n}\n\nvar msg2A = {\n    payload : msg.payload.result.S2_A\n}\n\nvar msg2W = {\n    payload : msg.payload.result.S2_W\n}\n\nvar msg2WH = {\n    payload : msg.payload.result.S2_WH\n}\n\nvar msg2T = {\n    payload : msg.payload.result.S2_T\n}\n\nvar msg2State = {\n    payload : msg.payload.result.S2_State\n}\n\nreturn [ msg1V, msg1A, msg1W, msg1WH, msg1T, msg1State, msg2V, msg2A, msg2W, msg2WH, msg2T, msg2State ];","outputs":12,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":160,"wires":[["f75cb44.fb98048"],["3a6da14c.ce9ace"],["960c4819.a36bc8"],[],[],[],["84823926.b4d598"],["a0fd183c.84c138"],["bde74369.d079e"],[],[],[]]},{"id":"84823926.b4d598","type":"ui_gauge","z":"ae9360b4.811ac","name":"UDC2","group":"25b85481.848a7c","order":2,"width":"5","height":"3","gtype":"gage","title":"UDC(2)","label":"V","format":"{{value | number:1}} V","min":0,"max":"1200","colors":["#b30000","#e6e600","#00b500"],"seg1":"","seg2":"","className":"","x":790,"y":180,"wires":[]},{"id":"3a6da14c.ce9ace","type":"ui_gauge","z":"ae9360b4.811ac","name":"ADC1","group":"25b85481.848a7c","order":3,"width":"5","height":"3","gtype":"gage","title":"ADC(1)","label":"A","format":"{{value | number:2}} A","min":0,"max":"10","colors":["#b30000","#e6e600","#00b500"],"seg1":"","seg2":"","className":"","x":790,"y":100,"wires":[]},{"id":"a0fd183c.84c138","type":"ui_gauge","z":"ae9360b4.811ac","name":"ADC2","group":"25b85481.848a7c","order":4,"width":"5","height":"3","gtype":"gage","title":"ADC(2)","label":"A","format":"{{value | number:2}} A","min":0,"max":"10","colors":["#b30000","#e6e600","#00b500"],"seg1":"","seg2":"","className":"","x":790,"y":220,"wires":[]},{"id":"960c4819.a36bc8","type":"ui_gauge","z":"ae9360b4.811ac","name":"WDC1","group":"25b85481.848a7c","order":5,"width":"5","height":"3","gtype":"gage","title":"WDC(1)","label":"W","format":"{{value | number:1}} W","min":0,"max":"5000","colors":["#b30000","#e6e600","#43cb3a"],"seg1":"","seg2":"","className":"","x":790,"y":140,"wires":[]},{"id":"bde74369.d079e","type":"ui_gauge","z":"ae9360b4.811ac","name":"WDC2","group":"25b85481.848a7c","order":6,"width":"5","height":"3","gtype":"gage","title":"WDC(2)","label":"W","format":"{{value | number:1}} W","min":0,"max":"5000","colors":["#b30000","#e6e600","#00b500"],"seg1":"","seg2":"","className":"","x":790,"y":260,"wires":[]},{"id":"35f6f79c9017f5cf","type":"debug","z":"ae9360b4.811ac","name":"Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":550,"y":360,"wires":[]},{"id":"41f2d75fbd5a41b1","type":"modbus-read","z":"ae9360b4.811ac","name":"Fronius Modbus - Storage","topic":"40343","showStatusActivities":false,"logIOActivities":false,"showErrors":true,"unitid":"1","dataType":"HoldingRegister","adr":"40343","quantity":"26","rate":"5","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"bcc4229c.180ac","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":170,"y":300,"wires":[["8c5c7325d4701062"],[]]},{"id":"8c5c7325d4701062","type":"function","z":"ae9360b4.811ac","name":"Calcs","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\n\nfunction toShort(number) {\n  const int16 = new Int16Array(1)\n  int16[0] = number\n  return int16[0]\n}\n\n\nvar MinRsvPctFactor =  toShort(raw.MinRsvPct_SF);\nvar ChaStateFactor =  toShort(raw.ChaState_SF);\n\n\nvar result ={\n    'Batt_Reserve_Percentage' : raw.MinRsvPct * Math.pow(10, MinRsvPctFactor),\n    'Batt_Charge_State' : raw.ChaState * Math.pow(10, ChaStateFactor),\n}\n\nmsg.payload = {\n    data : data,\n    raw : raw,\n    result : result\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":300,"wires":[["cedc0646fc1965d4","35f6f79c9017f5cf"]]},{"id":"cedc0646fc1965d4","type":"function","z":"ae9360b4.811ac","name":"Split Values","func":"var Batt_Reserve_Percentage = {\n    payload : msg.payload.result.Batt_Reserve_Percentage\n}\n\nvar Batt_Charge_State = {\n    payload : msg.payload.result.Batt_Charge_State\n}\n\n\nreturn [ Batt_Reserve_Percentage, Batt_Charge_State ];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":300,"wires":[["72e07a7e4f7e207d"],["ed23ed1fea21c025"]]},{"id":"72e07a7e4f7e207d","type":"ui_gauge","z":"ae9360b4.811ac","name":"Batt_Reserve_Percentage","group":"25b85481.848a7c","order":7,"width":"5","height":"3","gtype":"gage","title":"Batt_Reserve_Percentage","label":"A","format":"{{value | number:1}} %","min":0,"max":"100","colors":["#b30000","#e6e600","#00b500"],"seg1":"","seg2":"","className":"","x":860,"y":300,"wires":[]},{"id":"ed23ed1fea21c025","type":"ui_gauge","z":"ae9360b4.811ac","name":"Batt_Charge_State","group":"25b85481.848a7c","order":8,"width":"5","height":"3","gtype":"gage","title":"Batt_Charge_State","label":"W","format":"{{value | number:1}} %","min":0,"max":"100","colors":["#b30000","#e6e600","#00b500"],"seg1":"","seg2":"","className":"","x":830,"y":340,"wires":[]},{"id":"bcc4229c.180ac","type":"modbus-client","name":"Fronius","clienttype":"tcp","bufferCommands":false,"stateLogEnabled":true,"queueLogEnabled":true,"tcpHost":"192.168.1.250","tcpPort":"1502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":1,"commandDelay":1,"clientTimeout":5000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":false},{"id":"25b85481.848a7c","type":"ui_group","name":"String 1","tab":"14e13d07.f345c3","order":1,"disp":false,"width":"10","collapse":false,"className":""},{"id":"14e13d07.f345c3","type":"ui_tab","name":"Solar-Detail","icon":"dashboard","disabled":false,"hidden":false}]

To test the write i created this:

[{"id":"70b411fe4edeeb9e","type":"modbus-flex-write","z":"ae9360b4.811ac","d":true,"name":"Fronius-Storage","showStatusActivities":true,"showErrors":true,"server":"bcc4229c.180ac","emptyMsgOnFail":true,"keepMsgProperties":true,"x":680,"y":520,"wires":[[],[]]},{"id":"2f58b8f099c77280","type":"function","z":"ae9360b4.811ac","name":"Set-Storage-Reserve-15%","func":"msg.payload = { \n    value: 1500,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40350,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":480,"wires":[["70b411fe4edeeb9e"]]},{"id":"d3981a099e62ff42","type":"function","z":"ae9360b4.811ac","name":"Set-Storage-Reserve-95%","func":"msg.payload = { \n    value: 9500,\n    'fc': 6,\n    'unitid': 1,\n    'address': 40350,\n    'quantity': 1\n} \n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":560,"wires":[["70b411fe4edeeb9e"]]},{"id":"a798c06c497c9085","type":"inject","z":"ae9360b4.811ac","name":"Set-15%","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"Set-15%","payload":"","payloadType":"date","x":100,"y":440,"wires":[["2f58b8f099c77280"]]},{"id":"f661c8acd21315ed","type":"inject","z":"ae9360b4.811ac","name":"Set-95%","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"Set-95%","payload":"","payloadType":"date","x":100,"y":600,"wires":[["d3981a099e62ff42"]]},{"id":"bcc4229c.180ac","type":"modbus-client","name":"Fronius","clienttype":"tcp","bufferCommands":false,"stateLogEnabled":true,"queueLogEnabled":true,"tcpHost":"192.168.1.250","tcpPort":"1502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":1,"commandDelay":1,"clientTimeout":5000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":false}]

There isn't any error received as far as i can see...

Anyone with experience on this :slight_smile:

Kr,
Pauwel

Hi Pauwel,
No - I have a Gen24 as well (and BYD Battery) - all is fine here.
I just read all registers and then extract what I want over in Home Assistant.
Are you sure you are using the right register Excel spreadsheet from Fronius (for Gen24 Inf&SF_Storage)?
My Battery related registers starts at 40349 (StorCtl_Mod).
Remember to start reading 1 register prior to the one you want (eg. 40348 for StorCtl_Mod).

Hi Peterr,

Yes i think so, the numbers just don't seem to add up or im calculating it wrong ...
Are you using the scale factors at all ?

For the battery part everything looks ok though, well for reading anyway.
Writing to the bus still doesn't seem to work though...

Kr,
Pauwel

Hi again,
I'm using SF when reading and converting data.
Not when writing data to registers.
I'm having issues being able to write negative values (-50%) to eg. OutWRte.
Simply do not know how to do that.
Have you managed that - eg. using "Buffer maker"?
BR.
Peter

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.