Sonnenbatterie with APIv2 / Webhook

Hi Patrick
I’ve managed to creat a configuration in HA that allows me to control the battery. I have 5 main control buttons.

  1. Automatic mode:
    This is the self consumption mode where the battery will charge when there is solar energy and discharge when the house needs energy.
  2. Charge:
    This button will force the battery to charge from solar or grid or both at 3.3 kW (fastest rate) until 100% charged and not discharge.
  3. Discharge:
    This will force the battery to discharges at 3.3 kW (fastest rate) and power the house or feed into the grid or both until flat.
  4. Manual:
    Sit idle and not charge or discharge even when there is solar energy available.
  5. I don’t really use but its the Time of Use mode.

This is all done using http request nodes in Node-Red.

Then I have three automations that:

  1. Charge the battery at 3 am for an hour if the battery is below 20% charge and the amber general rate is “Very Low” (very low is a sensor state from the amber integration for Home Assistant).
    After the hour charging the battery sits in “Manual” or idle mode for two hours until 6 am then switches to ‘Automatic Mode’ when everybody starts to get up to go to work (make coffee and turn on the heaters etc.). This runs Monday to Friday not Saterday or Sunday. This takes advantage of the typical below 20c/kWh rate at 3 AM and discharges between 6:30 until the sun comes up.
  2. Charge the battery at 3:30 pm for an hour if the battery is below 80% charge (cloudy day) then switch to ‘Automatic Mode’ to try to avoid the high tariff in the evening.
  3. Monitor the feed-in price and when it goes above $1 per kWh start discharging the battery at full rate to sell as much eneregy while the price is spiking. this continues until the battery is flat or the price drops below 50c per kWh. This is to make some money as the spikes can go aboe $10 per kWh when the grid is unstable.

I’ve implemented these automations and buttons and curl commands using Node-Red.

The Node-Red flow:

[{"id":"f8c8624c7c9dca94","type":"http request","z":"65840aa926d9c567","name":"Set Charge","method":"POST","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"bearer","senderr":false,"headers":[],"x":1410,"y":400,"wires":[["0e3f0373d7e81e09"]]},{"id":"858d53f8ca9abe53","type":"function","z":"65840aa926d9c567","name":"Charge Setup","func":"msg.headers = {}\nmsg.headers['Auth-Token'] = 'YOUR SONNEN BATTERY AUTH TOKEN'\nmsg.headers [\"Content-Type\"] = \"application/x-www-form-urlencoded\"\nmsg.url = \"http://192.168.99.168:80/api/v2/setpoint/charge/3300\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1240,"y":400,"wires":[["f8c8624c7c9dca94"]]},{"id":"0e3f0373d7e81e09","type":"debug","z":"65840aa926d9c567","name":"debug Charge","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1580,"y":400,"wires":[]},{"id":"05d69d4319a0f5d6","type":"http request","z":"65840aa926d9c567","name":"Set Discharge","method":"POST","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"bearer","senderr":false,"headers":[],"x":1420,"y":280,"wires":[["0e4ea3476743d2c3"]]},{"id":"6151ac699f7381c1","type":"function","z":"65840aa926d9c567","name":"Discharge Setup","func":"msg.headers = {}\nmsg.headers['Auth-Token'] = 'YOUR SONNEN BATTERY AUTH TOKEN'\nmsg.headers [\"Content-Type\"] = \"application/x-www-form-urlencoded\"\nmsg.url = \"http://192.168.99.168:80/api/v2/setpoint/discharge/3300\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1240,"y":280,"wires":[["05d69d4319a0f5d6"]]},{"id":"0e4ea3476743d2c3","type":"debug","z":"65840aa926d9c567","name":"debug discharge","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1600,"y":280,"wires":[]},{"id":"402679171d35e0d2","type":"http request","z":"65840aa926d9c567","name":"Set State","method":"PUT","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"bearer","senderr":false,"headers":[],"x":1360,"y":340,"wires":[["5bd08bcd972153bc"]]},{"id":"9efde64dbc00c864","type":"function","z":"65840aa926d9c567","name":"Manual Mode","func":"msg.payload = \"EM_OperatingMode=1\"\nmsg.headers = {}\nmsg.headers['Auth-Token'] = 'YOUR SONNEN BATTERY AUTH TOKEN'\nmsg.headers [\"Content-Type\"] = \"application/x-www-form-urlencoded\"\nmsg.url = \"http://192.168.99.168:80/api/v2/configurations\" \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1180,"y":340,"wires":[["402679171d35e0d2"]]},{"id":"5bd08bcd972153bc","type":"debug","z":"65840aa926d9c567","name":"debug Manual Mode","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1560,"y":340,"wires":[]},{"id":"10920422f5fa573e","type":"api-call-service","z":"65840aa926d9c567","name":"Switch turn-off Charge","server":"afc27684.cf6ed8","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.sonnen_charge_2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1340,"y":680,"wires":[[]]},{"id":"b66c43b2d71ebcfc","type":"http request","z":"65840aa926d9c567","name":"Set State","method":"PUT","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"bearer","senderr":false,"headers":[],"x":1340,"y":460,"wires":[["1736681453a9e3de"]]},{"id":"49c07dcad21bb88c","type":"function","z":"65840aa926d9c567","name":"Automatic Mode","func":"msg.payload = \"EM_OperatingMode=2\"\nmsg.headers = {}\nmsg.headers['Auth-Token'] = 'YOUR SONNEN BATTERY AUTH TOKEN'\nmsg.headers [\"Content-Type\"] = \"application/x-www-form-urlencoded\"\nmsg.url = \"http://192.168.99.168:80/api/v2/configurations\" \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1160,"y":460,"wires":[["b66c43b2d71ebcfc"]]},{"id":"1736681453a9e3de","type":"debug","z":"65840aa926d9c567","name":"debug Automation Mode","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1550,"y":460,"wires":[]},{"id":"d6e30b460a9ee319","type":"api-call-service","z":"65840aa926d9c567","name":"Switch turn-off Automatic Mode","server":"afc27684.cf6ed8","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.sonnen_automatic_mode"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1370,"y":560,"wires":[[]]},{"id":"163bc3abe14e285d","type":"ha-switch","z":"65840aa926d9c567","name":"Sonnen Charge","version":0,"inputs":1,"outputs":2,"entityConfig":"2d18a92a5ddd4fd8","enableInput":true,"outputOnStateChange":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"str"}],"x":360,"y":520,"wires":[["8f6da85cea51a6c2"],[]]},{"id":"3896b33d87e81de7","type":"ha-switch","z":"65840aa926d9c567","name":"Sonnen Discharge","version":0,"inputs":1,"outputs":2,"entityConfig":"ee18bd169efda9d5","enableInput":true,"outputOnStateChange":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"true","valueType":"bool"}],"x":370,"y":460,"wires":[["c4a70f29ecac9603"],[]]},{"id":"99ea255a2bb6c9fa","type":"ha-switch","z":"65840aa926d9c567","name":"Sonnen Manual Mode","version":0,"inputs":1,"outputs":2,"entityConfig":"15891e5320025a4a","enableInput":true,"outputOnStateChange":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"str"}],"x":380,"y":400,"wires":[["767baa7b0d82b4ca"],[]]},{"id":"594e3b2e22d599e5","type":"ha-switch","z":"65840aa926d9c567","name":"Sonnen Automatic Mode","version":0,"inputs":1,"outputs":2,"entityConfig":"d173cac1c20527d9","enableInput":true,"outputOnStateChange":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"str"}],"x":390,"y":580,"wires":[["53cefbe739be3a2f"],[]]},{"id":"4b6455180cf0d210","type":"delay","z":"65840aa926d9c567","name":"5 sec","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1090,"y":400,"wires":[["858d53f8ca9abe53"]]},{"id":"a0bb98148eb3c453","type":"inject","z":"65840aa926d9c567","name":"03:00 charge","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"00 03 * * 1,2,3,4,5","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":220,"wires":[["72a5a832ce09938f"]]},{"id":"8327524c3f777f5d","type":"api-current-state","z":"65840aa926d9c567","name":"Battery under 20%","server":"afc27684.cf6ed8","version":3,"outputs":2,"halt_if":"20","halt_if_type":"num","halt_if_compare":"lt","entity_id":"sensor.sonnenbatterie_84324_state_charge_user","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":530,"y":220,"wires":[["6f6e5b3310e4f1d9","63ba9e6850f7361b"],[]]},{"id":"6f6e5b3310e4f1d9","type":"delay","z":"65840aa926d9c567","name":"","pauseType":"delay","timeout":"60","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":750,"y":200,"wires":[["b42b8c412b6200e7","31bb16b9d29df719"]]},{"id":"e7b5ec834da03f9f","type":"inject","z":"65840aa926d9c567","name":"15:30 charge","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"30 15 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":80,"wires":[["3622b2c21f2bb0f2"]]},{"id":"87fbdd7138e9d380","type":"api-current-state","z":"65840aa926d9c567","name":"Battery under 80%","server":"afc27684.cf6ed8","version":3,"outputs":2,"halt_if":"80","halt_if_type":"num","halt_if_compare":"lt","entity_id":"sensor.sonnenbatterie_84324_state_charge_user","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":550,"y":80,"wires":[["5993a1a3bf1ef9de","95976ebe7f6655d3"],[]]},{"id":"5993a1a3bf1ef9de","type":"delay","z":"65840aa926d9c567","name":"Charge for 1 hr","pauseType":"delay","timeout":"60","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":740,"y":60,"wires":[["8254f5986525b3a1"]]},{"id":"3622b2c21f2bb0f2","type":"api-current-state","z":"65840aa926d9c567","name":"Very low","server":"afc27684.cf6ed8","version":3,"outputs":2,"halt_if":"very_low","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.cecil_st_general_price_descriptor","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":340,"y":80,"wires":[["87fbdd7138e9d380"],[]]},{"id":"72a5a832ce09938f","type":"api-current-state","z":"65840aa926d9c567","name":"Very low","server":"afc27684.cf6ed8","version":3,"outputs":2,"halt_if":"very_low","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.cecil_st_general_price_descriptor","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":340,"y":220,"wires":[["8327524c3f777f5d"],[]]},{"id":"4e83ea6e880ed707","type":"delay","z":"65840aa926d9c567","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1100,"y":560,"wires":[["d6e30b460a9ee319"]]},{"id":"889022fc881fbb93","type":"delay","z":"65840aa926d9c567","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1100,"y":680,"wires":[["10920422f5fa573e"]]},{"id":"e5c940b48b9cc661","type":"server-state-changed","z":"65840aa926d9c567","name":"Feed-in price","server":"afc27684.cf6ed8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.cecil_st_feed_in_price","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":"","halt_if_type":"num","halt_if_compare":"gt","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"x":130,"y":740,"wires":[["b2f1e3b7259ee6e5"]]},{"id":"b04c5a889c7811e1","type":"api-call-service","z":"65840aa926d9c567","name":"Switch turn-off Manual Mode","server":"afc27684.cf6ed8","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.sonnen_manual_mode_2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1360,"y":620,"wires":[[]]},{"id":"1504b8a31a27f3c0","type":"delay","z":"65840aa926d9c567","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1100,"y":620,"wires":[["b04c5a889c7811e1"]]},{"id":"235f18f61ad60ba6","type":"api-call-service","z":"65840aa926d9c567","name":"Switch turn-off Discharge","server":"afc27684.cf6ed8","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.sonnen_discharge_2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1350,"y":740,"wires":[[]]},{"id":"05cf76adb5e1fce4","type":"delay","z":"65840aa926d9c567","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1100,"y":740,"wires":[["235f18f61ad60ba6"]]},{"id":"79ac18806ae7b257","type":"comment","z":"65840aa926d9c567","name":"FiT Discharge Spike (at $1.00 and nospike at $0.50","info":"","x":310,"y":700,"wires":[]},{"id":"0a3543a03660772a","type":"comment","z":"65840aa926d9c567","name":"Afternoon charge if battery below 80%","info":"","x":402,"y":43,"wires":[]},{"id":"8a366e8d4d842810","type":"comment","z":"65840aa926d9c567","name":"Early Morning charge if battery flat","info":"","x":380,"y":180,"wires":[]},{"id":"75db62f34895127b","type":"time-range-switch","z":"65840aa926d9c567","name":"Early morning 1 to 5:30","lat":"-33.79718416485773","lon":"151.09860994621346","startTime":"01:00","endTime":"05:30","startOffset":0,"endOffset":0,"x":350,"y":300,"wires":[[],[]]},{"id":"089a587a93351529","type":"poll-state","z":"65840aa926d9c567","name":"General price","server":"afc27684.cf6ed8","version":2,"exposeToHomeAssistant":true,"haConfig":[{"property":"name","value":"Norning Charge"},{"property":"icon","value":"mdiTransmissionTower"}],"updateinterval":"60","updateIntervalType":"num","updateIntervalUnits":"seconds","outputinitially":false,"outputonchanged":false,"entity_id":"sensor.cecil_st_general_price","state_type":"str","halt_if":"25","halt_if_type":"num","halt_if_compare":"lt","outputs":2,"x":130,"y":300,"wires":[["75db62f34895127b"],["75db62f34895127b"]]},{"id":"d7480326262afc7a","type":"link out","z":"65840aa926d9c567","name":"link out FiT low","mode":"link","links":["738d28e88d4351bd","f276c6683121c547","fb229ac0227a16b7","d577eb36f0d74d39"],"x":555,"y":780,"wires":[]},{"id":"738d28e88d4351bd","type":"link in","z":"65840aa926d9c567","name":"link in Automatic Mode","links":["d7480326262afc7a","53cefbe739be3a2f","8254f5986525b3a1","87b07b541bba63f6"],"x":995,"y":460,"wires":[["49c07dcad21bb88c"]]},{"id":"214eb49945a0f314","type":"link in","z":"65840aa926d9c567","name":"link in Turn off Automatic Moode Switch","links":["767baa7b0d82b4ca","d9ba6153cfb88bbb","c4a70f29ecac9603","8f6da85cea51a6c2"],"x":995,"y":560,"wires":[["4e83ea6e880ed707"]]},{"id":"f276c6683121c547","type":"link in","z":"65840aa926d9c567","name":"link in Turn off Manual Switch","links":["d7480326262afc7a","53cefbe739be3a2f","c4a70f29ecac9603","8f6da85cea51a6c2"],"x":995,"y":620,"wires":[["1504b8a31a27f3c0"]]},{"id":"fb229ac0227a16b7","type":"link in","z":"65840aa926d9c567","name":"link in Turn off Charge Switch","links":["d7480326262afc7a","53cefbe739be3a2f","d9ba6153cfb88bbb","c4a70f29ecac9603","767baa7b0d82b4ca"],"x":995,"y":680,"wires":[["889022fc881fbb93"]]},{"id":"d577eb36f0d74d39","type":"link in","z":"65840aa926d9c567","name":"link in Turn off Discharge switch","links":["d7480326262afc7a","53cefbe739be3a2f","8f6da85cea51a6c2","767baa7b0d82b4ca"],"x":995,"y":740,"wires":[["05cf76adb5e1fce4"]]},{"id":"53cefbe739be3a2f","type":"link out","z":"65840aa926d9c567","name":"link out Automatic Mode Switch","mode":"link","links":["738d28e88d4351bd","d577eb36f0d74d39","f276c6683121c547","fb229ac0227a16b7"],"x":535,"y":580,"wires":[]},{"id":"93beed478696134e","type":"link in","z":"65840aa926d9c567","name":"link in Charge Setup","links":["8f6da85cea51a6c2","63ba9e6850f7361b","95976ebe7f6655d3"],"x":995,"y":400,"wires":[["4b6455180cf0d210"]]},{"id":"2608790487e879c8","type":"link in","z":"65840aa926d9c567","name":"link in Manual Mode Setup","links":["8f6da85cea51a6c2","c4a70f29ecac9603","767baa7b0d82b4ca","d9ba6153cfb88bbb","63ba9e6850f7361b","95976ebe7f6655d3"],"x":995,"y":340,"wires":[["9efde64dbc00c864"]]},{"id":"5ee73c1f9154912a","type":"link in","z":"65840aa926d9c567","name":"link in Discharge Setup","links":["c4a70f29ecac9603","d9ba6153cfb88bbb"],"x":995,"y":280,"wires":[["174d6cc39f3cf6db"]]},{"id":"8f6da85cea51a6c2","type":"link out","z":"65840aa926d9c567","name":"link out Charge Mode Switch","mode":"link","links":["2608790487e879c8","93beed478696134e","28f35002be45f983","214eb49945a0f314","f276c6683121c547","d577eb36f0d74d39"],"x":535,"y":520,"wires":[]},{"id":"c4a70f29ecac9603","type":"link out","z":"65840aa926d9c567","name":"link out Discharge Mode Switch","mode":"link","links":["5ee73c1f9154912a","2608790487e879c8","214eb49945a0f314","f276c6683121c547","fb229ac0227a16b7"],"x":535,"y":460,"wires":[]},{"id":"174d6cc39f3cf6db","type":"delay","z":"65840aa926d9c567","name":"5 sec","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1090,"y":280,"wires":[["6151ac699f7381c1"]]},{"id":"767baa7b0d82b4ca","type":"link out","z":"65840aa926d9c567","name":"link out Manual Mode Switch","mode":"link","links":["2608790487e879c8","214eb49945a0f314","0fdea619274a2742","fb229ac0227a16b7","d577eb36f0d74d39"],"x":535,"y":400,"wires":[]},{"id":"d9ba6153cfb88bbb","type":"link out","z":"65840aa926d9c567","name":"link out FiT High","mode":"link","links":["5ee73c1f9154912a","2608790487e879c8","214eb49945a0f314","fb229ac0227a16b7"],"x":555,"y":700,"wires":[]},{"id":"63ba9e6850f7361b","type":"link out","z":"65840aa926d9c567","name":"link out Morning Charge On","mode":"link","links":["2608790487e879c8","93beed478696134e","28f35002be45f983"],"x":685,"y":320,"wires":[]},{"id":"b42b8c412b6200e7","type":"link out","z":"65840aa926d9c567","name":"link out Morning Charge Off","mode":"link","links":["0fdea619274a2742"],"x":905,"y":200,"wires":[]},{"id":"95976ebe7f6655d3","type":"link out","z":"65840aa926d9c567","name":"link out Evening charge On","mode":"link","links":["2608790487e879c8","93beed478696134e","28f35002be45f983"],"x":725,"y":120,"wires":[]},{"id":"8254f5986525b3a1","type":"link out","z":"65840aa926d9c567","name":"link out Evening Charge Off","mode":"link","links":["738d28e88d4351bd"],"x":875,"y":120,"wires":[]},{"id":"b2f1e3b7259ee6e5","type":"dsm","z":"65840aa926d9c567","name":"hysteresis","sm_config":"{\n    \"currentState\": \"undefined\",\n    \"states\": {\n        \"undefined\": {\n            \"cross_high\": \"high\",\n            \"cross_low\": \"low\",\n            \"inter\": \"deadband\"\n        },\n        \"high\": {\n            \"cross_low\": \"low\",\n            \"inter\": \"deadband\"\n        },\n        \"low\": {\n            \"cross_high\": \"high\",\n            \"inter\": \"deadband\"\n        },\n        \"deadband\": {\n            \"cross_high\": \"high\",\n            \"cross_low\": \"low\"\n        }\n    },\n    \"data\": {\n        \"setpoint_high\": 1.0,\n        \"setpoint_low\": 0.5,\n        \"greater_high\": \"on\",\n        \"less_low\":  \"off\"\n    },\n    \"methods\": {\n        \"setpoint_high\": {\n            \"name\": \"setData\"\n        },\n        \"setpoint_low\": {\n            \"name\": \"setData\"\n        },\n        \"onBeforeTransition\": [\n            \"if (!msg.topic) msg.topic = 'evaluade';\"\n        ],\n        \"evaluade\": [\n            \"if(msg.payload > sm.data.setpoint_high)\",\n            \"   resume('cross_high', msg);\",\n            \"else if (msg.payload < sm.data.setpoint_low)\",\n            \"   resume('cross_low', msg);\",\n            \"else {\",\n            \"   resume('inter', msg);\",\n            \"}\",\n            \"output = false;\"\n        ],\n        \"cross_high\": [\n            \"msg.payload = sm.data.greater_high;\",\n            \"sm.fill = 'yellow';\"\n        ],\n        \"cross_low\": [\n            \"msg.payload = sm.data.less_low;\",\n            \"sm.fill = 'green';\"\n        ],\n        \"inter\": [\n            \"sm.fill = 'grey';\",\n            \"output = false;\"\n        ],\n        \"status\": {\n            \"fill\": {\n                \"get\": \"sm.fill;\"\n            },\n            \"shape\": \"dot\",\n            \"text\": {\n                \"get\": \"sm.currentState;\"\n            }\n        }\n    }\n}","x":290,"y":740,"wires":[["7618c2e9822bf2fc"]]},{"id":"7618c2e9822bf2fc","type":"switch","z":"65840aa926d9c567","name":"on/off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":740,"wires":[["d9ba6153cfb88bbb","be2066935f32d614"],["d7480326262afc7a"]]},{"id":"be2066935f32d614","type":"api-call-service","z":"65840aa926d9c567","name":"Notify Robet's iPhones","server":"afc27684.cf6ed8","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_robsiphone","areaId":[],"deviceId":[],"entityId":[],"data":"{\"title\":\"FiT Spike\",\"message\":\"FiT price had breached $1\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":669.2578125,"y":739.26171875,"wires":[[]]},{"id":"71b6831a8862dc59","type":"http request","z":"65840aa926d9c567","name":"Set Charge","method":"POST","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"bearer","senderr":false,"headers":[],"x":1450,"y":220,"wires":[["0463b2679edf6145"]]},{"id":"0a139a31c1ecd269","type":"function","z":"65840aa926d9c567","name":"100W Charge Setup","func":"msg.headers = {}\nmsg.headers['Auth-Token'] = 'YOUR SONNEN BATTERY AUTH TOKEN'\nmsg.headers [\"Content-Type\"] = \"application/x-www-form-urlencoded\"\nmsg.url = \"http://192.168.99.168:80/api/v2/setpoint/charge/100\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1260,"y":220,"wires":[["71b6831a8862dc59"]]},{"id":"0463b2679edf6145","type":"debug","z":"65840aa926d9c567","name":"debug 100W Charge","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1640,"y":220,"wires":[]},{"id":"3838e81fb4788165","type":"inject","z":"65840aa926d9c567","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1060,"y":180,"wires":[["0a139a31c1ecd269"]]},{"id":"0e54ad505c3c0b16","type":"delay","z":"65840aa926d9c567","name":"5 sec","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1090,"y":220,"wires":[["0a139a31c1ecd269"]]},{"id":"0fdea619274a2742","type":"link in","z":"65840aa926d9c567","name":"link in 0 charge","links":["767baa7b0d82b4ca","b42b8c412b6200e7"],"x":995,"y":220,"wires":[["0e54ad505c3c0b16"]]},{"id":"31bb16b9d29df719","type":"delay","z":"65840aa926d9c567","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"hours","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":760,"y":260,"wires":[["87b07b541bba63f6"]]},{"id":"87b07b541bba63f6","type":"link out","z":"65840aa926d9c567","name":"link out first coffee","mode":"link","links":["738d28e88d4351bd"],"x":905,"y":260,"wires":[]},{"id":"afc27684.cf6ed8","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true},{"id":"2d18a92a5ddd4fd8","type":"ha-entity-config","server":"afc27684.cf6ed8","deviceConfig":"","name":"switch config for Sonnen Charge","version":"6","entityType":"switch","haConfig":[{"property":"name","value":"Sonnen Charge"},{"property":"icon","value":"mdi:battery-plus-outline"},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""}],"resend":true,"debugEnabled":false},{"id":"ee18bd169efda9d5","type":"ha-entity-config","server":"afc27684.cf6ed8","deviceConfig":"","name":"switch config for Sonnen Discharge","version":"6","entityType":"switch","haConfig":[{"property":"name","value":"Sonnen Discharge"},{"property":"icon","value":"mdi:battery-minus-outline"},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""}],"resend":true,"debugEnabled":false},{"id":"15891e5320025a4a","type":"ha-entity-config","server":"afc27684.cf6ed8","deviceConfig":"","name":"switch config for Sonnen Manual Mode","version":"6","entityType":"switch","haConfig":[{"property":"name","value":"Sonnen Manual Mode"},{"property":"icon","value":"mdi:car-shift-pattern"},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""}],"resend":true,"debugEnabled":false},{"id":"d173cac1c20527d9","type":"ha-entity-config","server":"afc27684.cf6ed8","deviceConfig":"","name":"switch config for Sonnen Automatic Mode test","version":"6","entityType":"switch","haConfig":[{"property":"name","value":"Sonnen Automatic Mode"},{"property":"icon","value":"mdi:refresh-auto"},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""}],"resend":true,"debugEnabled":false}]

So these three automations are very simple and are the rules base controls that one would implemet to start with. But the more difficult control system to implement is one that uses the forecasts that amber give you and solar forecasts that you can get from solcast and the like.

@davidusb has developes a system that does this. You can read about it here. I’m trying to implement that now.

2 Likes

So now I have this EMHASS system producing a power schedule. Just got to figure out how best to trigger automations with it.


The P_deferrable0 and P_deferrable1 are two deferrable loads I can move around. One is the pool pump and the other is the dish washer. I’m planning to add two more meing the cloths dryer and washer and the Telsa car charging. Haven’t set them up yet but the system should be able to suggest best time to implmenet them.
The other thing I want to get out of this system is the best time to charge and discharge with the forecast FiT from amber and forecast sun from solcast.

Yep, that will add a schedule to ToU, but then it will stay there even if you switch modes. This is fine for the standard 23:30-05:30 low tariff window, but there can be other times when a low tariff window will be provided based on wholesale prices. So if I set 14:30-15:30 one day, that slot might not be at a low tariff the next day. I haven’t figured out a way to clear a schedule via the API, only by logging into the dashboard, so I can’t automate that.

Maybe it would be better to just use manual mode for the variable cheap time slots, assuming that any solar generated at the time would go to the car anyway…

Robert,
thanks for the info. I have been following the emhass project and specifically Mark Purcell’s additional information. I need to look more closely at this. I do have a simple question first though - where do you find the commands to be able to control your Sonnen? I have the sonnenbatterie integration and can see app 50 sensor inputs. I read that you use json commands?
Pat

Libby
Yes, if you want to change the schedule all the time to chase variable rates then the best way is to ignore the ToU setting and switch between Automatic and Manual modes and while in Manual command the system to charge and discharge or sit idle according to the rate changes, if you have that rate data.

When in Automatic the battery will manage itself and charge from the PV system and discharge to loads in the house. This is the normal operating mode.

When in Manual you get to choose between three states.

  1. Idle, no charging or discharging. This is the state the battery goes into when first switched to manual.
  2. Charge at whatever Wattage you choose. This is a configuration you can apply while in Manual mode. I just charge at the full rate the battery can take which is 3.3 kW for my battery. While charging, it does not supply any power to anything.
  3. Discharge at whatever Wattage you choose. Again, this is a config you can apply while in Manual mode. I just discharge at 3.3.

Then you need the current rate data from your supplier to trigger these states. I don’t know where you are in the world so can’t help with that. But here in Australia my provider is Amber Electric. They are different to most electricity retailers in that they expose their customers to a wholesale rate to buy and sell electricity on the grid. So, the rates are changing all the time. There’s an example of a spike last week:


You can see the buy price has hit $15.28/kWh at 17:02. The sell price at this point was $13.76/kWh.

So my node-red automation triggered a discharge by first switching to Manual mode and then 5 seconds after, commanding the battery to discharge at the fastest rate possible being 3.3kW and then sends a message to my phone to let me know a spike is on, (and I run around the house turing everything off, annoying everybody like an old tight arsed granddad), to make as much money as I can while the spike is on:

They also provide forecast data as well which helps with the EMHASS system.

I have installed the amber integration in Home Assistant which gives me 8 sensors.

1 Like

Pat
There’s not much documentation on it. I found the commands by logging into the battery. The user account is all you need. If you have the same type of battery as me (eco 9.43 with version 2 firmware) then the user password would be sonnenUser3552.


Then under Software-Integration

Then under sonnenbattery JSON API V2 documentation

Much more on this at Sonnenbatterie with APIv2 / Webhook thanks to @julianlu

As said by Robert just a few documentation and Sonnen is not very collaborative on this.

This is what I’m planning to do (moving a bit slowly and still to fully test the commands, but I was able to switch from automatic to manual mode and viceversa)

In configuration.yaml:

## Shell commands
shell_command:
  # Definition of shell commands to invoke API endpoints for Sonnen batteries
  set_operating_mode_sonnen_battery: curl -X PUT -d EM_OperatingMode={{ operating_mode }} --header 'Auth-Token{{':'}} {{ token }}' {{ api_endpoint }}
  dis_charge_sonnen_battery: curl -d -H -X POST --header 'Auth-Token{{':'}} {{ token }}' {{ api_endpoint }}/{{dis_charge_command}}/{{ dis_charge_value }}

And then in an automation.yaml file (keep in mind this would not work if you create the automation through the UI - the !secrets are replaced when the automation gets loaded by HA)

- id: 'sonnen_8_manual_operating_mode'
  alias: "Sonnen 8 manual operating mode"
  description: "Imposta la Sonnen 8 in modalità manuale così che la carica/scarica possa comandata via API"
  trigger: []
  condition: []
  action:
    - service: shell_command.set_operating_mode_sonnen_battery
      data:
        operating_mode: 1
        token: !secret sonnen_8_api_token
        api_endpoint: !secret sonnen_8_configurations_api_endpoint
  mode: single

These two pieces of code together build the final command (I tested via PC terminal), for example to put the battery into Manual mode:

curl -X PUT -d EM_OperatingMode=1 --header 'Auth-Token: xxxxxxxxxxxx' http://192.xxx.xxx.xxx/api/v2/configurations

Thanks for sharing the EMHASS project, I’ll have a look.
At the moment I’m thinking to switch to manual mode and charge during the off-peak time with cheapest rates when the remaining capacity plus the forecasted production can’t cover tomorrow’s forecasted energy needs (median over the past 8 days) and then stop when I reach this equivalence.
The fact is that I should be able to dynamically adapt the charge power depending on the consumption (heating may start at night in winter and I don’t want to exceed the max allowed contractual power) and on how close I am to the end of the off-peak time-window.
I know, quite complex (probably I have to accept compromises), but maybe this project will give some ideas!

The benefit of EMHASS is that it makes available several methods for analysing all the forecasts and history (sun, supply costs, feed-in tariff, load history, current battery charge etc) and come up with a plan or schedule for charging and discharging, switching deferrable loads on and off (hot water, pool pumps, car chargers etc) to take advantage of the crests and troughs of supply cost and FiT profit.
The most accurate and most difficult to configure is Model Predictive Control MPC, a control model that continuously reanalyses the data to adjust the schedules (every 5 minutes or 1 min or 30 sec whatever you want). EMHASS has other models as well such as linier, that are more rudimentary and simpler to implement.
Graphic representation of today’s schedule (which still isn’t right as I haven’t got the PV data working correclty):


So I use the Batt Forecast (green) to charge and discharge the battery. I use the amplitude of the curve (in Watts) in the POST to the sonnen API to drive the battery.

Negative Batt Forecast or say -3300W means charge the battery at 3300 Watts, positive discharge.

The Pool (purple) is used to switch the pool pump on and off (simple switch on and off no control over wattage as it’s a constant 1500W pump). Yet to add the car charger but it would be a variable load.

1 Like

EMHASS config for sonnen v2

1 Like

Rob
This looks really promising. Thanks for your time in putting it together.
Now I have no excuses for not diving in deep. I’ll no doubt be in touch when I stuff something up.
Pat

1 Like

Good knowledge on the subject here:

1 Like

Thanks for this! Will have to see if I can get it working with Octopus Energy. :+1:

Edit: I think EMHASS might be a bit much for my Pi3. So I’ve turned it off for now and ordered a Pi4. :smiley:

1 Like

Hi rcruikshank,

I would like to have the configuration for the 5 buttons for controlling the solar battery. Unfortunately I can’t read what I need to do to implement this. I currently have the addon from GitHub - weltmeyer/ha_sonnenbatterie: Homeassistant integration to show many stats of Sonnenbatterie Weltmeyer in HA and the Sonnenbatterie with APIv2 / Webhook in the configuration.yaml from the first post. I don’t have Node-Red, my HA runs on Raspi, but I would like to automate battery charging depending on the expected solar output.
Kind Regards

My settings are documented here section 6.1.4. But this document is based on node-red and describes how to get EMHASS set up.

If you don’t want to use Node-Red then you can implement the REST API commands for the battery using rest_command in configuration.yaml.

If you look at section 7 HTTP Request Nodes for REST API calls. For example to put the battery into manual mode:

msg.payload = "EM_OperatingMode=1" 
msg.headers = {} 
msg.headers['Auth-Token'] = 'YOUR SONNEN API TOKEN' 
msg.headers ["Content-Type"] = "application/x-www-form-urlencoded" 
msg.url = "http://YOUR BATTERY IP ADDRESS:80/api/v2/configurations"

These are the elements in the Node-Red Function Node for REST API call for manual mode. Translate them into a rest_command in yaml.

rest_command:
  sonnen_manual_mode:
    url: http://YOUR BATTERY IP ADDRESS:80/api/v2/configurations
    method: PUT
    headers:
      authorization: your sonnen API Token
    content_type: 'application/x-www-form-urlencoded'
    payload: 'EM_OperatingMode=1' 

Or something like this.

1 Like

Thank you very much for your explanation, I will try to implement it that way.

If I set to manual mode and charge rate 7000 (sb performance 10) with start charging via rest command, the SB stop charging after 30 - 45 sec? and go back to automatic? do you have a glue why?

I can only say that I notice that my battery will start to wane after being held at maximum charge or discharge.

Did you try to ask clarifications for this behaviour to the tech service?
Can you share what they replied?