I should say that it seems "obvious" that we're killing the other alarms due to the ": null" at the end of the syntax, but what else can I put there? We tried putting in ": alarm" but it says the variable is undefined.
Can you check if alarm exists then if it does concatenate the string with your other value and a comma?
Like check the value of the alarm? An interesting approach; I wasn't aware multiple alarms could stack.
I'm also not sure the sequence of attribute computation of in-built attributes vs. computed attributes. I'm assuming computed attributes fire first since the in-built ones get nulled out.
This is a complete hack because I used bluelaser's idea and another recent post about alarms and chucked it into ChatGPT 5.2.
It works, but I need a lot of coffee in the morning to get my head around it. Also I'm too tired to format and indent it for now.
( (alarm ? alarm : "") + ((power >= 2 && power <= 10) ? ((alarm ? alarm : "").length() > 0 ? ",lowPower" : "lowPower") : "" ) + ((battery < 3.5) ? ( ( (alarm ? alarm : "").length() > 0 || (power >= 2 && power <= 10) ) ? ",lowBattery" : "lowBattery" ) : "" ) ).length() > 0 ? ( (alarm ? alarm : "") + ((power >= 2 && power <= 10) ? ((alarm ? alarm : "").length() > 0 ? ",lowPower" : "lowPower") : "" ) + ((battery < 3.5) ? ( ( (alarm ? alarm : "").length() > 0 || (power >= 2 && power <= 10) ) ? ",lowBattery" : "lowBattery" ) : "" ) ) : null
I also think ChatGPT has been excessively verbose so for now I'd just treat it as a "this works" rather than "this is elegant".
OK bugger it I just needed to paste it with formatting. Sorry, it's like midnight here.
(
(alarm ? alarm : "") +
((power >= 2 && power <= 10)
? ((alarm ? alarm : "").length() > 0 ? ",lowPower" : "lowPower")
: ""
) +
((battery < 3.5)
? (
(
(alarm ? alarm : "").length() > 0 ||
(power >= 2 && power <= 10)
)
? ",lowBattery"
: "lowBattery"
)
: ""
)
).length() > 0 ? (
(alarm ? alarm : "") +
((power >= 2 && power <= 10)
? ((alarm ? alarm : "").length() > 0 ? ",lowPower" : "lowPower")
: ""
) +
((battery < 3.5)
? (
(
(alarm ? alarm : "").length() > 0 ||
(power >= 2 && power <= 10)
)
? ",lowBattery"
: "lowBattery"
)
: ""
)
) : null
I wouldn't use LLMs for anything JEXL by the way, they mostly spit out garbage. I use this site for testing: https://czosel.github.io/jexl-playground/
Wouldn't it be better to setup the parameters device side though and generate a separate high priority event for each of these?
The parameters in question here for the lowBattery and lowPower alarm aren't something I have the spare Custom Scenarios in Teltonika devices available to configure that. We heavily use Custom Scenarios for other stuff so I won't be consuming two of the three available just for some voltage alarms.
As for LLMs, I don't trust them either, but for the purposes of working towards closure on this post so Anton doesn't need to get involved, it's nice to show progress. I'll tidy it up. We already do a lot of code changes to Traccar for our service, so this is all temporary until we work down our list of priorities and add our own Alarms and Notifications outside of Traccar currently supports.
You don't need custom scenarios, just set the high and low level in the I/O settings in the configurator with the priority set to high.
I think what you're saying is that by setting the priority to High it sends the parameter data but also because it was triggered by a High Priority it also sends the parameter ID as the Event ID. I actually use this a lot elsewhere but didn't think of it for this.
Sure, we could use that and it will make the JEXL shorter. We'll still need to have the computed attribute assign the alarm status based on these. Been a bit busy over the last few days; we'll get around to a tidy computed attribute some time next week.
The main advantage is because it will send a separate event you don't have to handle 2 alarms at once. So let's say you have a power cut followed by low battery your user can get 2 messages easily rather than you having to handle edge cases where you're trying to deal with multiple alarms in a single message.
In that case you're referring to the tidy up I haven't gotten to yet. :D
Rolling back around to this, bluelaser's logic here works really well.
Case in point - we have customers with both 12v and 24v vehicles. If I want the low power alarm for any vehicle type and I'm doing it using calculations in computed attributes (i.e. "power < 10") I have to create logic inside Traccar to correctly alarm based on what type of device it is.
If we change our alarm computed attribute to just check for event with a value of 66, and change our I/O parameter "External Voltage" to only trigger when the value enters the voltage range we mark as "low", then we just have separate configs we push to our trackers - which we already do, oddly enough.
In our case, everything below 2 volts we're handling via the Teltonika Power Cut detection feature. Arguably we could make our low voltage something like 0.5 volts I guess.
Teltonika devices used by our customers need the Low Power and Low Battery alarms to work and these are not defined in the Teltonika Decoder. However we understand these are tricky because what constitutes low power differs for a 12v or 24v system, and what constitutes low battery differs across Teltonika models (e.g. the TAT240 has an in-built non-rechargeable 7.2v battery).
So, we have created the following computed attribute called "Teltonika Alarms" which writes strings into the "Alarm" attribute:
This works for these two alarm types, but it kills all in-built alarms handled by Traccar already for teltonika devices such as:
So, what's possible here? Can we tweak this syntax so it doesn't stop other alarms, or does my computed attribute have to be coded to handle all alarms? Handling all alarms in the computed attribute is a problem because the raw attributes used by these are essentially captured by the teltonika decoder and don't appear to be accessible (e.g. io175 for the Geofence alarms, io252 for the Power Cut alarm, etc).