diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2019-03-31 22:35:39 -0700 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2019-03-31 22:35:39 -0700 |
commit | 59416923dcb3a756eaf532cc4259f2f6625c0762 (patch) | |
tree | 9082dae6616deac8fda432b7bfd80e4a52b6d9dc /src/main/java/org/traccar/handler/events | |
parent | 79a129dd6327d932133d6b9a50190d3f4927bff9 (diff) | |
download | trackermap-server-59416923dcb3a756eaf532cc4259f2f6625c0762.tar.gz trackermap-server-59416923dcb3a756eaf532cc4259f2f6625c0762.tar.bz2 trackermap-server-59416923dcb3a756eaf532cc4259f2f6625c0762.zip |
Convert project to gradle
Diffstat (limited to 'src/main/java/org/traccar/handler/events')
10 files changed, 788 insertions, 0 deletions
diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java new file mode 100644 index 000000000..0b7c8d23e --- /dev/null +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -0,0 +1,59 @@ +/* + * Copyright 2016 - 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 java.util.Collections; +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; + +@ChannelHandler.Sharable +public class AlertEventHandler extends BaseEventHandler { + + private final IdentityManager identityManager; + private final boolean ignoreDuplicateAlerts; + + public AlertEventHandler(Config config, IdentityManager identityManager) { + this.identityManager = identityManager; + ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS); + } + + @Override + protected Map<Event, Position> analyzePosition(Position position) { + Object alarm = position.getAttributes().get(Position.KEY_ALARM); + if (alarm != null) { + boolean ignoreAlert = false; + if (ignoreDuplicateAlerts) { + Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + if (lastPosition != null && alarm.equals(lastPosition.getAttributes().get(Position.KEY_ALARM))) { + ignoreAlert = true; + } + } + if (!ignoreAlert) { + Event event = new Event(Event.TYPE_ALARM, position.getDeviceId(), position.getId()); + event.set(Position.KEY_ALARM, (String) alarm); + return Collections.singletonMap(event, position); + } + } + return null; + } + +} diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java new file mode 100644 index 000000000..41f677f6c --- /dev/null +++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 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 java.util.Map; + +import org.traccar.BaseDataHandler; +import org.traccar.Context; +import org.traccar.model.Event; +import org.traccar.model.Position; + +public abstract class BaseEventHandler extends BaseDataHandler { + + @Override + protected Position handlePosition(Position position) { + Map<Event, Position> events = analyzePosition(position); + if (events != null && Context.getNotificationManager() != null) { + Context.getNotificationManager().updateEvents(events); + } + return position; + } + + protected abstract Map<Event, Position> analyzePosition(Position position); + +} diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java new file mode 100644 index 000000000..cfe676653 --- /dev/null +++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java @@ -0,0 +1,39 @@ +/* + * Copyright 2016 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 java.util.Collections; +import java.util.Map; + +import io.netty.channel.ChannelHandler; +import org.traccar.model.Event; +import org.traccar.model.Position; + +@ChannelHandler.Sharable +public class CommandResultEventHandler extends BaseEventHandler { + + @Override + protected Map<Event, Position> analyzePosition(Position position) { + Object commandResult = position.getAttributes().get(Position.KEY_RESULT); + if (commandResult != null) { + Event event = new Event(Event.TYPE_COMMAND_RESULT, position.getDeviceId(), position.getId()); + event.set(Position.KEY_RESULT, (String) commandResult); + return Collections.singletonMap(event, position); + } + return null; + } + +} diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java new file mode 100644 index 000000000..994df93fa --- /dev/null +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -0,0 +1,57 @@ +/* + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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 java.util.Collections; +import java.util.Map; + +import io.netty.channel.ChannelHandler; +import org.traccar.database.IdentityManager; +import org.traccar.model.Event; +import org.traccar.model.Position; + +@ChannelHandler.Sharable +public class DriverEventHandler extends BaseEventHandler { + + private final IdentityManager identityManager; + + public DriverEventHandler(IdentityManager identityManager) { + this.identityManager = identityManager; + } + + @Override + protected Map<Event, Position> analyzePosition(Position position) { + if (!identityManager.isLatestPosition(position)) { + return null; + } + String driverUniqueId = position.getString(Position.KEY_DRIVER_UNIQUE_ID); + if (driverUniqueId != null) { + String oldDriverUniqueId = null; + Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + if (lastPosition != null) { + oldDriverUniqueId = lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); + } + if (!driverUniqueId.equals(oldDriverUniqueId)) { + Event event = new Event(Event.TYPE_DRIVER_CHANGED, position.getDeviceId(), position.getId()); + event.set(Position.KEY_DRIVER_UNIQUE_ID, driverUniqueId); + return Collections.singletonMap(event, position); + } + } + return null; + } + +} diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java new file mode 100644 index 000000000..59de61bba --- /dev/null +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -0,0 +1,70 @@ +/* + * 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, 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.getDeviceId(), position.getId()); + event.set(ATTRIBUTE_FUEL_DROP_THRESHOLD, fuelDropThreshold); + return Collections.singletonMap(event, 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 new file mode 100644 index 000000000..067c97957 --- /dev/null +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -0,0 +1,89 @@ +/* + * Copyright 2016 - 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 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.GeofenceManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Calendar; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; + +@ChannelHandler.Sharable +public class GeofenceEventHandler extends BaseEventHandler { + + private final IdentityManager identityManager; + private final GeofenceManager geofenceManager; + private final CalendarManager calendarManager; + + public GeofenceEventHandler( + IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager) { + this.identityManager = identityManager; + this.geofenceManager = geofenceManager; + this.calendarManager = calendarManager; + } + + @Override + protected Map<Event, Position> analyzePosition(Position position) { + Device device = identityManager.getById(position.getDeviceId()); + if (device == null) { + return null; + } + if (!identityManager.isLatestPosition(position) || !position.getValid()) { + return null; + } + + List<Long> currentGeofences = geofenceManager.getCurrentDeviceGeofences(position); + List<Long> oldGeofences = new ArrayList<>(); + if (device.getGeofenceIds() != null) { + oldGeofences.addAll(device.getGeofenceIds()); + } + List<Long> newGeofences = new ArrayList<>(currentGeofences); + newGeofences.removeAll(oldGeofences); + oldGeofences.removeAll(currentGeofences); + + device.setGeofenceIds(currentGeofences); + + Map<Event, Position> events = new HashMap<>(); + for (long geofenceId : oldGeofences) { + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; + if (calendar == null || calendar.checkMoment(position.getFixTime())) { + Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId()); + event.setGeofenceId(geofenceId); + events.put(event, position); + } + } + for (long geofenceId : newGeofences) { + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; + if (calendar == null || calendar.checkMoment(position.getFixTime())) { + Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId()); + event.setGeofenceId(geofenceId); + events.put(event, position); + } + } + return events; + } + +} diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java new file mode 100644 index 000000000..ec133bafc --- /dev/null +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -0,0 +1,65 @@ +/* + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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 java.util.Collections; +import java.util.Map; + +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; + +@ChannelHandler.Sharable +public class IgnitionEventHandler extends BaseEventHandler { + + private final IdentityManager identityManager; + + public IgnitionEventHandler(IdentityManager identityManager) { + this.identityManager = identityManager; + } + + @Override + protected Map<Event, Position> analyzePosition(Position position) { + Device device = identityManager.getById(position.getDeviceId()); + if (device == null || !identityManager.isLatestPosition(position)) { + return null; + } + + Map<Event, Position> result = null; + + if (position.getAttributes().containsKey(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)) { + boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); + + if (ignition && !oldIgnition) { + result = Collections.singletonMap( + new Event(Event.TYPE_IGNITION_ON, position.getDeviceId(), position.getId()), position); + } else if (!ignition && oldIgnition) { + result = Collections.singletonMap( + new Event(Event.TYPE_IGNITION_OFF, position.getDeviceId(), position.getId()), position); + } + } + } + return result; + } + +} diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java new file mode 100644 index 000000000..93ae74142 --- /dev/null +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@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 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; + +@ChannelHandler.Sharable +public class MaintenanceEventHandler extends BaseEventHandler { + + private final IdentityManager identityManager; + private final MaintenancesManager maintenancesManager; + + public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) { + this.identityManager = identityManager; + this.maintenancesManager = maintenancesManager; + } + + @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) { + return null; + } + + Map<Event, Position> events = new HashMap<>(); + for (long maintenanceId : maintenancesManager.getAllDeviceItems(position.getDeviceId())) { + Maintenance maintenance = maintenancesManager.getById(maintenanceId); + 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()) + < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { + Event event = new Event(Event.TYPE_MAINTENANCE, position.getDeviceId(), position.getId()); + event.setMaintenanceId(maintenanceId); + event.set(maintenance.getType(), newValue); + events.put(event, position); + } + } + } + + return events; + } + +} diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java new file mode 100644 index 000000000..9ec02ccfb --- /dev/null +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -0,0 +1,135 @@ +/* + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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 java.util.Collections; +import java.util.Map; + +import io.netty.channel.ChannelHandler; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +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; + +@ChannelHandler.Sharable +public class MotionEventHandler extends BaseEventHandler { + + private final IdentityManager identityManager; + private final DeviceManager deviceManager; + private final TripsConfig tripsConfig; + + public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { + this.identityManager = identityManager; + this.deviceManager = deviceManager; + 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.getDeviceId(), position.getId()); + 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); + if (device == null) { + return null; + } + if (!identityManager.isLatestPosition(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); + } + deviceManager.setDeviceState(deviceId, deviceState); + return result; + } + +} diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java new file mode 100644 index 000000000..157bb64e0 --- /dev/null +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -0,0 +1,164 @@ +/* + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 Andrey Kunitsyn (andrey@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 java.util.Collections; +import java.util.Map; + +import io.netty.channel.ChannelHandler; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.database.DeviceManager; +import org.traccar.database.GeofenceManager; +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; + +@ChannelHandler.Sharable +public class OverspeedEventHandler extends BaseEventHandler { + + public static final String ATTRIBUTE_SPEED = "speed"; + public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; + + private final DeviceManager deviceManager; + private final GeofenceManager geofenceManager; + + 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); + 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.getDeviceId(), position.getId()); + 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); + if (device == null) { + return null; + } + if (!deviceManager.isLatestPosition(position) || !position.getValid()) { + return null; + } + + double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); + + double geofenceSpeedLimit = 0; + long overspeedGeofenceId = 0; + + if (geofenceManager != null && device.getGeofenceIds() != null) { + for (long geofenceId : device.getGeofenceIds()) { + Geofence geofence = geofenceManager.getById(geofenceId); + if (geofence != null) { + double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); + if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 + || preferLowest && currentSpeedLimit < geofenceSpeedLimit + || !preferLowest && currentSpeedLimit > geofenceSpeedLimit) { + geofenceSpeedLimit = currentSpeedLimit; + overspeedGeofenceId = geofenceId; + } + } + } + } + if (geofenceSpeedLimit > 0) { + speedLimit = geofenceSpeedLimit; + } + + if (speedLimit == 0) { + 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); + } + + deviceManager.setDeviceState(deviceId, deviceState); + return result; + } + +} |