Hey Everyone,
So I was going to share this workflow when I created my TP-Link HS110 video but with it becoming discontinued I now need to find an alternative smart plug with energy monitor and get a company to provide one.
Basically, this workflow uses Node-RED and Home Assistant to notify you when an appliance has finished.
It works off of some variables:
/*
How often do you want to check to see if the appliance is active?
figure in minutes
*/
var duration_is_appliance_active = 2;
/*
Once the appliance is active, how often do you want to check to see
if it has finished?
figure in minutes
*/
var duration_has_appliance_finished = 1;
/*
What level of power do you want to trigger the appliance as active
(out of standby/ready mode)?
figure in watts
*/
var power_is_appliance_active = 40;
/*
What do you want to call your appliance eg Dishwasher
*/
var appliance = 'Microwave';
/*
What do you want to be called in the notifications?
*/
var users_name = 'John';
/*
What is the IP address of the smart plug?
*/
var host_ip = '192.168.0.22';
Using that the flow goes like this.
Is the current power usage above $power_is_appliance_active
(40) watts?
If it isn’t, then check again in $duration_is_appliance_active
(2) minutes.
If it is then set the status to “started” and check again in $duration_has_appliance_finished
(1) minute(s).
Rinse and repeat until the watts falls below the threshold set.
Then set the status to “confirming” and check again in $duration_has_appliance_finished
(1) minute(s).
If it is still below the threshold, then set the status to “finished” and trigger whatever notifications you specify in Home Assistant.
For those who want to give it a go and you have a smart plug that can give energy usage as well as Node-RED installed, here is the code for Node-RED and what it looks like on screen:
[{"id":"43aba3e1.c38bcc","type":"tab","label":"Appliance status 1","disabled":false,"info":""},{"id":"7c62f2d3.d5abcc","type":"smart-plug","z":"43aba3e1.c38bcc","name":"Appliance","device":"192.168.0.22","interval":"1000","eventInterval":"3000","x":290,"y":380,"wires":[["b9887d4e.e205e"]]},{"id":"b9887d4e.e205e","type":"function","z":"43aba3e1.c38bcc","name":"The main workings","func":"flow.set('initial_scan_complete', true);\nvar appliance = flow.get('appliance_name');\nvar message = false;\nvar trigger = parseInt(flow.get('power_is_active'));\nflow.set('trigger', trigger);\nvar active_timeout = (parseInt(flow.get('duration_has_appliance_finished')) * 1000) * 60;\nvar inactive_timeout = (parseInt(flow.get('duration_is_appliance_active')) * 1000) * 60;\n \nif (msg.payload.voltage) {\n var watts = parseInt(msg.payload.power);\n flow.set('watts', watts);\n \n if (watts >= trigger) {\n if (flow.get('appliance_status') === 'finished' || flow.get('appliance_status') === 'off' || flow.get('appliance_status') === 'confirming') {\n flow.set('appliance_status', 'started');\n message = true;\n } else {\n //message = appliance + ' is on';\n flow.set('appliance_status', 'on');\n }\n \n var delay = active_timeout;\n flow.set('appliance_active', true);\n } else {\n if (flow.get('appliance_active')) {\n var delay = active_timeout;\n flow.set('appliance_status', 'confirming');\n } else if (flow.get('appliance_status') === 'confirming') {\n flow.set('appliance_status', 'finished');\n message = true;\n var delay = inactive_timeout;\n } else {\n var delay = inactive_timeout;\n flow.set('appliance_status', 'off');\n }\n \n flow.set('appliance_active', false);\n }\n} else {\n var delay = inactive_timeout;\n flow.set('appliance_status', 'off');\n}\nflow.set('send_message', message);\n\nreturn {\n delay: delay,\n payload: null,\n send_message: message\n \n};","outputs":1,"noerr":0,"x":860,"y":260,"wires":[["401b5a32.d63b74","cb4a0a0.9f64af8"]]},{"id":"fd2d3b9b.8e8238","type":"function","z":"43aba3e1.c38bcc","name":"Set variables","func":"/*\n How often do you want to check to see if the appliance is active?\n figure in minutes\n*/\nvar duration_is_appliance_active = 2;\n\n/*\n Once the appliance is active, how often do you want to check to see\n if it has finished?\n figure in minutes\n*/\nvar duration_has_appliance_finished = 1;\n\n/*\n What level of power do you want to trigger the appliance as active\n (out of standby/ready mode)?\n figure in watts\n*/\nvar power_is_appliance_active = 40;\n\n/*\n What do you want to call your appliance eg Dishwasher\n*/\nvar appliance = 'Microwave';\n\n/*\n What do you want to be called in the notifications?\n*/\nvar users_name = 'John';\n\n/*\n What is the IP address of the smart plug?\n*/\nvar host_ip = '192.168.0.22';\n\n\n/*\n Do not edit items below this line.\n*/\nflow.set('duration_is_appliance_active', duration_is_appliance_active || 5);\nflow.set('duration_has_appliance_finished', duration_has_appliance_finished || 1);\nflow.set('power_is_active', power_is_appliance_active || 100);\nflow.set('appliance_name', appliance);\nflow.set('users_name', users_name);\nflow.set('host_ip', host_ip);\nflow.set('initial_scan_complete', false);\n\nreturn { \n host: flow.get('host_ip')\n };\n","outputs":1,"noerr":0,"x":300,"y":140,"wires":[["f8fbf094.23abc"]]},{"id":"9c2e3896.350678","type":"play audio","z":"43aba3e1.c38bcc","name":"","voice":"2","x":1270,"y":680,"wires":[]},{"id":"401b5a32.d63b74","type":"delay","z":"43aba3e1.c38bcc","name":"Delay","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":170,"y":660,"wires":[["f31173d6.e2dbc"]]},{"id":"f31173d6.e2dbc","type":"function","z":"43aba3e1.c38bcc","name":"Extract command","func":"return {\n payload: \"getMeterInfo\"\n};","outputs":1,"noerr":0,"x":310,"y":320,"wires":[["7c62f2d3.d5abcc"]]},{"id":"d3216004.14dee","type":"start-up-trigger","z":"43aba3e1.c38bcc","x":310,"y":80,"wires":[["fd2d3b9b.8e8238"]]},{"id":"63b2d000.f1c39","type":"catch","z":"43aba3e1.c38bcc","name":"Catch ALL errors for this flow","scope":["7c62f2d3.d5abcc"],"x":270,"y":720,"wires":[["86937508.8181f8","401b5a32.d63b74"]]},{"id":"86937508.8181f8","type":"debug","z":"43aba3e1.c38bcc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":200,"y":780,"wires":[]},{"id":"bb5bea2f.0317a8","type":"inject","z":"43aba3e1.c38bcc","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":140,"wires":[["fd2d3b9b.8e8238"]]},{"id":"12eb5e77.fdaaa2","type":"api-call-service","z":"43aba3e1.c38bcc","name":"","server":"b9484d79.21669","service_domain":"notify","service":"clicksend","data":"","mergecontext":"","x":970,"y":740,"wires":[[]]},{"id":"eff8cb8f.935ea8","type":"function","z":"43aba3e1.c38bcc","name":"Send SMS to ClickSend","func":"return {\n payload: {\n \"domain\": \"notify\",\n \"service\": \"clicksend\",\n \"data\": {\n \"message\": msg.payload\n }\n }\n}\n","outputs":1,"noerr":0,"x":970,"y":680,"wires":[["12eb5e77.fdaaa2"]]},{"id":"f8fbf094.23abc","type":"adv ping","z":"43aba3e1.c38bcc","name":"Is the appliance plugged in?","host":"","x":360,"y":200,"wires":[["34f55077.59bc6"]]},{"id":"34f55077.59bc6","type":"switch","z":"43aba3e1.c38bcc","name":"Don't pester the appliance if it isn't online","property":"payload","propertyType":"msg","rules":[{"t":"false"},{"t":"else"}],"checkall":"true","repair":true,"outputs":2,"x":430,"y":260,"wires":[["b9887d4e.e205e"],["f31173d6.e2dbc"]]},{"id":"29fcb436.f27bfc","type":"template","z":"43aba3e1.c38bcc","name":"Convert the variable to a formatted message","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{payload.greeting}} {{payload.users_name}}, the {{payload.appliance_name}} has {{payload.appliance_status}}!","output":"str","x":1120,"y":320,"wires":[["9c2e3896.350678","eff8cb8f.935ea8"]]},{"id":"cb4a0a0.9f64af8","type":"function","z":"43aba3e1.c38bcc","name":"Create a random greeting","func":"if (msg.send_message) {\n var users_name = flow.get('users_name');\n var appliance_name = flow.get('appliance_name');\n var appliance_status = flow.get('appliance_status');\n \n var arr = [\n 'Hey there',\n 'Hi',\n 'Yo',\n 'Greetings',\n 'Sorry to disturb you',\n ];\n \n greeting = arr[Math.floor(Math.random()*arr.length)];\n \n var payload = {\n payload: {\n greeting: greeting,\n users_name: users_name,\n appliance_name: appliance_name,\n appliance_status: appliance_status,\n payload: null\n }\n }\n \n node.warn(payload);\n \n return payload;\n}","outputs":1,"noerr":0,"x":1190,"y":260,"wires":[["29fcb436.f27bfc"]]},{"id":"e5fcea1d.1407b8","type":"comment","z":"43aba3e1.c38bcc","name":"Catch errors & re-run task","info":"","x":270,"y":580,"wires":[]},{"id":"33707e6f.27b342","type":"comment","z":"43aba3e1.c38bcc","name":"SMS & Voice notifications","info":"","x":1130,"y":580,"wires":[]},{"id":"b9484d79.21669","type":"server","z":"","name":"Home Assistant - Main","url":"http://192.168.0.3:8123","pass":"$zhjR4V4"}]
If you need to install any modules that you don’t already have installed it will let you know that they are not installed.
The Home Assistant side is fairly straight-forward. You just need to have one or more notifications installed. I personally have Click2Send and the Node-RED “play audio” modules set for notifications.
I have also added an array of greetings as you can see.
If there’s anything that I haven’t explained properly or you need help with please don’t hesitate to give me a shout.
John
ps If you want to try Node-RED but haven’t got it installed yet, I have videos on installing it on both hassio and standalone systems over at my YouTube channel
https://YouTube.com/hasscasts
I’ve looked but I can’t see a place to enter a forum signature otherwise I’d put my link in there