Use Tronity API to extract car data into sensors using Node-Red

Put Debug 2 on Get data. This should return all the Tronity data. IF that’s OK . I supect you will need to relink Home assistant nodes (blue ones)

This should create the entities in Home Assistant via the Node-Red Companion App

Home assistant Settings->Devices & Services Node-RED Companion

image

Looking again at your screenshot its like you are not collecting data . If you are getting an access token . Are you sure your Car ID is correct . That is used in the Build API node . You will find that in the Tronity development app https://app.tronity.tech/

open the TRONITY Extension and its listed in Assigned Vehicles that need to be in the Tronity params flow.car

Programmers should never write documentation :slight_smile:

I’ve contacted Tronity, because of the missing data, they told me that we are using the old API, and we should take a look at the new one.

1 Like

Thankyou :wink: Just looking at the api now. Not a lot of change . Just testing now

this look like the data we can pull

{
“odometer”: 0,
“range”: 0,
“level”: 0,
“charging”: “Error”,
“chargeRemainingTime”: 0,
“plugged”: true,
“chargerPower”: 0,
“latitude”: 0,
“longitude”: 0,
“timestamp”: 0,
“lastUpdate”: 0
}

Testing now will add the folllwing enties to the flow

“chargePower”: ,
“chargeRemainingTime”: ,

Does the flow change a lot?
Not really familiar with nodered yet.

Updated to v1.0 of Tronity API

This is awesome! Thank you very much for providing the flow, which enabled me to get data from my Cupra Born within minutes.

1 Like

Got it all working (eventually), “anonymised” all the sensors so I can keep the same things in HA if/when we update car again, and mostly super happy with the result.

I want to (somewhat) replicate the Tronity phone app “dashboard” in HA, and the only thing I don’t yet know how to do is “Status” (Parked or Driving), based on whether the Lat/Long has changed since the last data packet was received.

If anyone can point me in the right direction, I’d be ever so grateful?

Glad the flow proved useful :slight_smile:

The flow creates a standard device tracker. Not sure how often your car updates this sensor, my Corsa only updates it’s position when it stops and starts. I have just created Zones in area/zones in the setting menu on HA. The sensor will then report on the cars position by name depending on which zone its in . i.e. Work, Home, Shops, Gym, etc

Check if the last update sensor is useful . Again my Corsa only updates this when something happens , starts, stop, Charging , force update on the car app, etc. If this sensor is quiet for a period time then the car is parked ? or simply create two template sensors to hold the current and previous gps positions and compare the two every say 10 mins. If different the cars moving , the same parked

Yeah, I’ve spent an instructive afternoon bouncing between Node-Red, it’s docs, and the Tronity docs. The Tronity docs are the least useful bit of that lot, TBH; the return payload has “status” in it, but it’s null (and I’m in no position to be driving the car around while checking the debug output in Node-Red to see if it changes :rofl: :rofl: ), so I’ve made a function to change that null into “Parked” (or “Driving” if it’s not null). Good enough for my purposes, it should only ever be “Parked”.

Well, you can forget about all that “status” nonsense I mentioned above; I have finally discovered the Map card in the HA dashboard :rofl: :rofl:, and I just added one of those for my EV entity. It’ll be as up-to-date as Tronity’s data, and that is more than adequate for my needs.

In other “stuff” @lonebaggie - am I the only person getting an error in “Last Update”?

image

The exact error messages being:

The left-hand side of an arithmetic operation must be of type ‘any’, ‘number’, ‘bigint’ or an enum type.(2362)
The right-hand side of an arithmetic operation must be of type ‘any’, ‘number’, ‘bigint’ or an enum type.(2362)

No your right I have the same error , Im not a javscript programmer , just a good googler . Im sure this code worked when I wrote it . Think the last node red update may have broke it (my excuse) . I have re-googled another way of working out the number of hours between two dates . Replace

var nohr = Math.round(Math.abs(currentdate - date) / 36e5);

with

var diff = date.valueOf() - currentdate.valueOf();
var nohr = Math.round(Math.abs(diff / 1000 / 60 / 60)); // Convert milliseconds to hours

Let me know if this works for you , and I will update the flow

1 Like

Just to prove how bad I am at Javascript I have used date.getDay() instead of date.getDate() which returns the day of week (Sunday = 0) rather than day of the month. So the attribute Date is wrong as well !

Replace

var day = date.getDay().toString();

with

var day = date.getDate().toString();

The incorrect line “reads right” but is plain wrong

1 Like

As an “equally skilled javascript/Node-Red programmer”, you have nothing but sympathy from me.

I’d already changed over to using (a pair of) “Date/Time Formatter” nodes to turn payload.lastupdate into payload.date and payload.time (because if there’s a node to do a thing that understands about timezones and formatting, why wouldn’t I), and just before noticing your replies I had figured out a way to calculate payload.nohr, but using your code above (along with more playing on my part) I’ve been able to reduce the “Last Update” node to:

msg.payload.nohr = Math.round(Math.abs((Date.now() - msg.payload.lastUpdate) / 1000 / 60 / 60));

return msg;

(Forgive the manic “compression”)

Show off :slight_smile: I will incorporate your code into the flow , much neater.

Can you show me the nodes ?

Here’s my “Last Update” flow… Pretty sure this has things in you don’t want/need, but export confuses me (currently).

[{"id":"fe6d9e8dcf2b2dee","type":"moment","z":"3f3f5aae.72acee","name":"","topic":"","input":"payload.lastupdate","inputType":"msg","inTz":"Europe/London","adjAmount":"0","adjType":"days","adjDir":"add","format":"DD/MM/YYYY","locale":"en","output":"payload.date","outputType":"msg","outTz":"Europe/London","x":660,"y":940,"wires":[["8a1a41d1a366e928"]]},{"id":"8a1a41d1a366e928","type":"moment","z":"3f3f5aae.72acee","name":"","topic":"","input":"payload.lastupdate","inputType":"msg","inTz":"Europe/London","adjAmount":"0","adjType":"days","adjDir":"add","format":"HH:mm","locale":"en","output":"payload.time","outputType":"msg","outTz":"Europe/London","x":900,"y":940,"wires":[["966cba34f33efb05"]]},{"id":"966cba34f33efb05","type":"function","z":"3f3f5aae.72acee","name":"Last update ","func":"msg.payload.nohr = Math.round(Math.abs((Date.now() - msg.payload.lastUpdate) / 1000 / 60 / 60));\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1110,"y":940,"wires":[["421368e408165af5"]]},{"id":"421368e408165af5","type":"ha-sensor","z":"3f3f5aae.72acee","name":"Last Update","entityConfig":"8ae07a618641546e","version":0,"state":"payload.nohr","stateType":"msg","attributes":[{"property":"Date","value":"payload.date","valueType":"msg"},{"property":"Time","value":"payload.time","valueType":"msg"},{"property":"Last Update","value":"payload.lastUpdate","valueType":"msg"}],"inputOverride":"allow","outputProperties":[],"x":1290,"y":940,"wires":[[]]},{"id":"8ae07a618641546e","type":"ha-entity-config","server":"8c7ce533.7eba88","deviceConfig":"","name":"sensor config for Last Update","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"ev-lastupdate"},{"property":"icon","value":"mdi:clock-outline"},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":"hrs"},{"property":"state_class","value":""}],"resend":true,"debugEnabled":false},{"id":"8c7ce533.7eba88","type":"server","name":"Home Assistant","addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"","connectionDelay":false,"cacheJson":false,"heartbeat":false,"heartbeatInterval":"","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"","enableGlobalContextStore":false}]

The node is a part of node-red-contrib-moment (for anyone following along)…

As the PSA car controller is getting more and more unstable and feature castrated thanks to PSA/Stellantis, I looked for alternatives and stumbled upon this way thx to a workmate. It’s great to have quite some of the features back now and on a stable and rock solid API. Of course some things are still missing and the every three minutes API call is not that precise, too… So I went and asked the TRONITY support about the maximum API calls per day and if they plan to add stuff like controlling the air conditioning and less important things like GPS precision and battery voltage to the API. Or maybe even more.

I got a nice reply…

This might be interesting for @lonebaggie:
The recommended maximum is one API call per minute, so this could be increased in your template.

Regarding features for car controlling they are still discussing with PSA/Stellantis and hope to provide more features we know from the B2C and B2B APIs to TRONITY somewhere next year. Right now they have no access to the contol APIs YET. So lets hope for the best :smiley:

Thanks for info . I think the car is the issue . It only seem to update data when it starts or stops , or when you force an update from the app . Increasing the poll will make little difference as I don’t think tronity has the data.

Looking forward to more control :slight_smile:

Well in my case the tracking map gained quite more precision compared to before. Now it almost resembles the map of the TRONITY app.

1 Like