[{"id":"63f58601642903de","type":"group","z":"ac86d42a29852803","name":"Determine room temperature","style":{"label":true,"fill":"#d1d1d1"},"nodes":["071fd378027c2a1c","86eaf8ad791419d7","8a24b55b79985c68","3147ab1f956d046c"],"x":734,"y":731.5,"w":662,"h":97},{"id":"071fd378027c2a1c","type":"ps-strategy-heat-capacitor","z":"ac86d42a29852803","g":"63f58601642903de","name":"Determine room temperature","timeHeat1C":"240","timeCool1C":"240","maxTempAdjustment":"0.4","boostTempHeat":"0.5","boostTempCool":"0.7","minSavings":"0.03","setpoint":"19.5","x":940,"y":780,"wires":[["86eaf8ad791419d7"],[],[]]},{"id":"86eaf8ad791419d7","type":"switch","z":"ac86d42a29852803","g":"63f58601642903de","name":"Filter outliers","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"10","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1230,"y":780,"wires":[["8a24b55b79985c68"],[]]},{"id":"8a24b55b79985c68","type":"link out","z":"ac86d42a29852803","g":"63f58601642903de","name":"Set room setpoint","mode":"link","links":["9a106cdefc873348"],"x":1355,"y":780,"wires":[]},{"id":"3147ab1f956d046c","type":"link in","z":"ac86d42a29852803","g":"63f58601642903de","name":"link in 62","links":["67fd7b3293b538cf"],"x":775,"y":780,"wires":[["071fd378027c2a1c"]]},{"id":"52933b5a502cf15d","type":"group","z":"ac86d42a29852803","name":"Get energy prices (decide on which one)","style":{"fill":"#bfc7d7","label":true},"nodes":["77d28a94767686f8","b27c143c7bfe97c7","23eb119f465c18a9","7e108813b76d59f0","8cf9e190b6100f7f","018ecd8886088f24","45e17cbe17e8860d","1f6a2e12ad0d961b","ebe54f29705ee6c4","60f20f0668304c0d","67fd7b3293b538cf","c5e0cbd18ab76b66"],"x":194,"y":339,"w":1212,"h":322},{"id":"77d28a94767686f8","type":"function","z":"ac86d42a29852803","d":true,"g":"52933b5a502cf15d","name":"Prep for Powersaver nodes","func":"const nordpool = msg.payload;\n\nfunction toIsoString(date) {\n var tzo = -date.getTimezoneOffset(), dif = tzo >= 0 ? \"+\" : \"-\",\n pad = function (num) {\n return (num < 10 ? \"0\" : \"\") + num;\n };\n\n return (\n date.getFullYear() + \"-\" +\n pad(date.getMonth() + 1) + \"-\" +\n pad(date.getDate()) + \"T\" +\n pad(date.getHours()) + \":\" +\n pad(date.getMinutes()) + \":\" +\n pad(date.getSeconds()) + dif +\n pad(Math.floor(Math.abs(tzo) / 60)) + \":\" +\n pad(Math.abs(tzo) % 60)\n );\n}\n\nconst payload = {\n priceData: nordpool.map((h) => {\n const date = new Date(h.timestamp);\n const start = toIsoString(date);\n const value = Math.round(h.price * 10) / 10000;\n\n return {\n start,\n value,\n };\n }),\n};\n\nreturn { payload };","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":560,"wires":[["67fd7b3293b538cf"]]},{"id":"b27c143c7bfe97c7","type":"nordpool-api-plus","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"Nordpool - tomorrow","area":"NL","currency":"EUR","action":"dayAhead","x":520,"y":620,"wires":[["77d28a94767686f8"]]},{"id":"23eb119f465c18a9","type":"inject","z":"ac86d42a29852803","d":true,"g":"52933b5a502cf15d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"23 14 * * *","once":true,"onceDelay":"20","topic":"","payload":"","payloadType":"date","x":310,"y":620,"wires":[["b27c143c7bfe97c7"]]},{"id":"7e108813b76d59f0","type":"nordpool-api-plus","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"Nordpool - today","area":"NL","currency":"EUR","action":"dayAhead","x":510,"y":560,"wires":[["77d28a94767686f8"]]},{"id":"8cf9e190b6100f7f","type":"inject","z":"ac86d42a29852803","d":true,"g":"52933b5a502cf15d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"","payloadType":"date","x":310,"y":560,"wires":[["7e108813b76d59f0"]]},{"id":"018ecd8886088f24","type":"ps-receive-price","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"Price Receiver","x":1040,"y":480,"wires":[["67fd7b3293b538cf"]]},{"id":"45e17cbe17e8860d","type":"api-current-state","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.nordpool","state_type":"num","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":770,"y":480,"wires":[["018ecd8886088f24","1f6a2e12ad0d961b"]]},{"id":"1f6a2e12ad0d961b","type":"function","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"Prep for Influx","func":"msg.payload = parseFloat(msg.payload);\nmsg.topic = \"hourly_price\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1040,"y":380,"wires":[["ebe54f29705ee6c4"]]},{"id":"ebe54f29705ee6c4","type":"influxdb out","z":"ac86d42a29852803","g":"52933b5a502cf15d","influxdb":"","name":"Log energy price","measurement":"energy_price","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"s","retentionPolicyV18Flux":"","org":"test","bucket":"x","x":1290,"y":380,"wires":[]},{"id":"60f20f0668304c0d","type":"cronplus","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"","outputField":"payload","timeZone":"Europe/Amsterdam","storeName":"memoryOnly","commandResponseMsgOutput":"output1","defaultLocation":"","defaultLocationType":"default","outputs":1,"options":[{"name":"schedule1","topic":"topic1","payloadType":"bool","payload":"true","expressionType":"cron","expression":"30 1 * * * ? *","location":"","offset":"0","solarType":"all","solarEvents":"sunrise,sunset"}],"x":400,"y":480,"wires":[["45e17cbe17e8860d"]]},{"id":"67fd7b3293b538cf","type":"link out","z":"ac86d42a29852803","g":"52933b5a502cf15d","name":"link out 62","mode":"link","links":["d1e5026a16dbc676","3147ab1f956d046c","161227f39fcbc429","1c054137d0201081","5e57908d7ea0be44","b2d8d3c2cff86243"],"x":1205,"y":540,"wires":[]},{"id":"c5e0cbd18ab76b66","type":"inject","z":"ac86d42a29852803","d":true,"g":"52933b5a502cf15d","name":"Replan when restarted nodes","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"60","topic":"","payload":"{\"commands\":{\"replan\":true}}","payloadType":"json","x":980,"y":620,"wires":[["67fd7b3293b538cf"]]},{"id":"1b8443f3a2fbced4","type":"group","z":"ac86d42a29852803","name":"Determine sterilisation scheme","style":{"fill":"#ffbfbf","label":true},"nodes":["b661b0da22d60992","230cbd34c03550c8","fb60cc084377388f","6cf298fc9c936de6","4ac4a4131a6a8465","ea2a1e3399a58c98","3cd1a1bc9111c34d","cc2c987231bf3a2d","161227f39fcbc429","1c054137d0201081","64ca8a80f8111a29"],"x":194,"y":919,"w":1222,"h":189.5},{"id":"b661b0da22d60992","type":"ps-strategy-lowest-price","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"Sterilisation lowest price ","fromTime":"00","toTime":"00","hoursOn":"2","maxPrice":"","doNotSplit":true,"sendCurrentValueWhenRescheduling":true,"outputValueForOn":"true","outputValueForOff":"false","outputValueForOntype":"bool","outputValueForOfftype":"bool","outputIfNoSchedule":"false","outputOutsidePeriod":"false","contextStorage":"memoryOnly","x":390,"y":980,"wires":[[],[],["230cbd34c03550c8"]]},{"id":"230cbd34c03550c8","type":"ps-schedule-merger","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"Merge day and time for sterilisation","outputIfNoSchedule":"false","logicFunction":"AND","schedulingDelay":"1000","sendCurrentValueWhenRescheduling":true,"outputValueForOn":"true","outputValueForOff":"false","outputValueForOntype":"bool","outputValueForOfftype":"bool","x":700,"y":980,"wires":[["ea2a1e3399a58c98","cc2c987231bf3a2d"],[],["64ca8a80f8111a29"]]},{"id":"fb60cc084377388f","type":"ps-strategy-fixed-schedule","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"Sterilisation day","periods":[{"start":"00","value":"true"}],"validFrom":"","validTo":"","days":{"Mon":false,"Tue":true,"Wed":false,"Thu":false,"Fri":false,"Sat":false,"Sun":false},"sendCurrentValueWhenRescheduling":true,"outputValueForOn":"true","outputValueForOff":"false","outputValueForOntype":"bool","outputValueForOfftype":"bool","outputIfNoSchedule":"false","contextStorage":"memoryOnly","x":420,"y":1060,"wires":[[],[],["230cbd34c03550c8"]]},{"id":"6cf298fc9c936de6","type":"link out","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"link out 39","mode":"link","links":["d0fda364deccc7f0"],"x":1375,"y":960,"wires":[]},{"id":"4ac4a4131a6a8465","type":"change","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"Prep for Sterilization planner","rules":[{"t":"set","p":"topic","pt":"msg","to":"Sterilization","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1190,"y":960,"wires":[["6cf298fc9c936de6"]]},{"id":"ea2a1e3399a58c98","type":"function","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"Turn heatpump on if necessary","func":"var HP_state = global.get('TOP0_Heatpump_State', \"file\"); // get the current state of the heatpump. Is it on or off.\n////////////////////////////////////////////////////////////////\nif ((HP_state == 0)) // check if the override state is enabled, AND currently heatpump state is off \n{\n msg = { payload: 1, topic: \"override\" };\n};\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1200,"y":1000,"wires":[["3cd1a1bc9111c34d"]]},{"id":"3cd1a1bc9111c34d","type":"link out","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"Power on Planning","mode":"link","links":["071ac5a0f08a8fdb","d9b3ca8bfaa4c10a"],"x":1375,"y":1000,"wires":[]},{"id":"cc2c987231bf3a2d","type":"delay","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"","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":995,"y":960,"wires":[["4ac4a4131a6a8465"]],"l":false},{"id":"161227f39fcbc429","type":"link in","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"link in 63","links":["67fd7b3293b538cf"],"x":235,"y":980,"wires":[["b661b0da22d60992"]]},{"id":"1c054137d0201081","type":"link in","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"link in 64","links":["67fd7b3293b538cf"],"x":285,"y":1060,"wires":[["fb60cc084377388f"]]},{"id":"64ca8a80f8111a29","type":"link out","z":"ac86d42a29852803","g":"1b8443f3a2fbced4","name":"link out 63","mode":"link","links":["b0897fa49e0b6e73"],"x":915,"y":1000,"wires":[]},{"id":"628b23cdd7529b06","type":"group","z":"ac86d42a29852803","name":"Determine DHW strategy","style":{"fill":"#bfdbef","label":true},"nodes":["a0d088fca91b26b4","8446dc090c0347fc","da7e68fd39fd25f2","f4b11920a2bc19b7","894b093e7020e766","7406ef2f61d0906a","eba8c63b733501c2","3ee6946a57749651","c567a1a68c52ad51","b248caed16a3e771","2a8c3c20cd9b4ff7","5e57908d7ea0be44","16428e63b0053db5"],"x":194,"y":1139,"w":1272,"h":182},{"id":"a0d088fca91b26b4","type":"ps-strategy-lowest-price","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Lowest Price","fromTime":"18","toTime":"06","hoursOn":"1","maxPrice":"","doNotSplit":true,"sendCurrentValueWhenRescheduling":true,"outputValueForOn":"true","outputValueForOff":"false","outputValueForOntype":"bool","outputValueForOfftype":"bool","outputIfNoSchedule":"false","outputOutsidePeriod":"false","contextStorage":"memoryOnly","x":930,"y":1240,"wires":[["eba8c63b733501c2","c567a1a68c52ad51"],["2a8c3c20cd9b4ff7"],["16428e63b0053db5"]]},{"id":"8446dc090c0347fc","type":"function","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Determine DHW strategy ","func":"const DHWTemp = msg.payload\nconst date = new Date();\nconst hour = date.getHours();\nconst TargetTemp = global.get('TOP9_DHW_Target_Temp','file')\nconst heatdelta = global.get('TOP22_DHW_Heat_Delta', 'file');\nconst delta = TargetTemp - DHWTemp + heatdelta;\n\nif(hour >= 6 && hour <18){\n var toTime = 18\n}\nelse {\n var toTime = 6\n};\n\nif (delta > 0) {\n const config = {\n \"name\": \"Lowest Price\",\n \"config\": {\n \"fromTime\": hour,\n \"toTime\": toTime,\n \"hoursOn\": 1,\n \"override\": \"auto\"\n }\n };\n\nmsg.payload = config;\n}\nelse \n\n{ const config = {\n \"name\": \"Lowest Price\",\n \"config\": {\n \"fromTime\": hour,\n \"toTime\": toTime,\n \"hoursOn\": 0,\n \"override\": \"off\"\n }\n};\n\nmsg.payload = config};\n\n// msg.payload = context.data.DHW_Target_Temp\n\nreturn msg; \n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":1240,"wires":[["a0d088fca91b26b4"]]},{"id":"da7e68fd39fd25f2","type":"mqtt in","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"DHWTemp","topic":"panasonic_heat_pump/main/DHW_Temp","qos":"2","datatype":"auto-detect","broker":"accae33c.753638","nl":false,"rap":true,"rh":0,"inputs":0,"x":280,"y":1240,"wires":[["f4b11920a2bc19b7"]]},{"id":"f4b11920a2bc19b7","type":"rbe","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":430,"y":1240,"wires":[["8446dc090c0347fc"]]},{"id":"894b093e7020e766","type":"link out","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Force DHW","mode":"link","links":["ef28d0205d50cb26"],"x":1425,"y":1180,"wires":[]},{"id":"7406ef2f61d0906a","type":"change","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Prep for force DHW ","rules":[{"t":"set","p":"topic","pt":"msg","to":"DHW","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":1180,"wires":[["894b093e7020e766"]]},{"id":"eba8c63b733501c2","type":"function","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Turn heatpump on if necessary","func":"var HP_state = global.get('TOP0_Heatpump_State', \"file\"); // get the current state of the heatpump. Is it on or off.\n////////////////////////////////////////////////////////////////\nif ((HP_state == 0)) // check if the override state is enabled, AND currently heatpump state is off \n{\n msg = { payload: 1, topic: \"override\" };\n};\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1240,"y":1220,"wires":[["3ee6946a57749651"]]},{"id":"3ee6946a57749651","type":"link out","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Power on Planning","mode":"link","links":["071ac5a0f08a8fdb","d9b3ca8bfaa4c10a"],"x":1425,"y":1220,"wires":[]},{"id":"c567a1a68c52ad51","type":"delay","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"","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":1025,"y":1180,"wires":[["7406ef2f61d0906a"]],"l":false},{"id":"b248caed16a3e771","type":"link out","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Power on Planning","mode":"link","links":["071ac5a0f08a8fdb","d9b3ca8bfaa4c10a"],"x":1425,"y":1260,"wires":[]},{"id":"2a8c3c20cd9b4ff7","type":"function","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"Turn heatpump off if possible","func":"var Operating_state = global.get('TOP4_Operating_Mode_State', \"file\"); // get the current state of the heatpump. Is it on or off.\nvar Pump_Flow = global.get('TOP1_Pump_Flow', \"memoryOnly\")\n////////////////////////////////////////////////////////////////\nif ((Operating_state == 3 && Pump_Flow < 1)) // check if only DHW is enabled \n{\n msg = { payload: 0, topic: \"override\" };\n};\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1230,"y":1260,"wires":[["b248caed16a3e771"]]},{"id":"5e57908d7ea0be44","type":"link in","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"link in 65","links":["67fd7b3293b538cf"],"x":805,"y":1220,"wires":[["a0d088fca91b26b4"]]},{"id":"16428e63b0053db5","type":"link out","z":"ac86d42a29852803","g":"628b23cdd7529b06","name":"link out 64","mode":"link","links":["b0897fa49e0b6e73"],"x":1045,"y":1280,"wires":[]},{"id":"accae33c.753638","type":"mqtt-broker","name":"MQTT","broker":"x.x.x.x","port":"1883","clientid":"node-red","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"5","keepalive":"60","cleansession":false,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"608a7292e1808e4d","type":"group","z":"ac86d42a29852803","name":"Visualisation for HA (opt)","style":{"fill":"#e3f3d3","label":true},"nodes":["01c3265cd075021e","cad33a63f66ef72e","b0a01df532296971","b0897fa49e0b6e73"],"x":584,"y":1371.5,"w":862,"h":97},{"id":"01c3265cd075021e","type":"ps-schedule-merger","z":"ac86d42a29852803","g":"608a7292e1808e4d","name":"Merge for HA visuatisation","outputIfNoSchedule":"false","logicFunction":"OR","schedulingDelay":2000,"sendCurrentValueWhenRescheduling":true,"outputValueForOn":"true","outputValueForOff":"false","outputValueForOntype":"bool","outputValueForOfftype":"bool","x":800,"y":1420,"wires":[[],[],["cad33a63f66ef72e"]]},{"id":"cad33a63f66ef72e","type":"function","z":"ac86d42a29852803","g":"608a7292e1808e4d","name":"Convert true/false to 1/0","func":"msg.payload.hours.forEach(h => h.onOff = h.onOff ? \"1\" : \"0\")\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1110,"y":1420,"wires":[["b0a01df532296971"]]},{"id":"b0a01df532296971","type":"ha-sensor","z":"ac86d42a29852803","g":"608a7292e1808e4d","name":"Info from PS to HA","entityConfig":"eab799518168f5a3","version":0,"state":"payload","stateType":"str","attributes":[{"property":"Schedule","value":"payload.schedule","valueType":"msg"},{"property":"Hours","value":"payload.hours","valueType":"msg"},{"property":"Control","value":"payload.hours[0].onOff","valueType":"str"},{"property":"Current","value":"payload.current","valueType":"str"}],"inputOverride":"allow","outputProperties":[],"x":1330,"y":1420,"wires":[[]]},{"id":"b0897fa49e0b6e73","type":"link in","z":"ac86d42a29852803","g":"608a7292e1808e4d","name":"link in 66","links":["64ca8a80f8111a29","16428e63b0053db5"],"x":625,"y":1420,"wires":[["01c3265cd075021e"]]},{"id":"eab799518168f5a3","type":"ha-entity-config","server":"33cb7d2214929908","deviceConfig":"541b42292cfc1dd5","name":"sensor config ","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"Powersaver"},{"property":"icon","value":""},{"property":"entity_category","value":""},{"property":"entity_picture","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":true,"debugEnabled":false},{"id":"33cb7d2214929908","type":"server","name":"Home Assistant","version":5,"addon":false,"rejectUnauthorizedCerts":false,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":": ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"default","statusTimeFormat":"h:m","enableGlobalContextStore":false},{"id":"541b42292cfc1dd5","type":"ha-device-config","name":"","hwVersion":"","manufacturer":"Node-RED","model":"","swVersion":""}]