Unfortunately, we have many devices that either lack a connected accessory cable, have it connected to a permanent positive, or don't have the cable at all. The problem we face with this is that the ignition state never changes, and engine hours are not accumulated.
I want to know if what I did is risky for system stability. I sincerely hope it isn't. Here are the steps I took:
First, I created a new handler called StopTimeHandler
. Here's the code:
package org.traccar.handler;
import io.netty.channel.ChannelHandler;
import org.traccar.BaseDataHandler;
import org.traccar.model.Position;
import org.traccar.session.cache.CacheManager;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
@ChannelHandler.Sharable
public class StopTimeHandler extends BaseDataHandler {
private final CacheManager cacheManager;
private static final double MIN_SPEED_KNOTS = 2.7;
@Inject
public StopTimeHandler(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
protected Position handlePosition(Position position) {
Position last = cacheManager.getPosition(position.getDeviceId());
if (last != null) {
long stopTime = last.getLong(Position.KEY_STOP_TIME);
if (last.getSpeed() < MIN_SPEED_KNOTS && position.getSpeed() < MIN_SPEED_KNOTS) {
stopTime += position.getFixTime().getTime() - last.getFixTime().getTime();
} else {
stopTime = 0;
}
position.set(Position.KEY_STOP_TIME, stopTime);
}
return position;
}
}
I added the handler to BasePipelineFactory.java
.
I also added KEY_STOP_TIME
to Position.java
and within modern
I added stopTime
to usePositionAttributes.js
and the respective translation in the l10n
folder.
Finally, I created the following computed attribute:
Attribute: ignition
Expression: (speed > 2.7) || (speed <= 2.7 && (stopTime / 1000) <= 180)
What I am looking for with this rule is that for devices that do not have an ignition state, we can have a software approximation. In short, it does the following: When the speed is greater than 2.7 knots, it changes the ignition state to true. And when the speed is lower, and a prudent stop time has elapsed (in this case 180 seconds), it sets the ignition state to false. The idea of the seconds is to avoid false negatives when the vehicle is driving and stops at a traffic light (to give an example).
A note regarding BasePipelineFactory
: EngineHoursHandler
was before ComputedAttributesHandler
. That is, it first calculated the hours, and then the attributes. I modified this, placing EngineHoursHandler
after ComputedAttributesHandler
. The code looked something like this in that part:
```java
/*previous code*/
CopyAttributesHandler.class,
StopTimeHandler.class, // THIS IS NEW, I also import it above.
ComputedAttributesHandler.class,
EngineHoursHandler.class, // THIS IS WHAT I CHANGE PLACE.
PositionForwardingHandler.class,
/*remaining code*/
```
What I am looking for with this modification is that if there is a rule from computed attributes that modifies the ignition state, it can influence the calculation of engine hours. I know now we can't use engine hours for computed attributes, but that's ok.
The question is to know if this is risky for system stability. There have not been many changes, but only those necessary to somehow solve the problem I described at the beginning. We know that speed has no relation with a running engine, but in this case we are opting for the "lesser bad", since between not having ignition or engine hours, or having ignition and engine hours based on speed, we prefer the latter.
I look forward to your feedback. Thank you very much for your time.
Best regards!
Unfortunately, we have many devices that either lack a connected accessory cable, have it connected to a permanent positive, or don't have the cable at all. The problem we face with this is that the ignition state never changes, and engine hours are not accumulated.
I want to know if what I did is risky for system stability. I sincerely hope it isn't. Here are the steps I took:
First, I created a new handler called
StopTimeHandler
. Here's the code:package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.inject.Singleton; @Singleton @ChannelHandler.Sharable public class StopTimeHandler extends BaseDataHandler { private final CacheManager cacheManager; private static final double MIN_SPEED_KNOTS = 2.7; // speed threshold for being 'stopped' @Inject public StopTimeHandler(CacheManager cacheManager) { this.cacheManager = cacheManager; } @Override protected Position handlePosition(Position position) { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { long stopTime = last.getLong(Position.KEY_STOP_TIME); if (last.getSpeed() < MIN_SPEED_KNOTS && position.getSpeed() < MIN_SPEED_KNOTS) { stopTime += position.getFixTime().getTime() - last.getFixTime().getTime(); } else { stopTime = 0; } position.set(Position.KEY_STOP_TIME, stopTime); } return position; } }
I added the handler to
BasePipelineFactory.java
.I also added
KEY_STOP_TIME
toPosition.java
and withinmodern
I addedstopTime
tousePositionAttributes.js
and the respective translation in thel10n
folder.Finally, I created the following computed attribute:
Attribute:
ignition
Expression:
(speed > 2.7) || (speed <= 2.7 && (stopTime / 1000) <= 180)
What I am looking for with this rule is that for devices that do not have an ignition state, we can have a software approximation. In short, it does the following: When the speed is greater than 2.7 knots, it changes the ignition state to true. And when the speed is lower, and a prudent stop time has elapsed (in this case 180 seconds), it sets the ignition state to false. The idea of the seconds is to avoid false negatives when the vehicle is driving and stops at a traffic light (to give an example).
A note regarding
BasePipelineFactory
:EngineHoursHandler
was beforeComputedAttributesHandler
. That is, it first calculated the hours, and then the attributes. I modified this, placingEngineHoursHandler
afterComputedAttributesHandler
. The code looked something like this in that part:What I am looking for with this modification is that if there is a rule from computed attributes that modifies the ignition state, it can influence the calculation of engine hours. I know now we can't use engine hours for computed attributes, but that's ok.
The question is to know if this is risky for system stability. There have not been many changes, but only those necessary to somehow solve the problem I described at the beginning. We know that speed has no relation with a running engine, but in this case we are opting for the "lesser bad", since between not having ignition or engine hours, or having ignition and engine hours based on speed, we prefer the latter.
I look forward to your feedback. Thank you very much for your time.
Best regards!