aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/handler
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/handler')
-rw-r--r--src/main/java/org/traccar/handler/ComputedAttributesHandler.java24
-rw-r--r--src/main/java/org/traccar/handler/CopyAttributesHandler.java36
-rw-r--r--src/main/java/org/traccar/handler/DefaultDataHandler.java19
-rw-r--r--src/main/java/org/traccar/handler/DistanceHandler.java20
-rw-r--r--src/main/java/org/traccar/handler/EngineHoursHandler.java19
-rw-r--r--src/main/java/org/traccar/handler/FilterHandler.java153
-rw-r--r--src/main/java/org/traccar/handler/GeocoderHandler.java22
-rw-r--r--src/main/java/org/traccar/handler/GeolocationHandler.java45
-rw-r--r--src/main/java/org/traccar/handler/HemisphereHandler.java9
-rw-r--r--src/main/java/org/traccar/handler/MotionHandler.java16
-rw-r--r--src/main/java/org/traccar/handler/OpenChannelHandler.java14
-rw-r--r--src/main/java/org/traccar/handler/RemoteAddressHandler.java26
-rw-r--r--src/main/java/org/traccar/handler/SpeedLimitHandler.java7
-rw-r--r--src/main/java/org/traccar/handler/StandardLoggingHandler.java8
-rw-r--r--src/main/java/org/traccar/handler/TimeHandler.java19
-rw-r--r--src/main/java/org/traccar/handler/events/AlertEventHandler.java17
-rw-r--r--src/main/java/org/traccar/handler/events/BaseEventHandler.java17
-rw-r--r--src/main/java/org/traccar/handler/events/BehaviorEventHandler.java16
-rw-r--r--src/main/java/org/traccar/handler/events/CommandResultEventHandler.java10
-rw-r--r--src/main/java/org/traccar/handler/events/DriverEventHandler.java25
-rw-r--r--src/main/java/org/traccar/handler/events/FuelDropEventHandler.java70
-rw-r--r--src/main/java/org/traccar/handler/events/FuelEventHandler.java79
-rw-r--r--src/main/java/org/traccar/handler/events/GeofenceEventHandler.java74
-rw-r--r--src/main/java/org/traccar/handler/events/IgnitionEventHandler.java26
-rw-r--r--src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java44
-rw-r--r--src/main/java/org/traccar/handler/events/MediaEventHandler.java49
-rw-r--r--src/main/java/org/traccar/handler/events/MotionEventHandler.java132
-rw-r--r--src/main/java/org/traccar/handler/events/OverspeedEventHandler.java135
28 files changed, 642 insertions, 489 deletions
diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java
index 153da29b9..c9f1f63d7 100644
--- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java
+++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,28 +34,29 @@ import org.slf4j.LoggerFactory;
import org.traccar.BaseDataHandler;
import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.AttributesManager;
-import org.traccar.database.IdentityManager;
import org.traccar.model.Attribute;
import org.traccar.model.Device;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class ComputedAttributesHandler extends BaseDataHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(ComputedAttributesHandler.class);
- private final IdentityManager identityManager;
- private final AttributesManager attributesManager;
+ private final CacheManager cacheManager;
private final JexlEngine engine;
private final boolean includeDeviceAttributes;
- public ComputedAttributesHandler(
- Config config, IdentityManager identityManager, AttributesManager attributesManager) {
- this.identityManager = identityManager;
- this.attributesManager = attributesManager;
+ @Inject
+ public ComputedAttributesHandler(Config config, CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
engine = new JexlEngine();
engine.setStrict(true);
engine.setFunctions(Collections.singletonMap("math", Math.class));
@@ -65,7 +66,7 @@ public class ComputedAttributesHandler extends BaseDataHandler {
private MapContext prepareContext(Position position) {
MapContext result = new MapContext();
if (includeDeviceAttributes) {
- Device device = identityManager.getById(position.getDeviceId());
+ Device device = cacheManager.getObject(Device.class, position.getDeviceId());
if (device != null) {
for (Object key : device.getAttributes().keySet()) {
result.set((String) key, device.getAttributes().get(key));
@@ -104,8 +105,7 @@ public class ComputedAttributesHandler extends BaseDataHandler {
@Override
protected Position handlePosition(Position position) {
- Collection<Attribute> attributes = attributesManager.getItems(
- attributesManager.getAllDeviceItems(position.getDeviceId()));
+ Collection<Attribute> attributes = cacheManager.getDeviceObjects(position.getDeviceId(), Attribute.class);
for (Attribute attribute : attributes) {
if (attribute.getAttribute() != null) {
Object result = null;
diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java
index f386116b0..e5c9bc29a 100644
--- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java
+++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,27 +18,39 @@ package org.traccar.handler;
import io.netty.channel.ChannelHandler;
import org.traccar.BaseDataHandler;
-import org.traccar.database.IdentityManager;
+import org.traccar.config.Config;
+import org.traccar.config.Keys;
+import org.traccar.helper.model.AttributeUtil;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class CopyAttributesHandler extends BaseDataHandler {
- private IdentityManager identityManager;
+ private final boolean enabled;
+ private final CacheManager cacheManager;
- public CopyAttributesHandler(IdentityManager identityManager) {
- this.identityManager = identityManager;
+ @Inject
+ public CopyAttributesHandler(Config config, CacheManager cacheManager) {
+ enabled = config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE);
+ this.cacheManager = cacheManager;
}
@Override
protected Position handlePosition(Position position) {
- String attributesString = identityManager.lookupAttributeString(
- position.getDeviceId(), "processing.copyAttributes", "", false, true);
- Position last = identityManager.getLastPosition(position.getDeviceId());
- if (last != null) {
- for (String attribute : attributesString.split("[ ,]")) {
- if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) {
- position.getAttributes().put(attribute, last.getAttributes().get(attribute));
+ if (enabled) {
+ String attributesString = AttributeUtil.lookup(
+ cacheManager, Keys.PROCESSING_COPY_ATTRIBUTES, position.getDeviceId());
+ Position last = cacheManager.getPosition(position.getDeviceId());
+ if (last != null && attributesString != null) {
+ for (String attribute : attributesString.split("[ ,]")) {
+ if (last.hasAttribute(attribute) && !position.hasAttribute(attribute)) {
+ position.getAttributes().put(attribute, last.getAttributes().get(attribute));
+ }
}
}
}
diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java
index 9d8ea044d..89255a5fe 100644
--- a/src/main/java/org/traccar/handler/DefaultDataHandler.java
+++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,25 +19,32 @@ import io.netty.channel.ChannelHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.BaseDataHandler;
-import org.traccar.database.DataManager;
import org.traccar.model.Position;
+import org.traccar.storage.Storage;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Request;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class DefaultDataHandler extends BaseDataHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDataHandler.class);
- private final DataManager dataManager;
+ private final Storage storage;
- public DefaultDataHandler(DataManager dataManager) {
- this.dataManager = dataManager;
+ @Inject
+ public DefaultDataHandler(Storage storage) {
+ this.storage = storage;
}
@Override
protected Position handlePosition(Position position) {
try {
- dataManager.addObject(position);
+ position.setId(storage.addObject(position, new Request(new Columns.Exclude("id"))));
} catch (Exception error) {
LOGGER.warn("Failed to store position", error);
}
diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java
index 1e7e444f6..30dc9ff2b 100644
--- a/src/main/java/org/traccar/handler/DistanceHandler.java
+++ b/src/main/java/org/traccar/handler/DistanceHandler.java
@@ -1,6 +1,6 @@
/*
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2015 Amila Silva
- * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,24 +20,28 @@ import io.netty.channel.ChannelHandler;
import org.traccar.BaseDataHandler;
import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.IdentityManager;
import org.traccar.helper.DistanceCalculator;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import java.math.BigDecimal;
import java.math.RoundingMode;
+@Singleton
@ChannelHandler.Sharable
public class DistanceHandler extends BaseDataHandler {
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
private final boolean filter;
private final int coordinatesMinError;
private final int coordinatesMaxError;
- public DistanceHandler(Config config, IdentityManager identityManager) {
- this.identityManager = identityManager;
+ @Inject
+ public DistanceHandler(Config config, CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
this.filter = config.getBoolean(Keys.COORDINATES_FILTER);
this.coordinatesMinError = config.getInteger(Keys.COORDINATES_MIN_ERROR);
this.coordinatesMaxError = config.getInteger(Keys.COORDINATES_MAX_ERROR);
@@ -47,15 +51,15 @@ public class DistanceHandler extends BaseDataHandler {
protected Position handlePosition(Position position) {
double distance = 0.0;
- if (position.getAttributes().containsKey(Position.KEY_DISTANCE)) {
+ if (position.hasAttribute(Position.KEY_DISTANCE)) {
distance = position.getDouble(Position.KEY_DISTANCE);
}
double totalDistance = 0.0;
- Position last = identityManager != null ? identityManager.getLastPosition(position.getDeviceId()) : null;
+ Position last = cacheManager.getPosition(position.getDeviceId());
if (last != null) {
totalDistance = last.getDouble(Position.KEY_TOTAL_DISTANCE);
- if (!position.getAttributes().containsKey(Position.KEY_DISTANCE)) {
+ if (!position.hasAttribute(Position.KEY_DISTANCE)) {
distance = DistanceCalculator.distance(
position.getLatitude(), position.getLongitude(),
last.getLatitude(), last.getLongitude());
diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java
index 92da84e6b..c10fe9064 100644
--- a/src/main/java/org/traccar/handler/EngineHoursHandler.java
+++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,22 +18,27 @@ package org.traccar.handler;
import io.netty.channel.ChannelHandler;
import org.traccar.BaseDataHandler;
-import org.traccar.database.IdentityManager;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class EngineHoursHandler extends BaseDataHandler {
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
- public EngineHoursHandler(IdentityManager identityManager) {
- this.identityManager = identityManager;
+ @Inject
+ public EngineHoursHandler(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
}
@Override
protected Position handlePosition(Position position) {
- if (!position.getAttributes().containsKey(Position.KEY_HOURS)) {
- Position last = identityManager.getLastPosition(position.getDeviceId());
+ if (!position.hasAttribute(Position.KEY_HOURS)) {
+ Position last = cacheManager.getPosition(position.getDeviceId());
if (last != null) {
long hours = last.getLong(Position.KEY_HOURS);
if (last.getBoolean(Position.KEY_IGNITION) && position.getBoolean(Position.KEY_IGNITION)) {
diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java
index 7cd9153c1..994276bb6 100644
--- a/src/main/java/org/traccar/handler/FilterHandler.java
+++ b/src/main/java/org/traccar/handler/FilterHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2014 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,49 +19,83 @@ import io.netty.channel.ChannelHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.BaseDataHandler;
-import org.traccar.Context;
import org.traccar.config.Config;
import org.traccar.config.Keys;
import org.traccar.helper.UnitsConverter;
+import org.traccar.helper.model.AttributeUtil;
+import org.traccar.model.Device;
import org.traccar.model.Position;
-
+import org.traccar.session.cache.CacheManager;
+import org.traccar.storage.Storage;
+import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Order;
+import org.traccar.storage.query.Request;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Date;
+
+@Singleton
@ChannelHandler.Sharable
public class FilterHandler extends BaseDataHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(FilterHandler.class);
- private boolean filterInvalid;
- private boolean filterZero;
- private boolean filterDuplicate;
- private long filterFuture;
- private boolean filterApproximate;
- private int filterAccuracy;
- private boolean filterStatic;
- private int filterDistance;
- private int filterMaxSpeed;
- private long filterMinPeriod;
- private long skipLimit;
- private boolean skipAttributes;
-
- public FilterHandler(Config config) {
+ private final boolean enabled;
+ private final boolean filterInvalid;
+ private final boolean filterZero;
+ private final boolean filterDuplicate;
+ private final long filterFuture;
+ private final long filterPast;
+ private final boolean filterApproximate;
+ private final int filterAccuracy;
+ private final boolean filterStatic;
+ private final int filterDistance;
+ private final int filterMaxSpeed;
+ private final long filterMinPeriod;
+ private final boolean filterRelative;
+ private final long skipLimit;
+ private final boolean skipAttributes;
+
+ private final CacheManager cacheManager;
+ private final Storage storage;
+
+ @Inject
+ public FilterHandler(Config config, CacheManager cacheManager, Storage storage) {
+ enabled = config.getBoolean(Keys.FILTER_ENABLE);
filterInvalid = config.getBoolean(Keys.FILTER_INVALID);
filterZero = config.getBoolean(Keys.FILTER_ZERO);
filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE);
filterFuture = config.getLong(Keys.FILTER_FUTURE) * 1000;
+ filterPast = config.getLong(Keys.FILTER_PAST) * 1000;
filterAccuracy = config.getInteger(Keys.FILTER_ACCURACY);
filterApproximate = config.getBoolean(Keys.FILTER_APPROXIMATE);
filterStatic = config.getBoolean(Keys.FILTER_STATIC);
filterDistance = config.getInteger(Keys.FILTER_DISTANCE);
filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED);
- filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000;
+ filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000L;
+ filterRelative = config.getBoolean(Keys.FILTER_RELATIVE);
skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000;
skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE);
+ this.cacheManager = cacheManager;
+ this.storage = storage;
+ }
+
+ private Position getPrecedingPosition(long deviceId, Date date) throws StorageException {
+ return storage.getObject(Position.class, new Request(
+ new Columns.All(),
+ new Condition.And(
+ new Condition.Equals("deviceId", deviceId),
+ new Condition.Compare("fixTime", "<=", "time", date)),
+ new Order("fixTime", true, 1)));
}
private boolean filterInvalid(Position position) {
return filterInvalid && (!position.getValid()
- || position.getLatitude() > 90 || position.getLongitude() > 180
- || position.getLatitude() < -90 || position.getLongitude() < -180);
+ || position.getLatitude() > 90 || position.getLongitude() > 180
+ || position.getLatitude() < -90 || position.getLongitude() < -180);
}
private boolean filterZero(Position position) {
@@ -71,7 +105,7 @@ public class FilterHandler extends BaseDataHandler {
private boolean filterDuplicate(Position position, Position last) {
if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) {
for (String key : position.getAttributes().keySet()) {
- if (!last.getAttributes().containsKey(key)) {
+ if (!last.hasAttribute(key)) {
return false;
}
}
@@ -84,6 +118,10 @@ public class FilterHandler extends BaseDataHandler {
return filterFuture != 0 && position.getFixTime().getTime() > System.currentTimeMillis() + filterFuture;
}
+ private boolean filterPast(Position position) {
+ return filterPast != 0 && position.getFixTime().getTime() < System.currentTimeMillis() - filterPast;
+ }
+
private boolean filterAccuracy(Position position) {
return filterAccuracy != 0 && position.getAccuracy() > filterAccuracy;
}
@@ -129,10 +167,9 @@ public class FilterHandler extends BaseDataHandler {
private boolean skipAttributes(Position position) {
if (skipAttributes) {
- String attributesString = Context.getIdentityManager().lookupAttributeString(
- position.getDeviceId(), "filter.skipAttributes", "", false, true);
- for (String attribute : attributesString.split("[ ,]")) {
- if (position.getAttributes().containsKey(attribute)) {
+ String string = AttributeUtil.lookup(cacheManager, Keys.FILTER_SKIP_ATTRIBUTES, position.getDeviceId());
+ for (String attribute : string.split("[ ,]")) {
+ if (position.hasAttribute(attribute)) {
return true;
}
}
@@ -144,51 +181,61 @@ public class FilterHandler extends BaseDataHandler {
StringBuilder filterType = new StringBuilder();
- Position last = null;
- if (Context.getIdentityManager() != null) {
- last = Context.getIdentityManager().getLastPosition(position.getDeviceId());
- }
-
+ // filter out invalid data
if (filterInvalid(position)) {
filterType.append("Invalid ");
}
if (filterZero(position)) {
filterType.append("Zero ");
}
- if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) {
- filterType.append("Duplicate ");
- }
if (filterFuture(position)) {
filterType.append("Future ");
}
+ if (filterPast(position)) {
+ filterType.append("Past ");
+ }
if (filterAccuracy(position)) {
filterType.append("Accuracy ");
}
if (filterApproximate(position)) {
filterType.append("Approximate ");
}
- if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) {
- filterType.append("Static ");
- }
- if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) {
- filterType.append("Distance ");
- }
- if (filterMaxSpeed(position, last)) {
- filterType.append("MaxSpeed ");
- }
- if (filterMinPeriod(position, last)) {
- filterType.append("MinPeriod ");
+
+ // filter out excessive data
+ long deviceId = position.getDeviceId();
+ if (filterDuplicate || filterStatic || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) {
+ Position preceding = null;
+ if (filterRelative) {
+ try {
+ Date newFixTime = position.getFixTime();
+ preceding = getPrecedingPosition(deviceId, newFixTime);
+ } catch (StorageException e) {
+ LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e);
+ preceding = cacheManager.getPosition(deviceId);
+ }
+ } else {
+ preceding = cacheManager.getPosition(deviceId);
+ }
+ if (filterDuplicate(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) {
+ filterType.append("Duplicate ");
+ }
+ if (filterStatic(position) && !skipLimit(position, preceding) && !skipAttributes(position)) {
+ filterType.append("Static ");
+ }
+ if (filterDistance(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) {
+ filterType.append("Distance ");
+ }
+ if (filterMaxSpeed(position, preceding)) {
+ filterType.append("MaxSpeed ");
+ }
+ if (filterMinPeriod(position, preceding)) {
+ filterType.append("MinPeriod ");
+ }
}
if (filterType.length() > 0) {
-
- StringBuilder message = new StringBuilder();
- message.append("Position filtered by ");
- message.append(filterType.toString());
- message.append("filters from device: ");
- message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId());
-
- LOGGER.info(message.toString());
+ String uniqueId = cacheManager.getObject(Device.class, deviceId).getUniqueId();
+ LOGGER.info("Position filtered by {}filters from device: {}", filterType, uniqueId);
return true;
}
@@ -197,7 +244,7 @@ public class FilterHandler extends BaseDataHandler {
@Override
protected Position handlePosition(Position position) {
- if (filter(position)) {
+ if (enabled && filter(position)) {
return null;
}
return position;
diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java
index 614cf97d6..e4f240a90 100644
--- a/src/main/java/org/traccar/handler/GeocoderHandler.java
+++ b/src/main/java/org/traccar/handler/GeocoderHandler.java
@@ -20,12 +20,11 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.traccar.Context;
import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.IdentityManager;
import org.traccar.geocoder.Geocoder;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
@ChannelHandler.Sharable
public class GeocoderHandler extends ChannelInboundHandlerAdapter {
@@ -33,18 +32,17 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(GeocoderHandler.class);
private final Geocoder geocoder;
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
private final boolean ignorePositions;
private final boolean processInvalidPositions;
- private final int geocoderReuseDistance;
+ private final int reuseDistance;
- public GeocoderHandler(
- Config config, Geocoder geocoder, IdentityManager identityManager) {
+ public GeocoderHandler(Config config, Geocoder geocoder, CacheManager cacheManager) {
this.geocoder = geocoder;
- this.identityManager = identityManager;
- ignorePositions = Context.getConfig().getBoolean(Keys.GEOCODER_IGNORE_POSITIONS);
+ this.cacheManager = cacheManager;
+ ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS);
processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS);
- geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0);
+ reuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0);
}
@Override
@@ -52,10 +50,10 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter {
if (message instanceof Position && !ignorePositions) {
final Position position = (Position) message;
if (processInvalidPositions || position.getValid()) {
- if (geocoderReuseDistance != 0) {
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
+ if (reuseDistance != 0) {
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
if (lastPosition != null && lastPosition.getAddress() != null
- && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) {
+ && position.getDouble(Position.KEY_DISTANCE) <= reuseDistance) {
position.setAddress(lastPosition.getAddress());
ctx.fireChannelRead(position);
return;
diff --git a/src/main/java/org/traccar/handler/GeolocationHandler.java b/src/main/java/org/traccar/handler/GeolocationHandler.java
index 0e78322c8..e7389f22d 100644
--- a/src/main/java/org/traccar/handler/GeolocationHandler.java
+++ b/src/main/java/org/traccar/handler/GeolocationHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.traccar.config.Keys;
import org.traccar.database.StatisticsManager;
import org.traccar.geolocation.GeolocationProvider;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
@ChannelHandler.Sharable
public class GeolocationHandler extends ChannelInboundHandlerAdapter {
@@ -32,14 +33,19 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(GeolocationHandler.class);
private final GeolocationProvider geolocationProvider;
+ private final CacheManager cacheManager;
private final StatisticsManager statisticsManager;
private final boolean processInvalidPositions;
+ private final boolean reuse;
public GeolocationHandler(
- Config config, GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) {
+ Config config, GeolocationProvider geolocationProvider, CacheManager cacheManager,
+ StatisticsManager statisticsManager) {
this.geolocationProvider = geolocationProvider;
+ this.cacheManager = cacheManager;
this.statisticsManager = statisticsManager;
- this.processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS);
+ processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS);
+ reuse = config.getBoolean(Keys.GEOLOCATION_REUSE);
}
@Override
@@ -48,6 +54,17 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter {
final Position position = (Position) message;
if ((position.getOutdated() || processInvalidPositions && !position.getValid())
&& position.getNetwork() != null) {
+ if (reuse) {
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
+ if (lastPosition != null && position.getNetwork().equals(lastPosition.getNetwork())) {
+ updatePosition(
+ position, lastPosition.getLatitude(), lastPosition.getLongitude(),
+ lastPosition.getAccuracy());
+ ctx.fireChannelRead(position);
+ return;
+ }
+ }
+
if (statisticsManager != null) {
statisticsManager.registerGeolocationRequest();
}
@@ -56,15 +73,7 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter {
new GeolocationProvider.LocationProviderCallback() {
@Override
public void onSuccess(double latitude, double longitude, double accuracy) {
- position.set(Position.KEY_APPROXIMATE, true);
- position.setValid(true);
- position.setFixTime(position.getDeviceTime());
- position.setLatitude(latitude);
- position.setLongitude(longitude);
- position.setAccuracy(accuracy);
- position.setAltitude(0);
- position.setSpeed(0);
- position.setCourse(0);
+ updatePosition(position, latitude, longitude, accuracy);
ctx.fireChannelRead(position);
}
@@ -82,4 +91,16 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter {
}
}
+ private void updatePosition(Position position, double latitude, double longitude, double accuracy) {
+ position.set(Position.KEY_APPROXIMATE, true);
+ position.setValid(true);
+ position.setFixTime(position.getDeviceTime());
+ position.setLatitude(latitude);
+ position.setLongitude(longitude);
+ position.setAccuracy(accuracy);
+ position.setAltitude(0);
+ position.setSpeed(0);
+ position.setCourse(0);
+ }
+
}
diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java
index aff3d8a64..ccbde9fe5 100644
--- a/src/main/java/org/traccar/handler/HemisphereHandler.java
+++ b/src/main/java/org/traccar/handler/HemisphereHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,17 @@ import org.traccar.config.Config;
import org.traccar.config.Keys;
import org.traccar.model.Position;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class HemisphereHandler extends BaseDataHandler {
private int latitudeFactor;
private int longitudeFactor;
+ @Inject
public HemisphereHandler(Config config) {
String latitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE);
if (latitudeHemisphere != null) {
@@ -36,7 +41,7 @@ public class HemisphereHandler extends BaseDataHandler {
latitudeFactor = -1;
}
}
- String longitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE);
+ String longitudeHemisphere = config.getString(Keys.LOCATION_LONGITUDE_HEMISPHERE);
if (longitudeHemisphere != null) {
if (longitudeHemisphere.equalsIgnoreCase("E")) {
longitudeFactor = 1;
diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java
index e8051dd75..10312f9b3 100644
--- a/src/main/java/org/traccar/handler/MotionHandler.java
+++ b/src/main/java/org/traccar/handler/MotionHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,19 +19,25 @@ package org.traccar.handler;
import io.netty.channel.ChannelHandler;
import org.traccar.BaseDataHandler;
import org.traccar.model.Position;
+import org.traccar.reports.common.TripsConfig;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class MotionHandler extends BaseDataHandler {
- private double speedThreshold;
+ private final double speedThreshold;
- public MotionHandler(double speedThreshold) {
- this.speedThreshold = speedThreshold;
+ @Inject
+ public MotionHandler(TripsConfig tripsConfig) {
+ speedThreshold = tripsConfig.getSpeedThreshold();
}
@Override
protected Position handlePosition(Position position) {
- if (!position.getAttributes().containsKey(Position.KEY_MOTION)) {
+ if (!position.hasAttribute(Position.KEY_MOTION)) {
position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold);
}
return position;
diff --git a/src/main/java/org/traccar/handler/OpenChannelHandler.java b/src/main/java/org/traccar/handler/OpenChannelHandler.java
index d09d617ab..e416f35ae 100644
--- a/src/main/java/org/traccar/handler/OpenChannelHandler.java
+++ b/src/main/java/org/traccar/handler/OpenChannelHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,26 +17,26 @@ package org.traccar.handler;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
-import org.traccar.TrackerServer;
+import org.traccar.TrackerConnector;
public class OpenChannelHandler extends ChannelDuplexHandler {
- private final TrackerServer server;
+ private final TrackerConnector connector;
- public OpenChannelHandler(TrackerServer server) {
- this.server = server;
+ public OpenChannelHandler(TrackerConnector connector) {
+ this.connector = connector;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
- server.getChannelGroup().add(ctx.channel());
+ connector.getChannelGroup().add(ctx.channel());
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
- server.getChannelGroup().remove(ctx.channel());
+ connector.getChannelGroup().remove(ctx.channel());
}
}
diff --git a/src/main/java/org/traccar/handler/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/RemoteAddressHandler.java
index c09b8c39a..e18d34ef2 100644
--- a/src/main/java/org/traccar/handler/RemoteAddressHandler.java
+++ b/src/main/java/org/traccar/handler/RemoteAddressHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,22 +18,36 @@ package org.traccar.handler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
+import org.traccar.config.Config;
+import org.traccar.config.Keys;
import org.traccar.model.Position;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import java.net.InetSocketAddress;
+@Singleton
@ChannelHandler.Sharable
public class RemoteAddressHandler extends ChannelInboundHandlerAdapter {
+ private final boolean enabled;
+
+ @Inject
+ public RemoteAddressHandler(Config config) {
+ enabled = config.getBoolean(Keys.PROCESSING_REMOTE_ADDRESS_ENABLE);
+ }
+
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
- InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
- String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null;
+ if (enabled) {
+ InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
+ String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null;
- if (msg instanceof Position) {
- Position position = (Position) msg;
- position.set(Position.KEY_IP, hostAddress);
+ if (msg instanceof Position) {
+ Position position = (Position) msg;
+ position.set(Position.KEY_IP, hostAddress);
+ }
}
ctx.fireChannelRead(msg);
diff --git a/src/main/java/org/traccar/handler/SpeedLimitHandler.java b/src/main/java/org/traccar/handler/SpeedLimitHandler.java
index 65f2c9cfe..0c6025999 100644
--- a/src/main/java/org/traccar/handler/SpeedLimitHandler.java
+++ b/src/main/java/org/traccar/handler/SpeedLimitHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 Anton Tananaev (anton@traccar.org)
+ * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,10 @@ import org.slf4j.LoggerFactory;
import org.traccar.model.Position;
import org.traccar.speedlimit.SpeedLimitProvider;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class SpeedLimitHandler extends ChannelInboundHandlerAdapter {
@@ -30,6 +34,7 @@ public class SpeedLimitHandler extends ChannelInboundHandlerAdapter {
private final SpeedLimitProvider speedLimitProvider;
+ @Inject
public SpeedLimitHandler(SpeedLimitProvider speedLimitProvider) {
this.speedLimitProvider = speedLimitProvider;
}
diff --git a/src/main/java/org/traccar/handler/StandardLoggingHandler.java b/src/main/java/org/traccar/handler/StandardLoggingHandler.java
index 13c5f8281..84492e2a5 100644
--- a/src/main/java/org/traccar/handler/StandardLoggingHandler.java
+++ b/src/main/java/org/traccar/handler/StandardLoggingHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import io.netty.channel.ChannelPromise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.NetworkMessage;
+import org.traccar.helper.NetworkUtil;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@@ -63,7 +64,7 @@ public class StandardLoggingHandler extends ChannelDuplexHandler {
public void log(ChannelHandlerContext ctx, boolean downstream, SocketAddress remoteAddress, ByteBuf buf) {
StringBuilder message = new StringBuilder();
- message.append("[").append(ctx.channel().id().asShortText()).append(": ");
+ message.append("[").append(NetworkUtil.session(ctx.channel())).append(": ");
message.append(protocol);
if (downstream) {
message.append(" > ");
@@ -76,9 +77,8 @@ public class StandardLoggingHandler extends ChannelDuplexHandler {
} else {
message.append("unknown");
}
- message.append("]");
+ message.append("] ");
- message.append(" HEX: ");
message.append(ByteBufUtil.hexDump(buf));
LOGGER.info(message.toString());
diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java
index 822c22a0a..c98b0bd4c 100644
--- a/src/main/java/org/traccar/handler/TimeHandler.java
+++ b/src/main/java/org/traccar/handler/TimeHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 - 2020 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,24 +19,33 @@ import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.traccar.BaseProtocolDecoder;
-import org.traccar.Context;
import org.traccar.config.Config;
import org.traccar.config.Keys;
import org.traccar.model.Position;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+@Singleton
@ChannelHandler.Sharable
public class TimeHandler extends ChannelInboundHandlerAdapter {
+ private final boolean enabled;
private final boolean useServerTime;
private final Set<String> protocols;
+ @Inject
public TimeHandler(Config config) {
- useServerTime = config.getString(Keys.TIME_OVERRIDE).equalsIgnoreCase("serverTime");
- String protocolList = Context.getConfig().getString(Keys.TIME_PROTOCOLS);
+ enabled = config.hasKey(Keys.TIME_OVERRIDE);
+ if (enabled) {
+ useServerTime = config.getString(Keys.TIME_OVERRIDE).equalsIgnoreCase("serverTime");
+ } else {
+ useServerTime = false;
+ }
+ String protocolList = config.getString(Keys.TIME_PROTOCOLS);
if (protocolList != null) {
protocols = new HashSet<>(Arrays.asList(protocolList.split("[, ]")));
} else {
@@ -47,7 +56,7 @@ public class TimeHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
- if (msg instanceof Position && (protocols == null
+ if (enabled && msg instanceof Position && (protocols == null
|| protocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName()))) {
Position position = (Position) msg;
diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java
index 05dbc516e..9f77df989 100644
--- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,18 +21,23 @@ import java.util.Map;
import io.netty.channel.ChannelHandler;
import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.IdentityManager;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class AlertEventHandler extends BaseEventHandler {
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
private final boolean ignoreDuplicateAlerts;
- public AlertEventHandler(Config config, IdentityManager identityManager) {
- this.identityManager = identityManager;
+ @Inject
+ public AlertEventHandler(Config config, CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS);
}
@@ -42,7 +47,7 @@ public class AlertEventHandler extends BaseEventHandler {
if (alarm != null) {
boolean ignoreAlert = false;
if (ignoreDuplicateAlerts) {
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
if (lastPosition != null && alarm.equals(lastPosition.getAttributes().get(Position.KEY_ALARM))) {
ignoreAlert = true;
}
diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java
index 41f677f6c..271aaa35d 100644
--- a/src/main/java/org/traccar/handler/events/BaseEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,17 +18,26 @@ package org.traccar.handler.events;
import java.util.Map;
import org.traccar.BaseDataHandler;
-import org.traccar.Context;
+import org.traccar.database.NotificationManager;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import javax.inject.Inject;
+
public abstract class BaseEventHandler extends BaseDataHandler {
+ private NotificationManager notificationManager;
+
+ @Inject
+ public void setNotificationManager(NotificationManager notificationManager) {
+ this.notificationManager = notificationManager;
+ }
+
@Override
protected Position handlePosition(Position position) {
Map<Event, Position> events = analyzePosition(position);
- if (events != null && Context.getNotificationManager() != null) {
- Context.getNotificationManager().updateEvents(events);
+ if (events != null && !events.isEmpty()) {
+ notificationManager.updateEvents(events);
}
return position;
}
diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java
index 767cef3f6..51bbd82d6 100644
--- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 Anton Tananaev (anton@traccar.org)
+ * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,32 +18,36 @@ package org.traccar.handler.events;
import io.netty.channel.ChannelHandler;
import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.IdentityManager;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import java.util.Collections;
import java.util.Map;
+@Singleton
@ChannelHandler.Sharable
public class BehaviorEventHandler extends BaseEventHandler {
private final double accelerationThreshold;
private final double brakingThreshold;
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
- public BehaviorEventHandler(Config config, IdentityManager identityManager) {
+ @Inject
+ public BehaviorEventHandler(Config config, CacheManager cacheManager) {
accelerationThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_ACCELERATION_THRESHOLD);
brakingThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_BRAKING_THRESHOLD);
- this.identityManager = identityManager;
+ this.cacheManager = cacheManager;
}
@Override
protected Map<Event, Position> analyzePosition(Position position) {
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
if (lastPosition != null && position.getFixTime().equals(lastPosition.getFixTime())) {
double acceleration = UnitsConverter.mpsFromKnots(position.getSpeed() - lastPosition.getSpeed()) * 1000
/ (position.getFixTime().getTime() - lastPosition.getFixTime().getTime());
diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java
index 9b7ff554e..772176e9c 100644
--- a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,17 @@ import io.netty.channel.ChannelHandler;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class CommandResultEventHandler extends BaseEventHandler {
+ @Inject
+ public CommandResultEventHandler() {
+ }
+
@Override
protected Map<Event, Position> analyzePosition(Position position) {
Object commandResult = position.getAttributes().get(Position.KEY_RESULT);
diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java
index 6fdf4246b..51fdc0307 100644
--- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,32 +16,37 @@
*/
package org.traccar.handler.events;
-import java.util.Collections;
-import java.util.Map;
-
import io.netty.channel.ChannelHandler;
-import org.traccar.database.IdentityManager;
+import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Collections;
+import java.util.Map;
+@Singleton
@ChannelHandler.Sharable
public class DriverEventHandler extends BaseEventHandler {
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
- public DriverEventHandler(IdentityManager identityManager) {
- this.identityManager = identityManager;
+ @Inject
+ public DriverEventHandler(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
}
@Override
protected Map<Event, Position> analyzePosition(Position position) {
- if (!identityManager.isLatestPosition(position)) {
+ if (!PositionUtil.isLatest(cacheManager, position)) {
return null;
}
String driverUniqueId = position.getString(Position.KEY_DRIVER_UNIQUE_ID);
if (driverUniqueId != null) {
String oldDriverUniqueId = null;
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
if (lastPosition != null) {
oldDriverUniqueId = lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID);
}
diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java
deleted file mode 100644
index 343a17311..000000000
--- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.traccar.handler.events;
-
-import io.netty.channel.ChannelHandler;
-import org.traccar.database.IdentityManager;
-import org.traccar.model.Device;
-import org.traccar.model.Event;
-import org.traccar.model.Position;
-
-import java.util.Collections;
-import java.util.Map;
-
-@ChannelHandler.Sharable
-public class FuelDropEventHandler extends BaseEventHandler {
-
- public static final String ATTRIBUTE_FUEL_DROP_THRESHOLD = "fuelDropThreshold";
-
- private final IdentityManager identityManager;
-
- public FuelDropEventHandler(IdentityManager identityManager) {
- this.identityManager = identityManager;
- }
-
- @Override
- protected Map<Event, Position> analyzePosition(Position position) {
-
- Device device = identityManager.getById(position.getDeviceId());
- if (device == null) {
- return null;
- }
- if (!identityManager.isLatestPosition(position)) {
- return null;
- }
-
- double fuelDropThreshold = identityManager
- .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, true, false);
-
- if (fuelDropThreshold > 0) {
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
- if (position.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)
- && lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)) {
-
- double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL)
- - position.getDouble(Position.KEY_FUEL_LEVEL);
- if (drop >= fuelDropThreshold) {
- Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position);
- event.set(ATTRIBUTE_FUEL_DROP_THRESHOLD, fuelDropThreshold);
- return Collections.singletonMap(event, position);
- }
- }
- }
-
- return null;
- }
-
-}
diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java
new file mode 100644
index 000000000..462cc4223
--- /dev/null
+++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.handler.events;
+
+import io.netty.channel.ChannelHandler;
+import org.traccar.config.Keys;
+import org.traccar.helper.model.AttributeUtil;
+import org.traccar.helper.model.PositionUtil;
+import org.traccar.model.Device;
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Map;
+
+@Singleton
+@ChannelHandler.Sharable
+public class FuelEventHandler extends BaseEventHandler {
+
+ private final CacheManager cacheManager;
+
+ @Inject
+ public FuelEventHandler(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
+ }
+
+ @Override
+ protected Map<Event, Position> analyzePosition(Position position) {
+
+ Device device = cacheManager.getObject(Device.class, position.getDeviceId());
+ if (device == null) {
+ return null;
+ }
+ if (!PositionUtil.isLatest(cacheManager, position)) {
+ return null;
+ }
+
+ if (position.hasAttribute(Position.KEY_FUEL_LEVEL)) {
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
+ if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) {
+ double before = lastPosition.getDouble(Position.KEY_FUEL_LEVEL);
+ double after = position.getDouble(Position.KEY_FUEL_LEVEL);
+ double change = after - before;
+
+ if (change > 0) {
+ double threshold = AttributeUtil.lookup(
+ cacheManager, Keys.EVENT_FUEL_INCREASE_THRESHOLD, position.getDeviceId());
+ if (change >= threshold) {
+ return Map.of(new Event(Event.TYPE_DEVICE_FUEL_INCREASE, position), position);
+ }
+ } else if (change < 0) {
+ double threshold = AttributeUtil.lookup(
+ cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId());
+ if (Math.abs(change) >= threshold) {
+ return Map.of(new Event(Event.TYPE_DEVICE_FUEL_DROP, position), position);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java
index dae0c891f..9414f4b31 100644
--- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,49 +15,59 @@
*/
package org.traccar.handler.events;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
import io.netty.channel.ChannelHandler;
-import org.traccar.database.CalendarManager;
-import org.traccar.database.ConnectionManager;
-import org.traccar.database.GeofenceManager;
-import org.traccar.database.IdentityManager;
+import org.traccar.config.Config;
+import org.traccar.helper.model.GeofenceUtil;
+import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Calendar;
import org.traccar.model.Device;
import org.traccar.model.Event;
+import org.traccar.model.Geofence;
import org.traccar.model.Position;
+import org.traccar.session.ConnectionManager;
+import org.traccar.session.cache.CacheManager;
+import org.traccar.storage.Storage;
+import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+@Singleton
@ChannelHandler.Sharable
public class GeofenceEventHandler extends BaseEventHandler {
- private final IdentityManager identityManager;
- private final GeofenceManager geofenceManager;
- private final CalendarManager calendarManager;
+ private final Config config;
+ private final CacheManager cacheManager;
private final ConnectionManager connectionManager;
+ private final Storage storage;
+ @Inject
public GeofenceEventHandler(
- IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager,
- ConnectionManager connectionManager) {
- this.identityManager = identityManager;
- this.geofenceManager = geofenceManager;
- this.calendarManager = calendarManager;
+ Config config, CacheManager cacheManager, ConnectionManager connectionManager, Storage storage) {
+ this.config = config;
+ this.cacheManager = cacheManager;
this.connectionManager = connectionManager;
+ this.storage = storage;
}
@Override
protected Map<Event, Position> analyzePosition(Position position) {
- Device device = identityManager.getById(position.getDeviceId());
+ Device device = cacheManager.getObject(Device.class, position.getDeviceId());
if (device == null) {
return null;
}
- if (!identityManager.isLatestPosition(position) || !position.getValid()) {
+ if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) {
return null;
}
- List<Long> currentGeofences = geofenceManager.getCurrentDeviceGeofences(position);
+ List<Long> currentGeofences = GeofenceUtil.getCurrentGeofences(config, cacheManager, position);
List<Long> oldGeofences = new ArrayList<>();
if (device.getGeofenceIds() != null) {
oldGeofences.addAll(device.getGeofenceIds());
@@ -66,15 +76,25 @@ public class GeofenceEventHandler extends BaseEventHandler {
newGeofences.removeAll(oldGeofences);
oldGeofences.removeAll(currentGeofences);
- device.setGeofenceIds(currentGeofences);
+
if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) {
- connectionManager.updateDevice(device);
+ device.setGeofenceIds(currentGeofences.isEmpty() ? null : currentGeofences);
+
+ try {
+ storage.updateObject(device, new Request(
+ new Columns.Include("geofenceIds"),
+ new Condition.Equals("id", device.getId())));
+ } catch (StorageException e) {
+ throw new RuntimeException("Update device geofences error", e);
+ }
+
+ connectionManager.updateDevice(true, device);
}
Map<Event, Position> events = new HashMap<>();
for (long geofenceId : oldGeofences) {
- long calendarId = geofenceManager.getById(geofenceId).getCalendarId();
- Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null;
+ long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId();
+ Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null;
if (calendar == null || calendar.checkMoment(position.getFixTime())) {
Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position);
event.setGeofenceId(geofenceId);
@@ -82,8 +102,8 @@ public class GeofenceEventHandler extends BaseEventHandler {
}
}
for (long geofenceId : newGeofences) {
- long calendarId = geofenceManager.getById(geofenceId).getCalendarId();
- Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null;
+ long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId();
+ Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null;
if (calendar == null || calendar.checkMoment(position.getFixTime())) {
Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position);
event.setGeofenceId(geofenceId);
diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java
index 69df9a46b..b2e9a3325 100644
--- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2016 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,34 +20,40 @@ import java.util.Collections;
import java.util.Map;
import io.netty.channel.ChannelHandler;
-import org.traccar.database.IdentityManager;
+import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class IgnitionEventHandler extends BaseEventHandler {
- private final IdentityManager identityManager;
+ private final CacheManager cacheManager;
- public IgnitionEventHandler(IdentityManager identityManager) {
- this.identityManager = identityManager;
+ @Inject
+ public IgnitionEventHandler(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
}
@Override
protected Map<Event, Position> analyzePosition(Position position) {
- Device device = identityManager.getById(position.getDeviceId());
- if (device == null || !identityManager.isLatestPosition(position)) {
+ Device device = cacheManager.getObject(Device.class, position.getDeviceId());
+ if (device == null || !PositionUtil.isLatest(cacheManager, position)) {
return null;
}
Map<Event, Position> result = null;
- if (position.getAttributes().containsKey(Position.KEY_IGNITION)) {
+ if (position.hasAttribute(Position.KEY_IGNITION)) {
boolean ignition = position.getBoolean(Position.KEY_IGNITION);
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
- if (lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_IGNITION)) {
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
+ if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_IGNITION)) {
boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION);
if (ignition && !oldIgnition) {
diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java
index 0f960ad1f..909950acf 100644
--- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,48 +20,46 @@ import java.util.HashMap;
import java.util.Map;
import io.netty.channel.ChannelHandler;
-import org.traccar.database.IdentityManager;
-import org.traccar.database.MaintenancesManager;
import org.traccar.model.Event;
import org.traccar.model.Maintenance;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
@ChannelHandler.Sharable
public class MaintenanceEventHandler extends BaseEventHandler {
- private final IdentityManager identityManager;
- private final MaintenancesManager maintenancesManager;
+ private final CacheManager cacheManager;
- public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) {
- this.identityManager = identityManager;
- this.maintenancesManager = maintenancesManager;
+ @Inject
+ public MaintenanceEventHandler(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
}
@Override
protected Map<Event, Position> analyzePosition(Position position) {
- if (identityManager.getById(position.getDeviceId()) == null
- || !identityManager.isLatestPosition(position)) {
- return null;
- }
-
- Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
- if (lastPosition == null) {
+ Position lastPosition = cacheManager.getPosition(position.getDeviceId());
+ if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) {
return null;
}
Map<Event, Position> events = new HashMap<>();
- for (long maintenanceId : maintenancesManager.getAllDeviceItems(position.getDeviceId())) {
- Maintenance maintenance = maintenancesManager.getById(maintenanceId);
+ for (Maintenance maintenance : cacheManager.getDeviceObjects(position.getDeviceId(), Maintenance.class)) {
if (maintenance.getPeriod() != 0) {
double oldValue = lastPosition.getDouble(maintenance.getType());
double newValue = position.getDouble(maintenance.getType());
- if (oldValue != 0.0 && newValue != 0.0
- && (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod())
+ if (oldValue != 0.0 && newValue != 0.0 && newValue >= maintenance.getStart()) {
+ if (oldValue < maintenance.getStart()
+ || (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod())
< (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) {
- Event event = new Event(Event.TYPE_MAINTENANCE, position);
- event.setMaintenanceId(maintenanceId);
- event.set(maintenance.getType(), newValue);
- events.put(event, position);
+ Event event = new Event(Event.TYPE_MAINTENANCE, position);
+ event.setMaintenanceId(maintenance.getId());
+ event.set(maintenance.getType(), newValue);
+ events.put(event, position);
+ }
}
}
}
diff --git a/src/main/java/org/traccar/handler/events/MediaEventHandler.java b/src/main/java/org/traccar/handler/events/MediaEventHandler.java
new file mode 100644
index 000000000..a49e08e8d
--- /dev/null
+++ b/src/main/java/org/traccar/handler/events/MediaEventHandler.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.handler.events;
+
+import io.netty.channel.ChannelHandler;
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Singleton
+@ChannelHandler.Sharable
+public class MediaEventHandler extends BaseEventHandler {
+
+ @Inject
+ public MediaEventHandler() {
+ }
+
+ @Override
+ protected Map<Event, Position> analyzePosition(Position position) {
+ return Stream.of(Position.KEY_IMAGE, Position.KEY_VIDEO, Position.KEY_AUDIO)
+ .filter(position::hasAttribute)
+ .map(type -> {
+ Event event = new Event(Event.TYPE_MEDIA, position);
+ event.set("media", type);
+ event.set("file", position.getString(type));
+ return event;
+ })
+ .collect(Collectors.toMap(event -> event, event -> position));
+ }
+
+}
diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java
index db276f32b..c406bd935 100644
--- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,120 +16,72 @@
*/
package org.traccar.handler.events;
-import java.util.Collections;
-import java.util.Map;
-
import io.netty.channel.ChannelHandler;
-import org.traccar.database.DeviceManager;
-import org.traccar.database.IdentityManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Device;
-import org.traccar.model.DeviceState;
import org.traccar.model.Event;
import org.traccar.model.Position;
-import org.traccar.reports.ReportUtils;
-import org.traccar.reports.model.TripsConfig;
+import org.traccar.reports.common.TripsConfig;
+import org.traccar.session.cache.CacheManager;
+import org.traccar.session.state.MotionProcessor;
+import org.traccar.session.state.MotionState;
+import org.traccar.storage.Storage;
+import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Collections;
+import java.util.Map;
+@Singleton
@ChannelHandler.Sharable
public class MotionEventHandler extends BaseEventHandler {
- private final IdentityManager identityManager;
- private final DeviceManager deviceManager;
+ private static final Logger LOGGER = LoggerFactory.getLogger(MotionEventHandler.class);
+
+ private final CacheManager cacheManager;
+ private final Storage storage;
private final TripsConfig tripsConfig;
- public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) {
- this.identityManager = identityManager;
- this.deviceManager = deviceManager;
+ @Inject
+ public MotionEventHandler(
+ CacheManager cacheManager, Storage storage, TripsConfig tripsConfig) {
+ this.cacheManager = cacheManager;
+ this.storage = storage;
this.tripsConfig = tripsConfig;
}
- private Map<Event, Position> newEvent(DeviceState deviceState, boolean newMotion) {
- String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED;
- Position position = deviceState.getMotionPosition();
- Event event = new Event(eventType, position);
- deviceState.setMotionState(newMotion);
- deviceState.setMotionPosition(null);
- return Collections.singletonMap(event, position);
- }
-
- public Map<Event, Position> updateMotionState(DeviceState deviceState) {
- Map<Event, Position> result = null;
- if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) {
- boolean newMotion = !deviceState.getMotionState();
- Position motionPosition = deviceState.getMotionPosition();
- long currentTime = System.currentTimeMillis();
- long motionTime = motionPosition.getFixTime().getTime()
- + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration());
- if (motionTime <= currentTime) {
- result = newEvent(deviceState, newMotion);
- }
- }
- return result;
- }
-
- public Map<Event, Position> updateMotionState(DeviceState deviceState, Position position) {
- return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION));
- }
-
- public Map<Event, Position> updateMotionState(DeviceState deviceState, Position position, boolean newMotion) {
- Map<Event, Position> result = null;
- Boolean oldMotion = deviceState.getMotionState();
-
- long currentTime = position.getFixTime().getTime();
- if (newMotion != oldMotion) {
- if (deviceState.getMotionPosition() == null) {
- deviceState.setMotionPosition(position);
- }
- } else {
- deviceState.setMotionPosition(null);
- }
-
- Position motionPosition = deviceState.getMotionPosition();
- if (motionPosition != null) {
- long motionTime = motionPosition.getFixTime().getTime();
- double distance = ReportUtils.calculateDistance(motionPosition, position, false);
- Boolean ignition = null;
- if (tripsConfig.getUseIgnition()
- && position.getAttributes().containsKey(Position.KEY_IGNITION)) {
- ignition = position.getBoolean(Position.KEY_IGNITION);
- }
- if (newMotion) {
- if (motionTime + tripsConfig.getMinimalTripDuration() <= currentTime
- || distance >= tripsConfig.getMinimalTripDistance()) {
- result = newEvent(deviceState, newMotion);
- }
- } else {
- if (motionTime + tripsConfig.getMinimalParkingDuration() <= currentTime
- || ignition != null && !ignition) {
- result = newEvent(deviceState, newMotion);
- }
- }
- }
- return result;
- }
-
@Override
protected Map<Event, Position> analyzePosition(Position position) {
long deviceId = position.getDeviceId();
- Device device = identityManager.getById(deviceId);
+ Device device = cacheManager.getObject(Device.class, deviceId);
if (device == null) {
return null;
}
- if (!identityManager.isLatestPosition(position)
+ if (!PositionUtil.isLatest(cacheManager, position)
|| !tripsConfig.getProcessInvalidPositions() && !position.getValid()) {
return null;
}
- Map<Event, Position> result = null;
- DeviceState deviceState = deviceManager.getDeviceState(deviceId);
-
- if (deviceState.getMotionState() == null) {
- deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION));
- } else {
- result = updateMotionState(deviceState, position);
+ MotionState state = MotionState.fromDevice(device);
+ MotionProcessor.updateState(state, position, position.getBoolean(Position.KEY_MOTION), tripsConfig);
+ if (state.isChanged()) {
+ state.toDevice(device);
+ try {
+ storage.updateObject(device, new Request(
+ new Columns.Include("motionStreak", "motionState", "motionTime", "motionDistance"),
+ new Condition.Equals("id", device.getId())));
+ } catch (StorageException e) {
+ LOGGER.warn("Update device motion error", e);
+ }
}
- deviceManager.setDeviceState(deviceId, deviceState);
- return result;
+ return state.getEvent() != null ? Collections.singletonMap(state.getEvent(), position) : null;
}
}
diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java
index 347ad9005..4d6aa8857 100644
--- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
* Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,111 +16,65 @@
*/
package org.traccar.handler.events;
-import java.util.Collections;
-import java.util.Map;
-
import io.netty.channel.ChannelHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.traccar.config.Config;
import org.traccar.config.Keys;
-import org.traccar.database.DeviceManager;
-import org.traccar.database.GeofenceManager;
+import org.traccar.helper.model.AttributeUtil;
+import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Device;
-import org.traccar.model.DeviceState;
import org.traccar.model.Event;
import org.traccar.model.Geofence;
import org.traccar.model.Position;
+import org.traccar.session.cache.CacheManager;
+import org.traccar.session.state.OverspeedProcessor;
+import org.traccar.session.state.OverspeedState;
+import org.traccar.storage.Storage;
+import org.traccar.storage.StorageException;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Collections;
+import java.util.Map;
+@Singleton
@ChannelHandler.Sharable
public class OverspeedEventHandler extends BaseEventHandler {
- public static final String ATTRIBUTE_SPEED = "speed";
- public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit";
+ private static final Logger LOGGER = LoggerFactory.getLogger(OverspeedEventHandler.class);
- private final DeviceManager deviceManager;
- private final GeofenceManager geofenceManager;
+ private final CacheManager cacheManager;
+ private final Storage storage;
- private final boolean notRepeat;
private final long minimalDuration;
private final boolean preferLowest;
- public OverspeedEventHandler(Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) {
- this.deviceManager = deviceManager;
- this.geofenceManager = geofenceManager;
- notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT);
+ @Inject
+ public OverspeedEventHandler(
+ Config config, CacheManager cacheManager, Storage storage) {
+ this.cacheManager = cacheManager;
+ this.storage = storage;
minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000;
preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST);
}
- private Map<Event, Position> newEvent(DeviceState deviceState, double speedLimit) {
- Position position = deviceState.getOverspeedPosition();
- Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position);
- event.set(ATTRIBUTE_SPEED, deviceState.getOverspeedPosition().getSpeed());
- event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit);
- event.setGeofenceId(deviceState.getOverspeedGeofenceId());
- deviceState.setOverspeedState(notRepeat);
- deviceState.setOverspeedPosition(null);
- deviceState.setOverspeedGeofenceId(0);
- return Collections.singletonMap(event, position);
- }
-
- public Map<Event, Position> updateOverspeedState(DeviceState deviceState, double speedLimit) {
- Map<Event, Position> result = null;
- if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState()
- && deviceState.getOverspeedPosition() != null && speedLimit != 0) {
- long currentTime = System.currentTimeMillis();
- Position overspeedPosition = deviceState.getOverspeedPosition();
- long overspeedTime = overspeedPosition.getFixTime().getTime();
- if (overspeedTime + minimalDuration <= currentTime) {
- result = newEvent(deviceState, speedLimit);
- }
- }
- return result;
- }
-
- public Map<Event, Position> updateOverspeedState(
- DeviceState deviceState, Position position, double speedLimit, long geofenceId) {
- Map<Event, Position> result = null;
-
- Boolean oldOverspeed = deviceState.getOverspeedState();
-
- long currentTime = position.getFixTime().getTime();
- boolean newOverspeed = position.getSpeed() > speedLimit;
- if (newOverspeed && !oldOverspeed) {
- if (deviceState.getOverspeedPosition() == null) {
- deviceState.setOverspeedPosition(position);
- deviceState.setOverspeedGeofenceId(geofenceId);
- }
- } else if (oldOverspeed && !newOverspeed) {
- deviceState.setOverspeedState(false);
- deviceState.setOverspeedPosition(null);
- deviceState.setOverspeedGeofenceId(0);
- } else {
- deviceState.setOverspeedPosition(null);
- deviceState.setOverspeedGeofenceId(0);
- }
- Position overspeedPosition = deviceState.getOverspeedPosition();
- if (overspeedPosition != null) {
- long overspeedTime = overspeedPosition.getFixTime().getTime();
- if (newOverspeed && overspeedTime + minimalDuration <= currentTime) {
- result = newEvent(deviceState, speedLimit);
- }
- }
- return result;
- }
-
@Override
protected Map<Event, Position> analyzePosition(Position position) {
long deviceId = position.getDeviceId();
- Device device = deviceManager.getById(deviceId);
+ Device device = cacheManager.getObject(Device.class, position.getDeviceId());
if (device == null) {
return null;
}
- if (!deviceManager.isLatestPosition(position) || !position.getValid()) {
+ if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) {
return null;
}
- double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, true, false);
+ double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId);
double positionSpeedLimit = position.getDouble(Position.KEY_SPEED_LIMIT);
if (positionSpeedLimit > 0) {
@@ -130,11 +84,11 @@ public class OverspeedEventHandler extends BaseEventHandler {
double geofenceSpeedLimit = 0;
long overspeedGeofenceId = 0;
- if (geofenceManager != null && device.getGeofenceIds() != null) {
+ if (device.getGeofenceIds() != null) {
for (long geofenceId : device.getGeofenceIds()) {
- Geofence geofence = geofenceManager.getById(geofenceId);
+ Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId);
if (geofence != null) {
- double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT);
+ double currentSpeedLimit = geofence.getDouble(Keys.EVENT_OVERSPEED_LIMIT.getKey());
if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0
|| preferLowest && currentSpeedLimit < geofenceSpeedLimit
|| !preferLowest && currentSpeedLimit > geofenceSpeedLimit) {
@@ -152,18 +106,19 @@ public class OverspeedEventHandler extends BaseEventHandler {
return null;
}
- Map<Event, Position> result = null;
- DeviceState deviceState = deviceManager.getDeviceState(deviceId);
-
- if (deviceState.getOverspeedState() == null) {
- deviceState.setOverspeedState(position.getSpeed() > speedLimit);
- deviceState.setOverspeedGeofenceId(position.getSpeed() > speedLimit ? overspeedGeofenceId : 0);
- } else {
- result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId);
+ OverspeedState state = OverspeedState.fromDevice(device);
+ OverspeedProcessor.updateState(state, position, speedLimit, minimalDuration, overspeedGeofenceId);
+ if (state.isChanged()) {
+ state.toDevice(device);
+ try {
+ storage.updateObject(device, new Request(
+ new Columns.Include("overspeedState", "overspeedTime", "overspeedGeofenceId"),
+ new Condition.Equals("id", device.getId())));
+ } catch (StorageException e) {
+ LOGGER.warn("Update device overspeed error", e);
+ }
}
-
- deviceManager.setDeviceState(deviceId, deviceState);
- return result;
+ return state.getEvent() != null ? Collections.singletonMap(state.getEvent(), position) : null;
}
}