I’m trying to create a good algorithm for my washing machine to send a push notification when it is ready.
For the hardware I have a Shelly EM and a door sensor.
Ofcourse everything is depending of your specific model of the washing machine.
I have created some test runs and this are my parameters:
- Washing machine off → Shelly returns 0 Watt
- Washing machine standby → Shelly returns about 1,5 till 1,8 Watt (* see comment below)
- Washing machine is running → More then 10 watts works good
I have changed the update period time of the MQTT settings of the Shelly to 1 second.
What I noticed is that when the washing machine is standby the power is every x seconds one moment 0 watt. I think that will be because it is very low and difficult to meassure (230V 1 watt).
What do I want:
- entity that shows if the washing machine is powered on or off
- entity that shows the state (Idle, Running, Clean)
- push notification that is send directly when the program has finished
- push notification every …minutes when the program has finished but the door is not opened.
In home assistant I have created this configuration:
input_select:
washing_machine_status:
name: Status wasmachine
options:
- Idle
- Running
- Clean
initial: Idle
input_boolean:
washing_machine_on:
name: Wasmachine aan
sensor:
- platform: mqtt
name: "wasmachine_mqtt_sensor"
state_topic: "shellies/shellyem-XXXXXXXXX/emeter/0/power"
value_template: "{{ value|float }}"
qos: 1
unit_of_measurement: "Watt"
In Node-Red I have created this flow:
[{"id":"7a34c540.8f84c4","type":"tab","label":"Wasmachine","disabled":false,"info":"","env":[]},{"id":"b1547d02.33153","type":"switch","z":"7a34c540.8f84c4","name":"","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"1.0","vt":"num"},{"t":"eq","v":"0","vt":"num"},{"t":"gt","v":"10","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":330,"y":100,"wires":[["69656173.a925"],[],["ca1a567ccc427a60"]]},{"id":"69656173.a925","type":"api-call-service","z":"7a34c540.8f84c4","name":"> 1 watt --> Set power state of washing machine to on","server":"ef392d83.86c5a","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.washing_machine_on","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":680,"y":60,"wires":[[]]},{"id":"80540aed.a59958","type":"server-state-changed","z":"7a34c540.8f84c4","name":"Washing Power","server":"ef392d83.86c5a","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.wasmachine_mqtt_sensor","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","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"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":120,"y":100,"wires":[["b1547d02.33153"]]},{"id":"efb03bfd0d1b4bd5","type":"server-state-changed","z":"7a34c540.8f84c4","name":"Washing Power <= 2 for 30 sec?","server":"ef392d83.86c5a","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.wasmachine_mqtt_sensor","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","haltifstate":"2","halt_if_type":"num","halt_if_compare":"lte","outputs":2,"output_only_on_state_change":true,"for":"30","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":170,"y":360,"wires":[["bd1f2febfbdb9e24"],[]]},{"id":"ca1a567ccc427a60","type":"api-call-service","z":"7a34c540.8f84c4","name":"> 10 watt --> Set washing machine state running","server":"ef392d83.86c5a","version":3,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.washing_machine_status","data":"{\"option\":\"Running\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":660,"y":140,"wires":[[]]},{"id":"a2597efd6f2591b8","type":"server-state-changed","z":"7a34c540.8f84c4","name":"Washing Power == 0 for 5 sec?","server":"ef392d83.86c5a","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.wasmachine_mqtt_sensor","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","haltifstate":"0","halt_if_type":"num","halt_if_compare":"is","outputs":2,"output_only_on_state_change":false,"for":"5","forType":"num","forUnits":"seconds","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":170,"y":240,"wires":[["ebc4e8e1f4093c1a"],[]]},{"id":"8f53e4fd288c1ac5","type":"api-call-service","z":"7a34c540.8f84c4","name":"Set power state of washing machine to off","server":"ef392d83.86c5a","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.washing_machine_on","data":"","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1080,"y":200,"wires":[[]]},{"id":"17eee4aaea92869e","type":"api-call-service","z":"7a34c540.8f84c4","name":"Set state to Idle","server":"ef392d83.86c5a","version":3,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.washing_machine_status","data":"{\"option\":\"Idle\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1000,"y":260,"wires":[[]]},{"id":"bd1f2febfbdb9e24","type":"api-current-state","z":"7a34c540.8f84c4","name":"Has the washing machine been running?","server":"ef392d83.86c5a","version":2,"outputs":2,"halt_if":"Running","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_select.washing_machine_status","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"x":580,"y":360,"wires":[["54b4df08b8da8b8e"],[]]},{"id":"54b4df08b8da8b8e","type":"api-call-service","z":"7a34c540.8f84c4","name":"Set state to clean","server":"ef392d83.86c5a","version":3,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.washing_machine_status","data":"{\"option\":\"Clean\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":910,"y":360,"wires":[["75b2d0998868b029"]]},{"id":"ebc4e8e1f4093c1a","type":"api-current-state","z":"7a34c540.8f84c4","name":"Has the washing machine been running?","server":"ef392d83.86c5a","version":2,"outputs":2,"halt_if":"Running","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_select.washing_machine_status","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"x":580,"y":240,"wires":[["8f53e4fd288c1ac5","54b4df08b8da8b8e"],["8f53e4fd288c1ac5","17eee4aaea92869e"]]},{"id":"a8a761be73a89c1a","type":"server-state-changed","z":"7a34c540.8f84c4","name":"Door washing machine opened?","server":"63f26c18.71f4f4","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"binary_sensor.wasmachine_deur","entityidfiltertype":"exact","outputinitially":false,"state_type":"habool","haltifstate":"true","halt_if_type":"bool","halt_if_compare":"is","outputs":2,"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"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":170,"y":580,"wires":[["0c89294c758a3482"],[]]},{"id":"02f32a50916b77e5","type":"api-call-service","z":"7a34c540.8f84c4","name":"Set state to Idle","server":"ef392d83.86c5a","version":3,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.washing_machine_status","data":"{\"option\":\"Idle\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":640,"y":580,"wires":[[]]},{"id":"75b2d0998868b029","type":"api-call-service","z":"7a34c540.8f84c4","name":"Send push notification: wash is ready","server":"63f26c18.71f4f4","version":3,"debugenabled":false,"service_domain":"notify","service":"mobile_app_iphone_van_martin","entityId":"","data":"{\"message\":\"Was is klaar.\"}","dataType":"json","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":360,"wires":[[]]},{"id":"20f98740379d96a2","type":"poll-state","z":"7a34c540.8f84c4","name":"Wash is clean and door not opened yet?","server":"63f26c18.71f4f4","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"30","updateIntervalType":"num","updateIntervalUnits":"minutes","outputinitially":false,"outputonchanged":false,"entity_id":"input_select.washing_machine_status","state_type":"str","halt_if":"Clean","halt_if_type":"str","halt_if_compare":"is","outputs":2,"x":190,"y":740,"wires":[[],[]]},{"id":"12c6c9970f21996a","type":"comment","z":"7a34c540.8f84c4","name":"Send every ....time a push notification that the wash is clean","info":"","x":260,"y":700,"wires":[]},{"id":"1d90178010efd54b","type":"comment","z":"7a34c540.8f84c4","name":"When door washing machine is opened and the washing program has runned, reset state to Idle","info":"","x":370,"y":540,"wires":[]},{"id":"0c89294c758a3482","type":"api-current-state","z":"7a34c540.8f84c4","name":"State is clean?","server":"ef392d83.86c5a","version":2,"outputs":2,"halt_if":"Clean","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_select.washing_machine_status","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"x":420,"y":580,"wires":[["02f32a50916b77e5"],[]]},{"id":"9f42b68e3d9788e4","type":"comment","z":"7a34c540.8f84c4","name":"TODO","info":"","x":430,"y":740,"wires":[]},{"id":"ef392d83.86c5a","type":"server","name":"Home Assistant","rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true},{"id":"63f26c18.71f4f4","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
Conclusion: it works but I think this could be better and more efficient.
Also I’m considering if it is not better to have poll state nodes in stead of the state changed nodes?
The problem is now that it only reacts on state changed events. But what if some part of the system is not working at some moment? The system is not repairing its self.
So I could poll every X seconds for example. But I didn’t have found a solution to check if the entity has a state for … seconds in a flow (so after the poll state node).
What do you thinks. Is my approach correct of could it be better?