From b5e180da135c48afc3d89665000b6de0e6a330e3 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 16 Jun 2017 09:30:32 +0500 Subject: Centralized motion detection --- src/org/traccar/BasePipelineFactory.java | 7 ++++ src/org/traccar/MotionHandler.java | 41 ++++++++++++++++++++++ src/org/traccar/events/MotionEventHandler.java | 16 +++------ src/org/traccar/protocol/Gl200ProtocolDecoder.java | 2 +- src/org/traccar/reports/ReportUtils.java | 7 +++- test/org/traccar/MotionHandlerTest.java | 21 +++++++++++ test/org/traccar/ProtocolTest.java | 4 +++ .../org/traccar/events/MotionEventHandlerTest.java | 2 +- 8 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 src/org/traccar/MotionHandler.java create mode 100644 test/org/traccar/MotionHandlerTest.java diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index 11457905d..45213c1a1 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -51,6 +51,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { private FilterHandler filterHandler; private CoordinatesHandler coordinatesHandler; private DistanceHandler distanceHandler; + private MotionHandler motionHandler; private GeocoderHandler geocoderHandler; private GeolocationHandler geolocationHandler; private HemisphereHandler hemisphereHandler; @@ -147,6 +148,8 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { distanceHandler = new DistanceHandler(); + motionHandler = new MotionHandler(Context.getConfig().getDouble("event.motion.speedThreshold", 0.01)); + if (Context.getConfig().hasKey("location.latitudeHemisphere") || Context.getConfig().hasKey("location.longitudeHemisphere")) { hemisphereHandler = new HemisphereHandler(); @@ -212,6 +215,10 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { pipeline.addLast("distance", distanceHandler); } + if (motionHandler != null) { + pipeline.addLast("motion", motionHandler); + } + if (copyAttributesHandler != null) { pipeline.addLast("copyAttributes", copyAttributesHandler); } diff --git a/src/org/traccar/MotionHandler.java b/src/org/traccar/MotionHandler.java new file mode 100644 index 000000000..fa3d51858 --- /dev/null +++ b/src/org/traccar/MotionHandler.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017 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; + +import org.traccar.model.Position; + +public class MotionHandler extends BaseDataHandler { + + private double speedThreshold; + + public MotionHandler(double speedThreshold) { + this.speedThreshold = speedThreshold; + } + + public Position calculateMotion(Position position) { + if (!position.getAttributes().containsKey(Position.KEY_MOTION)) { + position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold); + } + return position; + } + + @Override + protected Position handlePosition(Position position) { + return calculateMotion(position); + } + +} diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index be8218985..e6fd10f3e 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -26,12 +26,6 @@ import org.traccar.model.Position; public class MotionEventHandler extends BaseEventHandler { - private double speedThreshold; - - public MotionEventHandler() { - speedThreshold = Context.getConfig().getDouble("event.motion.speedThreshold", 0.01); - } - @Override protected Collection analyzePosition(Position position) { @@ -43,16 +37,16 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - double speed = position.getSpeed(); - double oldSpeed = 0; + boolean motion = position.getBoolean(Position.KEY_MOTION); + boolean oldMotion = false; Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); if (lastPosition != null) { - oldSpeed = lastPosition.getSpeed(); + oldMotion = lastPosition.getBoolean(Position.KEY_MOTION); } - if (speed > speedThreshold && oldSpeed <= speedThreshold) { + if (motion && !oldMotion) { return Collections.singleton( new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId())); - } else if (speed <= speedThreshold && oldSpeed > speedThreshold) { + } else if (!motion && oldMotion) { return Collections.singleton( new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId())); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 0927f53fd..a3062c942 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -716,7 +716,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { int reportType = parser.nextInt(0); if (type.equals("NMR")) { - position.set(Position.KEY_MOTION, reportType); + position.set(Position.KEY_MOTION, reportType == 1); } else if (type.equals("SOS")) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); } diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 1e004beae..cd30a61c4 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -220,7 +220,12 @@ public final class ReportUtils { >= tripsConfig.getMinimalNoDataDuration()) { return false; } - return positions.get(index).getSpeed() > speedThreshold; + if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) + && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { + return positions.get(index).getBoolean(Position.KEY_MOTION); + } else { + return positions.get(index).getSpeed() > speedThreshold; + } } public static Collection detectTripsAndStops(TripsConfig tripsConfig, boolean ignoreOdometer, diff --git a/test/org/traccar/MotionHandlerTest.java b/test/org/traccar/MotionHandlerTest.java new file mode 100644 index 000000000..d716a5ec7 --- /dev/null +++ b/test/org/traccar/MotionHandlerTest.java @@ -0,0 +1,21 @@ +package org.traccar; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.traccar.model.Position; + +public class MotionHandlerTest { + + @Test + public void testCalculateMotion() throws Exception { + + MotionHandler motionHandler = new MotionHandler(0.01); + + Position position = motionHandler.calculateMotion(new Position()); + + assertEquals(false, position.getAttributes().get(Position.KEY_MOTION)); + + } + +} diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index ee5811e49..eaecfab0b 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -237,6 +237,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_CHARGE) instanceof Boolean); } + if (attributes.containsKey(Position.KEY_MOTION)) { + Assert.assertTrue(attributes.get(Position.KEY_MOTION) instanceof Boolean); + } + if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { for (CellTower cellTower : position.getNetwork().getCellTowers()) { checkInteger(cellTower.getMobileCountryCode(), 0, 999); diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index 622680d91..f05ef54d5 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -18,7 +18,7 @@ public class MotionEventHandlerTest extends BaseTest { MotionEventHandler motionEventHandler = new MotionEventHandler(); Position position = new Position(); - position.setSpeed(10.0); + position.set(Position.KEY_MOTION, true); position.setValid(true); Collection events = motionEventHandler.analyzePosition(position); assertNotNull(events); -- cgit v1.2.3 From 9a3889863bc8b0140ccdcaa1ba1982903202b67b Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 16 Jun 2017 09:51:57 +0500 Subject: Fix last Stop if it is last position in period --- src/org/traccar/reports/ReportUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index cd30a61c4..705f11429 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -300,7 +300,7 @@ public final class ReportUtils { previousEndParkingIndex)); } } - result.add(calculateStop(positions, startParkingIndex, endParkingIndex)); + result.add(calculateStop(positions, startParkingIndex, isLast ? i : endParkingIndex)); } } previousEndParkingIndex = endParkingIndex; -- cgit v1.2.3 From b1d5a5cfd165d2b52cf4dcdc57a6825e0ff1db8f Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 16 Jun 2017 11:42:35 +0500 Subject: Remove intermediate functions --- src/org/traccar/DistanceHandler.java | 8 ++------ src/org/traccar/MotionHandler.java | 8 ++------ test/org/traccar/DistanceHandlerTest.java | 2 +- test/org/traccar/MotionHandlerTest.java | 2 +- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/org/traccar/DistanceHandler.java b/src/org/traccar/DistanceHandler.java index fdf9847a7..0ab2d9048 100644 --- a/src/org/traccar/DistanceHandler.java +++ b/src/org/traccar/DistanceHandler.java @@ -31,7 +31,8 @@ public class DistanceHandler extends BaseDataHandler { return null; } - public Position calculateDistance(Position position) { + @Override + protected Position handlePosition(Position position) { double distance = 0.0; double totalDistance = 0.0; @@ -59,9 +60,4 @@ public class DistanceHandler extends BaseDataHandler { return position; } - @Override - protected Position handlePosition(Position position) { - return calculateDistance(position); - } - } diff --git a/src/org/traccar/MotionHandler.java b/src/org/traccar/MotionHandler.java index fa3d51858..901965dd5 100644 --- a/src/org/traccar/MotionHandler.java +++ b/src/org/traccar/MotionHandler.java @@ -26,16 +26,12 @@ public class MotionHandler extends BaseDataHandler { this.speedThreshold = speedThreshold; } - public Position calculateMotion(Position position) { + @Override + protected Position handlePosition(Position position) { if (!position.getAttributes().containsKey(Position.KEY_MOTION)) { position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold); } return position; } - @Override - protected Position handlePosition(Position position) { - return calculateMotion(position); - } - } diff --git a/test/org/traccar/DistanceHandlerTest.java b/test/org/traccar/DistanceHandlerTest.java index b14caaec5..66b2f3d1c 100644 --- a/test/org/traccar/DistanceHandlerTest.java +++ b/test/org/traccar/DistanceHandlerTest.java @@ -12,7 +12,7 @@ public class DistanceHandlerTest { DistanceHandler distanceHandler = new DistanceHandler(); - Position position = distanceHandler.calculateDistance(new Position()); + Position position = distanceHandler.handlePosition(new Position()); assertEquals(0.0, position.getAttributes().get(Position.KEY_DISTANCE)); assertEquals(0.0, position.getAttributes().get(Position.KEY_TOTAL_DISTANCE)); diff --git a/test/org/traccar/MotionHandlerTest.java b/test/org/traccar/MotionHandlerTest.java index d716a5ec7..fc6dce033 100644 --- a/test/org/traccar/MotionHandlerTest.java +++ b/test/org/traccar/MotionHandlerTest.java @@ -12,7 +12,7 @@ public class MotionHandlerTest { MotionHandler motionHandler = new MotionHandler(0.01); - Position position = motionHandler.calculateMotion(new Position()); + Position position = motionHandler.handlePosition(new Position()); assertEquals(false, position.getAttributes().get(Position.KEY_MOTION)); -- cgit v1.2.3