Hi everyone,
as I promised in another thread, I’m posting the code for using Node-Red to pull data from AutoPi API.
First part is getting your token (that expires every few hours), device_id and unit_id.
This you can get with:
[{“id”:“207111fc.39d516”,“type”:“http request”,“z”:“de854356.27206”,“name”:“login”,“method”:“POST”,“ret”:“obj”,“url”:“https://api.autopi.io/auth/login/",“tls”:"",“x”:310,“y”:760,“wires”:[[“377eeb2a.982804”]]},{“id”:“be7c6baa.bdb1f8”,“type”:“inject”,“z”:“de854356.27206”,“name”:"send login data”,“topic”:"",“payload”:"{“email”:“your@email.domain”,“password”:“YourVeryStrongPassword”}",“payloadType”:“json”,“repeat”:“14400”,“crontab”:"",“once”:false,“onceDelay”:0.1,“x”:130,“y”:760,“wires”:[[“207111fc.39d516”]]},{“id”:“377eeb2a.982804”,“type”:“function”,“z”:“de854356.27206”,“name”:“saveLoginInfo”,“func”:“var token = { payload: msg.payload.token };\nflow.set(“currentToken”, token.payload);\nvar deviceid = { payload: msg.payload.user.devices[0].id };\nflow.set(“device_id”, deviceid.payload);\nvar unitid = { payload: msg.payload.user.devices[0].unit_id };\nflow.set(“unit_id”, unitid.payload);\nreturn [token, deviceid, unitid];”,“outputs”:3,“noerr”:0,“x”:460,“y”:760,“wires”:[[“c615b916.6045”],[“162f9b50.f8c3a5”],[“d15b94d.563ad68”]],“outputLabels”:[“token”,“device_id”,“unit_id”]},{“id”:“c615b916.6045”,“type”:“debug”,“z”:“de854356.27206”,“name”:“token”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“x”:650,“y”:700,“wires”:[]},{“id”:“162f9b50.f8c3a5”,“type”:“debug”,“z”:“de854356.27206”,“name”:“device_id”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“x”:660,“y”:740,“wires”:[]},{“id”:“d15b94d.563ad68”,“type”:“debug”,“z”:“de854356.27206”,“name”:“unit_id”,“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“x”:650,“y”:780,“wires”:[]}]
The main part is this:
[{“id”:“b46446ff.a25058”,“type”:“moment”,“z”:“de854356.27206”,“name”:"-1h",“topic”:"",“input”:"",“inputType”:“date”,“inTz”:“Europe/Ljubljana”,“adjAmount”:“1”,“adjType”:“hours”,“adjDir”:“subtract”,“format”:“ISO8601”,“locale”:“C”,“output”:“from_utc”,“outputType”:“msg”,“outTz”:“Europe/Ljubljana”,“x”:610,“y”:860,“wires”:[[“24d252b1.194726”]]},{“id”:“bc886b32.2beae8”,“type”:“inject”,“z”:“de854356.27206”,“name”:“batt_power+current+volts”,“topic”:"",“payload”:“soc_display!batt_power!batt_current!batt_volts”,“payloadType”:“str”,“repeat”:“5”,“crontab”:"",“once”:false,“onceDelay”:0.1,“x”:160,“y”:880,“wires”:[[“72f326f4.de27a”]]},{“id”:“88629479.a89ca”,“type”:“www-request”,“z”:“de854356.27206”,“name”:“get data”,“method”:“GET”,“ret”:“obj”,“url”:"",“follow-redirects”:true,“tls”:"",“x”:360,“y”:980,“wires”:[[“d9540f9e.84663”]]},{“id”:“24d252b1.194726”,“type”:“function”,“z”:“de854356.27206”,“name”:“storage > read > list (get PID)”,“func”:“msg.headers = {};\nmsg.headers[‘Authorization’] = 'bearer '+flow.get(“currentToken”);\nmsg.device_id = flow.get(“device_id”);\n//msg.url = “https://api.autopi.io/logbook/storage/read/?from_utc="+msg.from_utc+"&"+“field=obd.batt_power.value”+"&"+“field_type=json”+"&"+“device_id=”+flow.get(“device_id”)+"&"+“interval=1s”+"&"+"end_utc=now”;\nmsg.url = “https://api.autopi.io/logbook/storage/read/?from_utc="+msg.from_utc+"&"+“field=obd.”+msg.pid_id+".value"+"&"+“field_type=json”+"&"+“device_id=”+flow.get(“device_id”)+"&"+“interval=1s”+"&"+“end_utc=now”;\nreturn msg;”,“outputs”:1,“noerr”:0,“x”:550,“y”:920,“wires”:[[“88629479.a89ca”]]},{“id”:“d9540f9e.84663”,“type”:“function”,“z”:“de854356.27206”,“name”:“dataProcessor”,“func”:”// poglej če ima array vsaj 1 podatek, če ne, vrni null\nvar outraw = {}\nvar textout = {}\nif (msg.payload.length >= 1){\n // battery power v kW (V*A)\n if (msg.pid_id == “batt_power”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null; //{ payload: “Trenutna moč: " + msg.payload[msg.payload.length-1].value.toFixed(2) + " kW” };\n }\n // battery tok v A\n else if (msg.pid_id == “batt_current”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // battery tok v V\n else if (msg.pid_id == “batt_volts”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // SOC display\n else if (msg.pid_id == “soc_display”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = { payload: “Stanje akumulatorja: " + msg.payload[msg.payload.length-1].value.toFixed(2) + " %” };\n }\n // battery SOH\n else if (msg.pid_id == “soh”){\n outraw.payload = Number(msg.payload[msg.payload.length-1].value.toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 1\n else if (msg.pid_id == “batt_temp1”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 2\n else if (msg.pid_id == “batt_temp2”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 3\n else if (msg.pid_id == “batt_temp3”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 4\n else if (msg.pid_id == “batt_temp4”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 5\n else if (msg.pid_id == “batt_temp5”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 6\n else if (msg.pid_id == “batt_temp6”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 7\n else if (msg.pid_id == “batt_temp7”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 8\n else if (msg.pid_id == “batt_temp8”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 9\n else if (msg.pid_id == “batt_temp9”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 10\n else if (msg.pid_id == “batt_temp10”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 22\n else if (msg.pid_id == “batt_temp11”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n // temperatura sklopa 23\n else if (msg.pid_id == “batt_temp12”){\n outraw.payload = Number((msg.payload[msg.payload.length-1].value).toFixed(2));\n outraw.topic = “stat/autopi/”+msg.pid_id;\n textout = null;\n }\n else {\n outraw = null;\n textout = null;\n }\n}\nelse {\n outraw = null;\n textout = null;\n}\nreturn [outraw, textout]",“outputs”:2,“noerr”:0,“x”:560,“y”:980,“wires”:[[“56aad096.3322c8”,“720b7c4d.3962b4”],[“4182ad79.fe7c4c”,“865643df.82c22”]],“outputLabels”:[“outRaw”,“TelegramOut”]},{“id”:“720b7c4d.3962b4”,“type”:“mqtt out”,“z”:“de854356.27206”,“name”:“AutoPi out”,“topic”:"",“qos”:“0”,“retain”:“false”,“broker”:“9c9e2d3f.25de88”,“x”:950,“y”:960,“wires”:[]},{“id”:“56aad096.3322c8”,“type”:“debug”,“z”:“de854356.27206”,“name”:"",“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“x”:770,“y”:920,“wires”:[]},{“id”:“bc11f57a.a03c5”,“type”:“change”,“z”:“de854356.27206”,“name”:“move to pid_id”,“rules”:[{“t”:“move”,“p”:“payload”,“pt”:“msg”,“to”:“pid_id”,“tot”:“msg”}],“action”:"",“property”:"",“from”:"",“to”:"",“reg”:false,“x”:420,“y”:860,“wires”:[[“b46446ff.a25058”]]},{“id”:“316b2d84.64e75a”,“type”:“telegrambot-notify”,“z”:“de854356.27206”,“name”:“IoniqBot”,“bot”:“6776ad8c.1cf8e4”,“chatId”:“chatID”,“message”:"",“parseMode”:"",“x”:940,“y”:1020,“wires”:[]},{“id”:“4182ad79.fe7c4c”,“type”:“rbe”,“z”:“de854356.27206”,“name”:"",“func”:“rbei”,“gap”:"",“start”:"",“inout”:“out”,“property”:“payload”,“x”:770,“y”:1020,“wires”:[[“316b2d84.64e75a”]]},{“id”:“8ff29e2.7c3876”,“type”:“inject”,“z”:“de854356.27206”,“name”:"",“topic”:"",“payload”:“soh”,“payloadType”:“str”,“repeat”:“3600”,“crontab”:"",“once”:false,“onceDelay”:0.1,“x”:90,“y”:960,“wires”:[[“bc11f57a.a03c5”]]},{“id”:“865643df.82c22”,“type”:“debug”,“z”:“de854356.27206”,“name”:"",“active”:false,“tosidebar”:true,“console”:false,“tostatus”:false,“complete”:“true”,“targetType”:“full”,“x”:770,“y”:1060,“wires”:[]},{“id”:“12770b91.f25e04”,“type”:“inject”,“z”:“de854356.27206”,“name”:“batt_temp1-12”,“topic”:"",“payload”:“batt_temp1!batt_temp2!batt_temp3!batt_temp4!batt_temp5!batt_temp6!batt_temp7!batt_temp8!batt_temp9!batt_temp10!batt_temp11!batt_temp12”,“payloadType”:“str”,“repeat”:“30”,“crontab”:"",“once”:false,“onceDelay”:0.1,“x”:120,“y”:920,“wires”:[[“72f326f4.de27a”]]},{“id”:“72f326f4.de27a”,“type”:“split”,“z”:“de854356.27206”,“name”:"",“splt”:"!",“spltType”:“str”,“arraySplt”:1,“arraySpltType”:“len”,“stream”:false,“addname”:"",“x”:290,“y”:920,“wires”:[[“bc11f57a.a03c5”]]},{“id”:“9c9e2d3f.25de88”,“type”:“mqtt-broker”,“z”:"",“name”:“HASS”,“broker”:“localhost”,“port”:“1883”,“clientid”:“node-red”,“usetls”:false,“compatmode”:true,“keepalive”:“60”,“cleansession”:true,“birthTopic”:"",“birthQos”:“0”,“birthPayload”:"",“closeTopic”:"",“closeQos”:“0”,“closePayload”:"",“willTopic”:"",“willQos”:“0”,“willPayload”:""},{“id”:“6776ad8c.1cf8e4”,“type”:“telegrambot-config”,“z”:"",“botname”:“IoniqBot”,“usernames”:"",“chatIds”:"",“pollInterval”:“300”}]
I hope I didn’t reveal too much personal info in here, I was in a bit of a hurry
If there is anything else you’d like to know, just ask.
And sorry about comments, they’re in Slovenian language. It’s not so hard to understand I hope (the code is mostly using variables named in English).
One more thing, battery power, battery current and battery voltage are requested every 5 seconds.
Battery temperatures of modules 1 through 12 are requested every 30 seconds, state of health is requested every hour.