Charger Performance with Tasker
This project measures charging speeds of various chargers and draws curves of the charge profiles. It gathers information via Tasker and uses Dashboard to display it.
Features:
- charging curves
- total charge time
- charger score
- multiple chargers and phones supported
- record managment: draw/delete/clear
Requirements
- node-red-contrib-dashboard
- node-red-node-ui-table
- Tasker installed on Android device
Settings
- CT_PhoneData set details of your phone and HTTP credentials in this Tasker task first.
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":"38387c2e.5b3764","type":"tab","label":"Charger Test","disabled":false,"info":"![enter image description here](https://notenoughtech.com/wp-content/uploads/2017/08/thumbnail.jpg)\nThis project measures charging speeds of various chargers and draws curves of the charge profiles. It gathers information via Tasker and uses Dashboard to display it.\n\n - [Complete instructions](https://notenoughtech.com/tasker/tasker-total-charging-time-project-test-chargers/)\n\n**Features**:\n- **charging curves**\n- **total charge time**\n- **charger score**\n- **multiple chargers and phones supported**\n- **record managment: draw/delete/clear**\n\n\n## Requirements\n\n - node-red-contrib-dashboard\n - node-red-node-ui-table\n - Tasker installed on Android device\n\n\n# Settings\n\n - **CT_PhoneData** set details of your phone and HTTP credentials in this Tasker task first.\n \n ## More about me:\n\nIf you want to get the latest updates to this project you can follow me via your preferred social media:\n\n- [Facebook](https://www.facebook.com/NotEnoughTECH/)\n- [Twitter](https://twitter.com/NotEnoughTECH)\n- [Instagram](https://www.instagram.com/notenoughtech/)\n- [YouTube](https://www.youtube.com/user/Polepositionpage)\n\nAnd if you feeling like buying me a coffee or supporting me in a more continuous way:\n\n- [Paypal](https://www.paypal.me/notenoughtech)\n- [Patreon](https://www.patreon.com/NotEnoughTECH)\n\nI hope you have enjoyed the project!"},{"id":"1bf473a9.3af3ac","type":"group","z":"38387c2e.5b3764","name":"User Interface","style":{"label":true,"fill":"#e3f3d3"},"nodes":["de692c8e.7149a","8133fc9.5e72f","95c3ba63.9dec88","3d6b873b.ca1068","7cafb6b9.9bd0c8","b893e3e6.12b0f","92f413cb.4ee0c","6c60ed5b.2f5d84","64fc809.a7a668","432f0b9f.1ca2f4","3fc6112e.a6179e","c3fefe14.c14cc","d9effcb1.b4df3","68395b1.30f2ca4","7ccf6d01.ee9204","df4b776e.135918","8574e056.c70bc","441bea06.bd51e4","68cd8d36.b48dd4","ea7409af.c4a988","a3ced19.7d6763"],"x":594,"y":119,"w":762,"h":342},{"id":"4f94bc50.0a5624","type":"http in","z":"38387c2e.5b3764","name":"","url":"/charger","method":"post","upload":false,"swaggerDoc":"","x":110,"y":320,"wires":[["cf74b415.1f1338","ee4db074.fce2e","adc24b7b.0f9b88"]]},{"id":"cf74b415.1f1338","type":"http response","z":"38387c2e.5b3764","name":"","statusCode":"","headers":{},"x":330,"y":260,"wires":[]},{"id":"ee4db074.fce2e","type":"function","z":"38387c2e.5b3764","name":"Chart format","func":"function sec2min(ms){\n sec = Math.floor(ms /1000)\n let min = Math.floor(sec/60);\n let s = sec%60;\n if(s < 10){s = \"0\"+s;}\n time = min + \":\" + s;\n return time;\n}\n\n// add new data to the array\nvar ChargeData = flow.get(\"ChargeData\");\nvar data = msg.payload;\nChargeData.push(data);\nflow.set(\"ChargeData\", ChargeData);\n\nvar dataSeries =[]; \nvar dataLabels=[];\nvar dataData =[];\nvar array = {};\nvar arrayTime = [];\nvar arrayLevel = [];\n\nfor(var x in data.timestamp){\n let level = data.level[x];\n let time = sec2min(data.timestamp[x]-data.chargeStart);\n arrayLevel.push(level);\n arrayTime.push(time);\n}\n dataSeries.push(data.name);\n dataData.push(arrayLevel);\n dataLabels = arrayTime;\n\n\n\n// chart formated data\narray.series = dataSeries; // topic chargers names\narray.data = dataData; // levels of the battery\narray.labels = dataLabels; //time time \n\n\n\nreturn {payload:[array]};\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":350,"y":300,"wires":[["c76721c3.9c31e"]]},{"id":"adc24b7b.0f9b88","type":"function","z":"38387c2e.5b3764","name":"Table format","func":"var chargers = flow.get(\"chargers\");\n\nif(chargers === undefined){\n chargers = [];\n}\n\n//delete and update the table\nif(msg.topic === \"delete\"){\n msg.payload = chargers;\n flow.set(\"chargers\", chargers);\n return msg;\n}\n// add new record to the table\n\nvar data = msg.payload;\nvar update = { \"Charger name\": data.name,\n \"Phone name\": data.phone,\n \"charging protocol\": data.proto,\n \"battery (mAh)\": data.battery ,\n \"charge time\": data.chargeDelta,\n \"score (mAh/min)\": data.score\n };\n\nchargers.push(update);\nflow.set(\"chargers\", chargers);\nvar msg1 = {payload: []};\nvar msg2 = {payload: chargers};\n\nreturn [[msg1,msg2]];\n\n \n","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n\nvar array = [];\nvar x = flow.get(\"chargers\");\nif (x === undefined){\n flow.set(\"chargers\", array); \n}\n \nvar array2 = [];\nvar y = flow.get(\"ChargeData\");\nif (y === undefined){\n flow.set(\"ChargeData\", array2);\n}\n\nvar array3 = [];\nvar z = flow.get(\"selection\");\nif (z === undefined){\n flow.set(\"selection\", array3);\n}\n ","finalize":"","x":350,"y":340,"wires":[["5ba2af25.252dd"]]},{"id":"c3fefe14.c14cc","type":"change","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"str"},{"t":"set","p":"selection","pt":"flow","to":"[]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":1180,"y":420,"wires":[["7ccf6d01.ee9204"]]},{"id":"de692c8e.7149a","type":"ui_dropdown","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","label":"","tooltip":"","place":"Select dataset","group":"3d9e45e.bcd50ba","order":2,"width":0,"height":0,"passthru":false,"multiple":true,"options":[],"payload":"","topic":"topic","topicType":"msg","x":980,"y":280,"wires":[["3fc6112e.a6179e"]]},{"id":"8133fc9.5e72f","type":"inject","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":690,"y":280,"wires":[["95c3ba63.9dec88"]]},{"id":"95c3ba63.9dec88","type":"function","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"Make list","func":"var chargedata = flow.get(\"ChargeData\");\nvar data =[];\n\n\nfor(let x =0; x < chargedata.length; x++ ){\n let y = chargedata[x].name;\n let z = {};\n z[y] = x;\n data.push(z);\n}\n\nmsg.options = data;\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":840,"y":280,"wires":[["de692c8e.7149a"]]},{"id":"3d6b873b.ca1068","type":"function","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"Send data","func":"var action = msg.payload;\nvar selection = flow.get(\"selection\");\nvar data = flow.get(\"ChargeData\");\nvar dataChargers = flow.get(\"chargers\");\n\nfunction sec2min(ms){\n sec = Math.floor(ms /1000)\n let min = Math.floor(sec/60);\n let s = sec%60;\n if(s < 10){s = \"0\"+s;}\n time = min + \":\" + s;\n return time;\n}\n\n// if selection is valid and action is to display chart (true)\nif(selection.length > 0){\n if(action === true){\n \n var index = selection;\n var dataSeries =[]; \n var dataLabels=[];\n var dataData =[];\n var array = {};\n \n for(var i =0; i<index.length; i++){\n var datatimestamp = data[index[i]].timestamp;\n var datalevel = data[index[i]].level;\n var labels = data[index[i]].name;\n var arrayTime = [];\n var arrayLevel = [];\n \n for(var x in datatimestamp){\n let level = datalevel[x];\n let time = sec2min(datatimestamp[x]-data[index[i]].chargeStart);\n arrayLevel.push(level);\n arrayTime.push(time);\n }\n dataSeries.push(data[index[i]].name);\n dataData.push(arrayLevel);\n dataLabels = arrayTime;\n }\n array.series = dataSeries; // topic chargers names\n array.data = dataData; // levels of the battery\n array.labels = dataLabels; //time time \n \n return [{payload:[array]}, null];\n }\n if(action === false) {\n for( var r = 0; r < selection.length; r++){\n //remove and squash chargedata\n delete data[selection[r]];\n var squash1 = data.filter(function (el) {return el != null;});\n flow.set(\"ChargeData\", squash1);\n //remove and squash charger info\n delete dataChargers[selection[r]];\n var squash2 = dataChargers.filter(function (el) {return el != null;});\n flow.set(\"chargers\", squash2);\n msg.topic = \"delete\";\n }\n return[null, msg];\n }\n}\n\n\n\nvar filtered = array.filter(function (el) {\n return el != null;\n});","outputs":2,"noerr":0,"initialize":"","finalize":"","x":1170,"y":320,"wires":[["a3ced19.7d6763"],["68395b1.30f2ca4"]]},{"id":"7cafb6b9.9bd0c8","type":"ui_chart","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","group":"3d9e45e.bcd50ba","order":1,"width":0,"height":0,"label":"Charging curve","chartType":"line","legend":"true","xformat":"mm:ss","interpolate":"bezier","nodata":"Select Charging data","dot":false,"ymin":"","ymax":"110","removeOlder":"0","removeOlderPoints":"1000","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"x":1220,"y":160,"wires":[[]]},{"id":"b893e3e6.12b0f","type":"ui_button","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","group":"3d9e45e.bcd50ba","order":6,"width":4,"height":1,"passthru":false,"label":"Clear Chart","tooltip":"","color":"","bgcolor":"pink","icon":"","payload":"[]","payloadType":"json","topic":"topic","topicType":"msg","x":810,"y":160,"wires":[["441bea06.bd51e4"]]},{"id":"92f413cb.4ee0c","type":"ui_table","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","group":"3d9e45e.bcd50ba","name":"","order":7,"width":12,"height":5,"columns":[],"outputs":0,"cts":false,"x":1190,"y":200,"wires":[]},{"id":"6c60ed5b.2f5d84","type":"ui_button","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","group":"3d9e45e.bcd50ba","order":8,"width":7,"height":1,"passthru":false,"label":"Clear Whole Table","tooltip":"","color":"","bgcolor":"pink","icon":"","payload":"[]","payloadType":"json","topic":"topic","topicType":"msg","x":790,"y":200,"wires":[["68cd8d36.b48dd4"]]},{"id":"64fc809.a7a668","type":"ui_button","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","group":"3d9e45e.bcd50ba","order":5,"width":8,"height":1,"passthru":false,"label":"Add to Chart","tooltip":"","color":"","bgcolor":"green","icon":"","payload":"true","payloadType":"bool","topic":"topic","topicType":"msg","x":970,"y":340,"wires":[["3d6b873b.ca1068"]]},{"id":"432f0b9f.1ca2f4","type":"ui_button","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","group":"3d9e45e.bcd50ba","order":9,"width":5,"height":1,"passthru":false,"label":"Remove Selected Records","tooltip":"","color":"","bgcolor":"red","icon":"","payload":"false","payloadType":"bool","topic":"topic","topicType":"msg","x":920,"y":380,"wires":[["3d6b873b.ca1068"]]},{"id":"3fc6112e.a6179e","type":"function","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"Save selection","func":"flow.set(\"selection\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1180,"y":280,"wires":[[]]},{"id":"d9effcb1.b4df3","type":"link in","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["68395b1.30f2ca4"],"x":1015,"y":420,"wires":[["c3fefe14.c14cc"]]},{"id":"68395b1.30f2ca4","type":"link out","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["d9effcb1.b4df3","ff8d0b6e.1c3a58"],"x":1315,"y":360,"wires":[]},{"id":"df4b776e.135918","type":"link in","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["7ccf6d01.ee9204","c76721c3.9c31e"],"x":715,"y":340,"wires":[["95c3ba63.9dec88"]]},{"id":"7ccf6d01.ee9204","type":"link out","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["df4b776e.135918"],"x":1315,"y":420,"wires":[]},{"id":"ff8d0b6e.1c3a58","type":"link in","z":"38387c2e.5b3764","name":"","links":["68395b1.30f2ca4"],"x":215,"y":380,"wires":[["adc24b7b.0f9b88"]]},{"id":"c76721c3.9c31e","type":"link out","z":"38387c2e.5b3764","name":"","links":["8574e056.c70bc","df4b776e.135918"],"x":475,"y":300,"wires":[]},{"id":"8574e056.c70bc","type":"link in","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["c76721c3.9c31e","441bea06.bd51e4","a3ced19.7d6763"],"x":1035,"y":160,"wires":[["7cafb6b9.9bd0c8"]]},{"id":"441bea06.bd51e4","type":"link out","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["8574e056.c70bc"],"x":935,"y":160,"wires":[]},{"id":"ea7409af.c4a988","type":"link in","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["68cd8d36.b48dd4","5ba2af25.252dd"],"x":1035,"y":200,"wires":[["92f413cb.4ee0c"]]},{"id":"68cd8d36.b48dd4","type":"link out","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["ea7409af.c4a988"],"x":935,"y":200,"wires":[]},{"id":"5ba2af25.252dd","type":"link out","z":"38387c2e.5b3764","name":"","links":["ea7409af.c4a988"],"x":475,"y":340,"wires":[]},{"id":"a3ced19.7d6763","type":"link out","z":"38387c2e.5b3764","g":"1bf473a9.3af3ac","name":"","links":["8574e056.c70bc"],"x":1315,"y":300,"wires":[]},{"id":"3d9e45e.bcd50ba","type":"ui_group","name":"Charging Stats","tab":"f484a0a.6c67a6","order":1,"disp":true,"width":"12","collapse":false},{"id":"f484a0a.6c67a6","type":"ui_tab","name":"Charging Profiles","icon":"dashboard","disabled":false,"hidden":false}]