Power Dashboard with PC controls

enter image description here Control your PC and monitor the power consumption of connected device. I used a NETIO cable to power up my PSU (a similar effect can be achieved with Sonoff POW R2) to take over the control and measurements.

Features:

  • Online Dashboard
  • Dynamic buttons
  • WOL, Sleep, Restart PC options
  • Total and Daily Cost
  • Total and Daily Power use
  • Total and Daily Up time
  • 7 Day dynamic chart
  • Secure restart
  • 2FA Restart authentication

You will need the following nodes:

  • node-red-dashboard
  • node-red-contrib-wol

This article uses 2FA tutorial and build on the washing machine notifications.

You will also need:

or

Settings

  • Refresh Rate time interval in seconds to get the readings

More about me:

If you want to get the latest updates to this project you can follow me via your preferred social media:

And if you feeling like buying me a coffee or supporting me in a more continuous way:

I hope you have enjoyed the project!

[{"id":"b44411e6.28ae6","type":"subflow","name":"2FA","info":"","category":"","in":[{"x":320,"y":240,"wires":[{"id":"54d21981.c2c698"}]}],"out":[{"x":1040,"y":220,"wires":[{"id":"d6bdef4b.09f4b","port":0}]}],"env":[{"name":"default2fa","type":"bool","value":"false"},{"name":"timer","type":"num","value":"20"},{"name":"ARdevice","type":"str","value":""},{"name":"title","type":"str","value":""},{"name":"text","type":"str","value":""},{"name":"2FApath","type":"str","value":""},{"name":"ID","type":"str","value":""}],"color":"#DDAA99"},{"id":"54d21981.c2c698","type":"function","z":"b44411e6.28ae6","name":"Set alarm","func":"var x = env.get(\"timer\");\nvar timer = x *1000;\nvar time = new Date();\nvar timeseconds = time.getTime();\nvar alarm = timeseconds + timer;\n\n\nflow.set(\"$parent.alarm\", alarm);\nflow.set(\"$parent.time\", timeseconds);\nflow.set(\"$parent.authentication\", \"pending\");\n\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":240,"wires":[["978a4770.9effd8","d6bdef4b.09f4b"]]},{"id":"7aedd4b4.d3497c","type":"delay","z":"b44411e6.28ae6","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":740,"y":320,"wires":[["d6bdef4b.09f4b"]]},{"id":"978a4770.9effd8","type":"function","z":"b44411e6.28ae6","name":"2FA Push","func":"var device = env.get(\"ARdevice\");\nvar timer = env.get(\"timer\");\nvar title = env.get(\"title\");\nvar text = env.get(\"text\");\nvar path = env.get(\"2FApath\");\nvar ID = env.get(\"ID\");\nvar default2fa = env.get(\"default2fa\");\nvar status2fa;\n\nif(default2fa === true){\n    status2fa = \"approved\";\n}\n\nif(default2fa === false){\n    status2fa = \"declined\";\n}\n\n\nvar key = global.get(device);\nvar time = flow.get(\"$parent.time\");\nvar alarm = flow.get(\"$parent.alarm\");\nvar url = \"https://autoremotejoaomgcd.appspot.com/sendmessage\";\nvar command = \"2FA\";\nvar body = {\n    \"title\": {\n        \"title\": title,\n        \"titleexpanded\": title\n  },\n  \"text\": {\n        \"text\": text,\n        \"textexpanded\": text\n  },\n  \"icons\": {\n    \"navbaricon\": \"android.resource://net.dinglisch.android.taskerm/hl_device_access_new_account\",\n    \"bigicon\": \"android.resource://net.dinglisch.android.taskerm/hl_device_access_new_account\"\n  },\n  \"notificationid\": ID,\n  \"persistent\": true,\n  \"priority\": 1,\n  \"default2fa\": default2fa,\n  \"status2fa\" : status2fa,\n  \"path\" : path,\n  \"timer\": timer,  // in seconds\n  \"start\": time,   // in ms\n  \"alarm\": alarm,  // in ms\n  \"buttons\": [\n    {\n      \"button1\": {\n        \"icon\": \"\",\n        \"label\": \"Allow\",\n        \"command\": \"2faresponse_true\"\n      },\n     \n      \"button2\": {\n        \"icon\": \"\",\n        \"label\": \"Deny\",\n        \"command\": \"2faresponse_false\"\n      }\n    \n    }\n  ]\n};\nmsg.data = body;\nvar x = JSON.stringify(body);\nvar encodedBody = encodeURIComponent(x);\n\nmsg.url = url + \"?key=\" + key + \"&message=\" +command + \"=:=\"+ encodedBody;\nreturn msg;\n\n\n","outputs":1,"noerr":0,"x":620,"y":360,"wires":[["d3f75fc.8c556a"]]},{"id":"d3f75fc.8c556a","type":"http request","z":"b44411e6.28ae6","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"","x":850,"y":360,"wires":[[]]},{"id":"d6bdef4b.09f4b","type":"function","z":"b44411e6.28ae6","name":"Timer","func":"var authentication = flow.get(\"$parent.authentication\");\nvar default2fa = env.get(\"default2fa\");\nvar alarm = flow.get(\"$parent.alarm\");\n\nvar time = new Date();\nvar timeseconds = time.getTime();\n\n//2FA message approved (1)\nif(authentication === \"approved\"){    \n    flow.set(\"$parent.authentication\", \"pending\");\n    return[msg, null, null];\n}\n\n//2FA message declined (2)\nif(authentication === \"declined\"){\n    flow.set(\"$parent.authentication\", \"pending\");\n    return[null, msg, null];\n}\n\n//pending for 2FA message (3)\nif(authentication === \"pending\"){\n    if(timeseconds < alarm){           //loop\n        return[null, null, msg];\n    }\n    \n    if(timeseconds => alarm){\n        if(default2fa === true){         // timeout & default approved\n            \n            return[msg, null, null];\n        }\n        if(default2fa === false){        // timeout & default declined\n            \n            return[null, msg, null];\n        }\n    }\n}","outputs":3,"noerr":0,"x":710,"y":240,"wires":[[],[],["7aedd4b4.d3497c"]]},{"id":"1fe6aa28.98d036","type":"subflow","name":"AR Component","info":"","category":"","in":[{"x":40,"y":80,"wires":[{"id":"2c5c3033.d3977"}]}],"out":[],"env":[{"name":"ARname","type":"str","value":""},{"name":"command","type":"str","value":""},{"name":"message","type":"str","value":""}],"color":"#DDAA99"},{"id":"a40447b3.8855d8","type":"http request","z":"1fe6aa28.98d036","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"","x":410,"y":80,"wires":[[]]},{"id":"2c5c3033.d3977","type":"function","z":"1fe6aa28.98d036","name":"Compose AR","func":"var message = env.get(\"message\"); \nvar command = env.get(\"command\"); \nvar ARname = env.get(\"ARname\"); \n\nvar AR = global.get(ARname);\nvar url = \"https://autoremotejoaomgcd.appspot.com/sendmessage?key=\";\n\nurl.method = \"GET\";\nmsg.url = url+AR+\"&message=\"+command+\"=:=\"+message;\n\nreturn msg;\n","outputs":1,"noerr":0,"x":190,"y":80,"wires":[["a40447b3.8855d8"]]},{"id":"16657f26.bd82f1","type":"tab","label":"Power Dashboard with PC controls","disabled":false,"info":"![enter image description here](https://notenoughtech.com/wp-content/uploads/2019/12/maxresdefault-8.jpg)\nControl your PC and monitor the power consumption of connected device. I used a NETIO cable to power up my PSU (a similar effect can be achieved with Sonoff POW R2) to take over the control and measurements.\n\n - [Complete instruction](https://notenoughtech.com/home-automation/nodered-home-automation/pc-dashboard-using-netio-power-cables/)\n\n\n**Features**:\n- Online Dashboard\n- Dynamic buttons\n- WOL, Sleep, Restart PC options\n- Total and Daily Cost\n- Total and Daily Power use\n- Total and Daily Up time\n- 7 Day dynamic chart\n- Secure restart\n- [2FA Restart authentication](https://notenoughtech.com/home-automation/nodered-home-automation/two-factor-authentication-in-nodered/)\n\nYou will need the following nodes:\n\n - node-red-dashboard\n - node-red-contrib-wol\n \n\nThis article uses [2FA tutorial](https://notenoughtech.com/home-automation/nodered-home-automation/two-factor-authentication-in-nodered/) and build on the [washing machine notifications](https://notenoughtech.com/featured/washing-machine-notifications/). \n \n You will also need:\n \n - [NETIO Power Cable 101x](https://shop.netio.eu/netio-power-sockets/powercable-modbus-101x/)\n\n or \n \n\n - Sonoff POWR2: ([Aliexpress](http://s.click.aliexpress.com/e/by4YqwXQ), [Banggood](https://www.banggood.com/custlink/mGmvyM4HC2), [Gearbest](https://www.gearbest.com/smart-home-controls/pp_1829203.html?wid=1433363&lkid=20102743), [AmazonUK](https://amzn.to/2TJRPN6), [AmazonUS](https://amzn.to/2u9E0bs), [Itead store](http://shrsl.com/1i9e8))\n\n\n\n\n# Settings\n\n - **Refresh Rate** time interval in seconds to get the readings\n \n"},{"id":"116ba3dd.ce029c","type":"inject","z":"16657f26.bd82f1","name":"","props":[{"p":"payload","v":"{}","vt":"json"},{"p":"topic","v":"","vt":"string"}],"repeat":"10","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"{}","payloadType":"json","x":110,"y":380,"wires":[["aa0cff16.0c50d","12f536f2.c96c89"]]},{"id":"90b30fa9.3ffad","type":"ui_chart","z":"16657f26.bd82f1","name":"","group":"e4992359.570b9","order":10,"width":8,"height":5,"label":"7-day usage","chartType":"bar","legend":"true","xformat":"dd HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"3000","removeOlder":"7","removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"x":470,"y":560,"wires":[[]]},{"id":"bc2f0866.998d68","type":"ui_button","z":"16657f26.bd82f1","name":"","group":"e4992359.570b9","order":2,"width":8,"height":1,"passthru":false,"label":"{{msg.label}}","tooltip":"","color":"","bgcolor":"{{msg.color}}","icon":"","payload":"state","payloadType":"str","topic":"","x":1170,"y":380,"wires":[["2f67f3aa.5f8a6c"]]},{"id":"494fbe09.549c1","type":"ui_toast","z":"16657f26.bd82f1","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"","topic":"","name":"","x":1570,"y":300,"wires":[]},{"id":"a0c77870.131c28","type":"switch","z":"16657f26.bd82f1","name":"OFF|SLEEP|ON","property":"payload.Outputs[0].Load","propertyType":"msg","rules":[{"t":"lte","v":"2","vt":"num"},{"t":"btwn","v":"3","vt":"num","v2":"5","v2t":"num"},{"t":"gte","v":"6","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":760,"y":380,"wires":[["89ea8c52.14f3b"],["dd2592e4.44e9d"],["e496e111.6b38c"]]},{"id":"89ea8c52.14f3b","type":"function","z":"16657f26.bd82f1","name":"RESET ","func":"msg.label = \"TURN ON\";\nmsg.color = \"red\";\nflow.set(\"Power_function\", \"reset\");\n\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":340,"wires":[["bc2f0866.998d68"]]},{"id":"e496e111.6b38c","type":"function","z":"16657f26.bd82f1","name":"SLEEP","func":"msg.label = \"SLEEP\";\nmsg.color = \"green\";\nflow.set(\"Power_function\", \"sleep\");\n\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":420,"wires":[["bc2f0866.998d68"]]},{"id":"dd2592e4.44e9d","type":"function","z":"16657f26.bd82f1","name":"WOL","func":"msg.label = \"WAKE UP\";\nmsg.color = \"blue\";\nflow.set(\"Power_function\", \"wol\");\n\nreturn msg;","outputs":1,"noerr":0,"x":990,"y":380,"wires":[["bc2f0866.998d68"]]},{"id":"2f67f3aa.5f8a6c","type":"function","z":"16657f26.bd82f1","name":"Commands","func":"var x = flow.get(\"Power_function\");\n\nif(x === \"wol\"){\n    msg.payload = \"Desktop will wake up now\";\n    msg.topic = \"Computer: DESKTOP\";\n    return [msg, null, null];\n}\n\nif(x === \"sleep\"){\n    msg.payload = \"Desktop is going to sleep\";\n    msg.topic = \"Computer: DESKTOP\";\n    return [null, msg, null];\n}\n\nif(x === \"reset\"){\n    msg.payload = \"Desktop will reset now\";\n    msg.topic = \"Computer: DESKTOP\";\n    return [null, null, msg];\n}","outputs":3,"noerr":0,"x":1350,"y":380,"wires":[["a6af33f1.a4d4","494fbe09.549c1"],["494fbe09.549c1","2a626659.959e7a"],["494fbe09.549c1","d5437beb.dd65f8"]]},{"id":"dd376fdf.cf0cb","type":"function","z":"16657f26.bd82f1","name":"Every Hour","func":"var total = flow.get(\"TotalUseByHour\");\n\nif(!total.length){\n        total = [0];\n    }\n\n//push element to an array 1st postition\n\n\nvar value = flow.get(\"AverageUsePerHour\");\ntotal.unshift(value);\nflow.set(\"TotalUseByHour\", total);\nflow.set(\"AverageUsePerHour\", 0);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":470,"y":300,"wires":[[]]},{"id":"c5c26397.850f8","type":"inject","z":"16657f26.bd82f1","name":"Every 24h","repeat":"","crontab":"00 00 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":340,"wires":[["80d791c5.4b8f6"]]},{"id":"4ffb707d.6649b","type":"inject","z":"16657f26.bd82f1","name":"Every hour","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"3600","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":300,"wires":[["dd376fdf.cf0cb"]]},{"id":"80d791c5.4b8f6","type":"function","z":"16657f26.bd82f1","name":"Every 24h","func":"var totalD = flow.get(\"TotalUseByHour\");\nvar weektotal = flow.get(\"TotalUseByDay\");\nflow.set(\"TimeDay\", 0);\n\nif(!totalD || !totalD.length || totalD === undefined){\n        totalD = [0];\n        return msg;\n    }\n\n\nfunction add(accumulator, a) {\n            return accumulator + a}\n        \n\n//Watts per 24h\nvar usedperday = totalD.reduce(add);\n\nweektotal.unshift(usedperday);\nflow.set(\"TotalUseByDay\", weektotal);\ntotalD.splice(0,totalD.length);\ntotalD = [0];\nflow.set(\"TotalUseByHour\",totalD);\n\n\n\nvar totalW = flow.get(\"TotalUseByDay\");\n\nif(!totalW || !totalW.length || totalW === undefined){\n        totalW = [0];\n        return msg;\n    }\n\n\n\n//keep x number of elements in an array\n\nvar position = 7;\n\nif(totalW[position] === undefined) {\n    //do nothing if array empty\n}\nelse {\n    totalW.splice(position, 7); //remove 1 element from position\n    flow.set(\"TotalUseByDay\", totalW);\n    \n}\n","outputs":1,"noerr":0,"x":460,"y":340,"wires":[[]]},{"id":"aa0cff16.0c50d","type":"function","z":"16657f26.bd82f1","name":"Update Chart","func":"var arrayD = flow.get(\"TotalUseByDay\");\nvar arrayH= flow.get(\"TotalUseByHour\");\nvar averageperhour = flow.get(\"AverageUsePerHour\");\n\n//if array doen't exist\nif(arrayD === undefined){\n    arrayD = [0];\n    flow.set(\"TotalUseByDay\", arrayD);\n}\nif(arrayH === undefined){\n    arrayH = [0];\n    flow.set(\"TotalUseByHour\", arrayH);\n}\n\n//function\nfunction add(accumulator, a) {\n            return accumulator + a}\n\n\n//set data, label and series for the chart\n\nvar m = {};\nvar count = arrayD.length;\n\nif(count === undefined || count < 2){\n    \n    m.labels = [\"Today\"];\n    m.data = [[]];\n    m.series = [];\n    \n    \n    if(arrayH[0] === 0){\n        m.data[0].push(averageperhour.toFixed(2));\n        m.series.push(\"Watts/24h\");\n    }\n    if(arrayH[0] > 0){    \n        var usedperday = arrayH.reduce(add);\n        m.data[0].push(usedperday.toFixed(2));\n        m.series.push(\"Watts/24h\");\n    }\n    \n    \n    \n    return {payload:[m],topic:msg.topic};\n}\n\nelse{\n    \n    m.labels = [\"Today\",\"Yesterday\",\"Day3\",\"Da4\",\"Day5\",\"Day6\", \"Day7\"];\n    m.data = [[]];\n    m.series = [];\n    if(arrayH[0] === 0){\n        m.data[0].push(averageperhour.toFixed(2));\n        m.series.push(\"Watts/24h\");\n    }\n    if(arrayH[0] > 0){    \n        usedperday = arrayH.reduce(add);\n        m.data[0].push(usedperday.toFixed(2));\n        m.series.push(\"Watts/24h\");\n    }m.series.push(\"Watts/24h\");\n\nfor (i=0; i<count; i++){\n    m.data[0].push(arrayD[i].toFixed(2));\n    m.series.push(\"Watts/24h\");\n} \n\nreturn {payload:[m],topic:msg.topic};\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":250,"y":520,"wires":[["90b30fa9.3ffad"]]},{"id":"46f779e3.e9bcb8","type":"inject","z":"16657f26.bd82f1","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[]","payloadType":"json","x":250,"y":600,"wires":[["90b30fa9.3ffad"]]},{"id":"2a626659.959e7a","type":"subflow:1fe6aa28.98d036","z":"16657f26.bd82f1","name":"AR Message","env":[{"name":"ARname","value":"ARdesktop","type":"str"},{"name":"command","value":"PC","type":"str"},{"name":"message","value":"sleep","type":"str"}],"x":1550,"y":400,"wires":[]},{"id":"8a15f00b.31dca","type":"function","z":"16657f26.bd82f1","name":"Reset (needs 2FA)","func":"var IP = \"192.168.1.93\";\nvar command = 2;\n\nmsg.url = \"http://\"+IP+\"/netio.json\";\n\nmsg.payload = {\n \"Outputs\": [{\n  \"ID\": 1,\n  \"Action\": command\n }]\n};\n\n\nreturn msg;","outputs":1,"noerr":0,"x":1790,"y":440,"wires":[["7e8853c.e7e41ac"]]},{"id":"7e8853c.e7e41ac","type":"http request","z":"16657f26.bd82f1","name":"","method":"POST","ret":"obj","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"basic","x":1990,"y":440,"wires":[["40f69790.8b6f88"]]},{"id":"40f69790.8b6f88","type":"http response","z":"16657f26.bd82f1","name":"","statusCode":"","headers":{},"x":2150,"y":440,"wires":[]},{"id":"b93f082d.47abc8","type":"function","z":"16657f26.bd82f1","name":"Settings","func":"","outputs":1,"noerr":0,"initialize":"// frequency of polling in sec\nflow.set(\"refresh_rate\", 10);\n\n//reset\nflow.set(\"TimeDay\",0);\nflow.set(\"TimeTotal\",0);\nflow.set(\"TotalUseByDay\",[0]);\nflow.set(\"TotalUseByHour\",[0]);\nflow.set(\"AverageUsePerHour\",0);\n\n\n\n\nreturn msg;","finalize":"","x":120,"y":100,"wires":[[]]},{"id":"46f08399.8bf29c","type":"function","z":"16657f26.bd82f1","name":"Store Values","func":"flow.set(\"Voltage\", msg.payload.GlobalMeasure.Voltage);\nflow.set(\"TotalLoad\", msg.payload.GlobalMeasure.TotalLoad);\nflow.set(\"TotalEnergy\", msg.payload.GlobalMeasure.TotalEnergy);\nflow.set(\"PowerFactor\", msg.payload.GlobalMeasure.TotalEnergy);\nflow.set(\"Frequency\", msg.payload.GlobalMeasure.Frequency);\nflow.set(\"Current\", msg.payload.Outputs[0].Current);\nflow.set(\"StartDate\", msg.payload.GlobalMeasure.EnergyStart);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":380,"wires":[["a0c77870.131c28","32f18042.ce7d1"]]},{"id":"12f536f2.c96c89","type":"http request","z":"16657f26.bd82f1","name":"NETIO REST","method":"GET","ret":"obj","paytoqs":"query","url":"http://computercable.lan/netio.json","tls":"","persist":false,"proxy":"","authType":"basic","x":300,"y":380,"wires":[["46f08399.8bf29c","b73ba52f.495538","fbb3b605.ee8468"]]},{"id":"32f18042.ce7d1","type":"function","z":"16657f26.bd82f1","name":"Calculate all","func":"//get values\nvar totalload =  flow.get(\"TotalLoad\");\nvar totalenergy = flow.get(\"TotalEnergy\");\nvar refresh = flow.get(\"refresh_rate\");\nvar totalusebyday = flow.get(\"TotalUseByDay\");\nvar totalusebyhour = flow.get(\"TotalUseByHour\");\nvar timetotal = flow.get(\"TimeTotal\");\nvar timeday = flow.get(\"TimeDay\");\nvar cost = global.get(\"PowerCost\");\nvar averageuseperhour = flow.get(\"AverageUsePerHour\");\n\n//ERROR HANDLING\n// functions\nfunction calcTimeHM(hh){\n    var hours = (\"0\"+Math.floor((hh%86400)/3600)).slice(-2);\n    var minutes = (\"0\"+Math.floor((hh%3600)/60)).slice(-2);\n    return hours + \"h \" + minutes +\"min\";\n}\n\nfunction calcTimeDHM(hh){\n    var days = (\"0\"+Math.floor(hh/86400)).slice(-2);\n    var hours = (\"0\"+Math.floor((hh%86400)/3600)).slice(-2);\n    var minutes = (\"0\"+Math.floor((hh%3600)/60)).slice(-2);\n    return days+\"d \" +hours + \"h \" + minutes +\"min\";\n}\n\nfunction add(accumulator, a) {\n            return accumulator + a}\n\n//WATTAGE\n\n//total kWh\nvar kw = totalenergy/1000;\n//today so far W\nvar todayw1 = totalusebyhour[0];\nif(todayw1 === 0){\n    var todayw = averageuseperhour.toFixed(2);\n}\nif(todayw1 !== 0){\n   todayw = (totalusebyhour.reduce(add) + averageuseperhour).toFixed(2);\n}\n\n// Watts used in X sec (W per h)\nvar houruse = ((totalload/3600)*refresh);\nvar currentuse = averageuseperhour +  houruse;  \n\n\n//COST\n\n//calculate the day cost per used kWh\nvar daycost1 = totalusebyhour[0];\nif(daycost1 === 0 || undefined){\n    var daycost = (averageuseperhour/1000 * cost).toFixed(2);\n}\nif(daycost1 !== 0){\n    daycost = ((totalusebyhour.reduce(add))/1000 * cost).toFixed(2);\n}\n//calculate the day cost per used kWh\nvar totalcost = (totalenergy/1000*cost).toFixed(2);\n\n\n//TIME\n\n//calculate uptime\nif(totalload => 5){\n    //total uptime\n    var timeT = timetotal + 10;    \n    var timeTdisplay = calcTimeDHM(timeT);\n    //daily so far uptime\n    var timeD = timeday + 10;    \n    var timeDdisplay = calcTimeHM(timeD);\n}\nif(totalload < 5){\n    //total uptime\n    timeT = timetotal;    \n    timeTdisplay = calcTimeDHM(timeT);\n    //daily so far uptime\n    timeD = timeday;    \n    timeDdisplay = calcTimeHM(timeD);\n}\n     \n//update values\nflow.set(\"TimeTotal\", timeT);\nflow.set(\"TimeDay\", timeD);\nflow.set(\"AverageUsePerHour\", currentuse);\n\n\n\n\n//final payload\n\nmsg.payload = {\n    \"kwh\"         : kw,\n    \"todayw\"      : todayw,\n    \"daycost\"     : daycost,\n    \"totalcost\"   : totalcost,\n    \"currentuse\"  : currentuse,\n    \"timeT\"       : timeT,\n    \"timeTdisplay\": timeTdisplay,\n    \"timeD\"       : timeD,\n    \"timeDdisplay\": timeDdisplay,\n    \"totalload\"   : totalload,\n    \"totalenergy\" : totalenergy\n};\n\n\nreturn msg;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":750,"y":520,"wires":[["9062e869.7fbbd8","eaa41c89.179b2","7255fa63.55ca54","35b7f49f.acc24c","76863f53.b4eb4","e71c41c7.b7f0c","4cbfe1b4.9f613","257ac191.19b34e"]]},{"id":"9062e869.7fbbd8","type":"ui_gauge","z":"16657f26.bd82f1","name":"Current Load","group":"e4992359.570b9","order":1,"width":8,"height":4,"gtype":"gage","title":"Current Power (W)","label":"Watts","format":"{{msg.payload.totalload}}W","min":0,"max":"500","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":1250,"y":720,"wires":[]},{"id":"eaa41c89.179b2","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":7,"width":4,"height":1,"name":"Total Cost","label":"Total Electricity Cost ","format":"£{{msg.payload.totalcost}}","layout":"row-spread","x":1240,"y":680,"wires":[]},{"id":"35b7f49f.acc24c","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":8,"width":4,"height":1,"name":"Total Watts","label":"Total Power Use (kW)","format":"{{msg.payload.kwh}}kW","layout":"row-spread","x":1250,"y":600,"wires":[]},{"id":"76863f53.b4eb4","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":3,"width":4,"height":1,"name":"Today Watts","label":"Today so far (Wh)","format":"{{msg.payload.todayw}}Wh","layout":"row-spread","x":1250,"y":560,"wires":[]},{"id":"7255fa63.55ca54","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":4,"width":4,"height":1,"name":"Daily Cost","label":"Daily Cost (£)","format":"£{{msg.payload.daycost}}","layout":"row-spread","x":1250,"y":640,"wires":[]},{"id":"e71c41c7.b7f0c","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":5,"width":8,"height":1,"name":"Today Uptime","label":"Today Uptime","format":"{{msg.payload.timeDdisplay}}","layout":"row-spread","x":1260,"y":520,"wires":[]},{"id":"4cbfe1b4.9f613","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":9,"width":8,"height":1,"name":"Total Uptime","label":"Total Uptime","format":"{{msg.payload.timeTdisplay}}","layout":"row-spread","x":1250,"y":480,"wires":[]},{"id":"a1f238ae.b19628","type":"ui_switch","z":"16657f26.bd82f1","name":"","label":"","tooltip":"","group":"e4992359.570b9","order":12,"width":3,"height":1,"passthru":false,"decouple":"false","topic":"","topicType":"str","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":true,"x":330,"y":680,"wires":[["e7df829d.b7d21"]]},{"id":"b5cdef72.d99d5","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":11,"width":5,"height":1,"name":"","label":"Enable RESTART","format":"","layout":"row-spread","x":130,"y":680,"wires":[]},{"id":"29f73f7a.7ef34","type":"ui_button","z":"16657f26.bd82f1","name":"","group":"e4992359.570b9","order":13,"width":0,"height":0,"passthru":false,"label":"RESTART","tooltip":"","color":"","bgcolor":"red","icon":"","payload":"Off","payloadType":"str","topic":"","topicType":"str","x":510,"y":840,"wires":[["b76d5f5d.e0256","8a15f00b.31dca"]]},{"id":"e7df829d.b7d21","type":"function","z":"16657f26.bd82f1","name":"Enable button","func":"var x =  msg.payload;\nmsg.enabled = x;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":540,"y":680,"wires":[["29f73f7a.7ef34"]]},{"id":"b76d5f5d.e0256","type":"delay","z":"16657f26.bd82f1","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":680,"y":840,"wires":[["59f4ce41.21e7a"]]},{"id":"59f4ce41.21e7a","type":"change","z":"16657f26.bd82f1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":840,"wires":[["e7df829d.b7d21"]]},{"id":"d5437beb.dd65f8","type":"subflow:b44411e6.28ae6","z":"16657f26.bd82f1","name":"","env":[{"name":"timer","value":"60","type":"num"},{"name":"ARdevice","value":"ARmi9","type":"str"},{"name":"title","value":"Restart Desktop?","type":"str"},{"name":"text","value":"Confirm the action","type":"str"},{"name":"2FApath","value":"/2fa/desktop","type":"str"},{"name":"ID","value":"2FAdesktop","type":"str"}],"x":1530,"y":440,"wires":[["8a15f00b.31dca"]]},{"id":"6d8fc7f.6db1d38","type":"http in","z":"16657f26.bd82f1","name":"","url":"/2fa/desktop","method":"post","upload":false,"swaggerDoc":"","x":1530,"y":540,"wires":[["7ce94dc8.8cb164","9e3530c0.385f"]]},{"id":"9e3530c0.385f","type":"function","z":"16657f26.bd82f1","name":"2FA authenticate","func":"var x = msg.payload.authentication;\n\nif(x === true){\n    flow.set(\"authentication\", \"approved\");\n}\nif(x === false){\n    flow.set(\"authentication\", \"declined\");\n}\n\n","outputs":1,"noerr":0,"x":1790,"y":500,"wires":[[]]},{"id":"7ce94dc8.8cb164","type":"http response","z":"16657f26.bd82f1","name":"","statusCode":"","headers":{},"x":1720,"y":540,"wires":[]},{"id":"55e84899.6274b8","type":"comment","z":"16657f26.bd82f1","name":"See Setup tab","info":"","x":170,"y":60,"wires":[]},{"id":"a6af33f1.a4d4","type":"wake on lan","z":"16657f26.bd82f1","mac":"B4-2E-99-36-86-E7","host":"10.1.1.12","udpport":9,"name":"WOL Desktop","x":1560,"y":340,"wires":[]},{"id":"b73ba52f.495538","type":"debug","z":"16657f26.bd82f1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":470,"y":460,"wires":[]},{"id":"75864dcb.61d624","type":"inject","z":"16657f26.bd82f1","name":"","props":[{"p":"payload"},{"p":"enabled","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Started!","payloadType":"str","x":130,"y":860,"wires":[["29f73f7a.7ef34","a1f238ae.b19628"]]},{"id":"3600b80e.b52628","type":"ui_chart","z":"16657f26.bd82f1","name":"Watts","group":"e4992359.570b9","order":14,"width":0,"height":0,"label":"Watts","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"","ymax":"1000","removeOlder":"6","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#f31212","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"x":1230,"y":760,"wires":[[]]},{"id":"257ac191.19b34e","type":"change","z":"16657f26.bd82f1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.totalload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1060,"y":760,"wires":[["3600b80e.b52628"]]},{"id":"b8f54e55.0803c","type":"ui_text","z":"16657f26.bd82f1","group":"e4992359.570b9","order":6,"width":0,"height":0,"name":"From Total","label":"Total usage from:","format":"{{msg.date}}","layout":"row-spread","x":1250,"y":800,"wires":[]},{"id":"fbb3b605.ee8468","type":"function","z":"16657f26.bd82f1","name":"Date format","func":"var date = msg.payload.GlobalMeasure.EnergyStart;\nvar x  = Date.parse(date);\nvar y = new Date(x);\nmsg.date = y.getDate() + \"/\" + y.getMonth()+ \"/\" +y.getFullYear();\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1070,"y":800,"wires":[["b8f54e55.0803c"]]},{"id":"e4992359.570b9","type":"ui_group","name":"Computer","tab":"2eccf0c5.1c97b","order":1,"disp":true,"width":8,"collapse":false},{"id":"2eccf0c5.1c97b","type":"ui_tab","name":"Computer","icon":"dashboard","order":9,"disabled":false,"hidden":false}]

Flow Info

Created 4 years, 8 months ago
Updated 3 years, 4 months ago
Rating: not yet rated

Actions

Rate:

Node Types

Core
  • change (x2)
  • comment (x1)
  • debug (x1)
  • delay (x2)
  • function (x18)
  • http in (x1)
  • http request (x4)
  • http response (x2)
  • inject (x5)
  • switch (x1)
Other
  • subflow (x2)
  • subflow:1fe6aa28.98d036 (x1)
  • subflow:b44411e6.28ae6 (x1)
  • tab (x1)
  • ui_button (x2)
  • ui_chart (x2)
  • ui_gauge (x1)
  • ui_group (x1)
  • ui_switch (x1)
  • ui_tab (x1)
  • ui_text (x8)
  • ui_toast (x1)
  • wake on lan (x1)

Tags

  • netio
  • dashboard
  • power
  • wol
  • sleep
  • restart
  • control
  • pc
  • cost
  • uptime
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option