From b19f1a505f7088ff48f467b32b5f1c207aa3be01 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 12 Jul 2017 14:22:03 +0500 Subject: - Handle rfid attributes and populate driverUniqueId - Add Driver Name to Trip report --- test/org/traccar/ProtocolTest.java | 4 ++++ test/org/traccar/processing/PopulateDriverTest.java | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/org/traccar/processing/PopulateDriverTest.java (limited to 'test/org') diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 3b801c6eb..dc4f70981 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -245,6 +245,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_ARCHIVE) instanceof Boolean); } + if (attributes.containsKey(Position.KEY_RFID)) { + Assert.assertTrue(attributes.get(Position.KEY_RFID) instanceof String); + } + 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/processing/PopulateDriverTest.java b/test/org/traccar/processing/PopulateDriverTest.java new file mode 100644 index 000000000..7c6ee9f06 --- /dev/null +++ b/test/org/traccar/processing/PopulateDriverTest.java @@ -0,0 +1,21 @@ +package org.traccar.processing; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.model.Position; + +public class PopulateDriverTest { + + @Test + public void testPopulateDriver() { + Position position = new Position(); + PopulateDriverHandler populateDriverHandler = new PopulateDriverHandler(); + Assert.assertNull(populateDriverHandler.handlePosition(position).getString(Position.KEY_DRIVER_UNIQUE_ID)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, "123"); + Assert.assertEquals("123", + populateDriverHandler.handlePosition(position).getString(Position.KEY_DRIVER_UNIQUE_ID)); + position.set(Position.KEY_RFID, "321"); + Assert.assertEquals("321", + populateDriverHandler.handlePosition(position).getString(Position.KEY_DRIVER_UNIQUE_ID)); + } +} -- cgit v1.2.3 From beffaa1bcb14965e34d533cf7c771886c5832391 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Jul 2017 05:57:21 +1200 Subject: Add Teltonika UDP tests --- src/org/traccar/protocol/TeltonikaProtocol.java | 4 ++-- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 11 +++++++---- .../org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 14 +++++++++++++- 3 files changed, 22 insertions(+), 7 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TeltonikaProtocol.java b/src/org/traccar/protocol/TeltonikaProtocol.java index 524e6d5b5..d0177da97 100644 --- a/src/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/org/traccar/protocol/TeltonikaProtocol.java @@ -39,14 +39,14 @@ public class TeltonikaProtocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new TeltonikaFrameDecoder()); pipeline.addLast("objectEncoder", new TeltonikaProtocolEncoder()); - pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this)); + pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("objectEncoder", new TeltonikaProtocolEncoder()); - pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this)); + pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); } }); } diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 3f5b68f67..d8a7b0bc0 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -35,8 +35,11 @@ import java.util.List; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { - public TeltonikaProtocolDecoder(TeltonikaProtocol protocol) { + boolean connectionless; + + public TeltonikaProtocolDecoder(TeltonikaProtocol protocol, boolean connectionless) { super(protocol); + this.connectionless = connectionless; } private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { @@ -249,7 +252,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int locationPacketId, String... imei) { List positions = new LinkedList<>(); - if (!(channel instanceof DatagramChannel)) { + if (!connectionless) { buf.readUnsignedInt(); // data length } @@ -278,7 +281,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - if (channel instanceof DatagramChannel) { + if (connectionless) { ChannelBuffer response = ChannelBuffers.dynamicBuffer(); response.writeShort(5); response.writeShort(0); @@ -301,7 +304,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; - if (channel instanceof DatagramChannel) { + if (connectionless) { return decodeUdp(channel, remoteAddress, buf); } else { return decodeTcp(channel, remoteAddress, buf); diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index dd484cad7..2eb5271d1 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -1,5 +1,6 @@ package org.traccar.protocol; +import org.junit.Ignore; import org.junit.Test; import org.traccar.ProtocolTest; @@ -8,7 +9,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - TeltonikaProtocolDecoder decoder = new TeltonikaProtocolDecoder(new TeltonikaProtocol()); + TeltonikaProtocolDecoder decoder = new TeltonikaProtocolDecoder(new TeltonikaProtocol(), false); verifyNull(decoder, binary( "000F313233343536373839303132333435")); @@ -60,4 +61,15 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { } + @Ignore + @Test + public void testDecodeConnectionless() throws Exception { + + TeltonikaProtocolDecoder decoder = new TeltonikaProtocolDecoder(new TeltonikaProtocol(), true); + + verifyPositions(decoder, false, binary( + "0049cafe0122000f33353734353430373237313339373508010000015d3766f6a800003eef961ec6215e0063006d09003100070401000200f001c8000242381c18003201c7000000e10001")); + + } + } -- cgit v1.2.3 From a2e1f56adf50746425565557dd38f0e2c81a0222 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 14 Jul 2017 06:59:47 +1200 Subject: Implement extended Teltonika protocol --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 15 +++++++++++++++ .../traccar/protocol/TeltonikaProtocolDecoderTest.java | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 8c4d6f72e..c8c2e4002 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -19,6 +19,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; @@ -35,10 +36,16 @@ import java.util.List; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { private boolean connectionless; + private boolean extended; + + public void setExtended(boolean extended) { + this.extended = extended; + } public TeltonikaProtocolDecoder(TeltonikaProtocol protocol, boolean connectionless) { super(protocol); this.connectionless = connectionless; + this.extended = Context.getConfig().getBoolean(getProtocolName() + ".extended"); } private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { @@ -245,6 +252,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + // Read 16 byte data + if (extended) { + int cnt = buf.readUnsignedByte(); + for (int j = 0; j < cnt; j++) { + position.set(Position.PREFIX_IO + buf.readUnsignedByte(), ChannelBuffers.hexDump(buf.readBytes(16))); + } + } + } private List parseData( diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 2eb5271d1..50e8600cf 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -58,7 +58,12 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "00000000000000a608010000013f14a1d1ce000f0eb790209a778000ab010c0500000000000000000100003390")); - + + decoder.setExtended(true); + + verifyPositions(decoder, false, binary( + "00000000000003b5080b0000015ab5642a8800d5db1769ec01d70a020a00e3040004000e0501010200030004006000060900100a00010b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab5642e7000d5db178aec01d6d6020a0070040003000e0501010200030004006000060900100a00000b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab567050000d5db1805ec01da3c02060101040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000046f7000000000001cb000000000000000000000000000000000000015ab56708e800d5db1723ec01d9ec020600e5040006000e05010102000300040060000609000f0a00010b0000130000422f1018000502c700000003f7000000000001cb000000000000000000000000000000000000015ab5685cc000d5db20f7ec01d8fa02080033050007000e05010102000300040060000609000f0a00010b0000130000422f0a18000502c700000030f7000000000001cb000000000000000000000000000000000000015ab5693b6800d5db2367ec01d9430211011b040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000027f7000000000001cb000000000000000000000000000000000000015ab569433800d5db1fb2ec01d9310211008b040006000e0501010200030004006000060900110a00000b0000130000422f1318000402c700000009f7000000000001cb000000000000000000000000000000000000015ab56a0e5800d5db22a2ec01da5502100041050007000e05010102000300040060000609000f0a00000b0000130000422f1118000602c70000000ef7000000000001cb000000000000000000000000000000000000015ab56a700000d5db2afcec01ddb2020a0012050008000e05010102000300040060000609000e0a00000b0000130000422f0918000502c700000026f7000000000001cb000000000000000000000000000000000000015ab56a73e800d5db2ad8ec01de65020a014e050008000e05010102000300040060000609000f0a00010b0000130000422f0818000702c700000002f7000000000001cb000000000000000000000000000000000000015ab56a7bb800d5db2971ec01e00e020a013f040008000e0501010200030004006000060900100a00020b0000130000422f0b18000802c700000004f7000000000001cb000000000000000000000000000000000b00007c5f")); + } @Ignore -- cgit v1.2.3 From 44691a373200b0e265df5a24e159f5cdff89fb96 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 14 Jul 2017 10:56:20 +0500 Subject: Populate driverUniqueId in CopyAttributesHanler --- src/org/traccar/BasePipelineFactory.java | 8 ---- .../traccar/processing/CopyAttributesHandler.java | 1 + .../traccar/processing/PopulateDriverHandler.java | 45 ---------------------- .../org/traccar/processing/PopulateDriverTest.java | 21 ---------- 4 files changed, 1 insertion(+), 74 deletions(-) delete mode 100644 src/org/traccar/processing/PopulateDriverHandler.java delete mode 100644 test/org/traccar/processing/PopulateDriverTest.java (limited to 'test/org') diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index 98a327220..edbebc9e2 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -41,7 +41,6 @@ import org.traccar.events.AlertEventHandler; import org.traccar.helper.Log; import org.traccar.processing.ComputedAttributesHandler; import org.traccar.processing.CopyAttributesHandler; -import org.traccar.processing.PopulateDriverHandler; import java.net.InetSocketAddress; @@ -56,7 +55,6 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { private GeocoderHandler geocoderHandler; private GeolocationHandler geolocationHandler; private HemisphereHandler hemisphereHandler; - private PopulateDriverHandler populateDriverHandler; private CopyAttributesHandler copyAttributesHandler; private ComputedAttributesHandler computedAttributesHandler; @@ -156,8 +154,6 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { hemisphereHandler = new HemisphereHandler(); } - populateDriverHandler = new PopulateDriverHandler(); - if (Context.getConfig().getBoolean("processing.copyAttributes.enable")) { copyAttributesHandler = new CopyAttributesHandler(); } @@ -221,10 +217,6 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { pipeline.addLast("motion", motionHandler); } - if (populateDriverHandler != null) { - pipeline.addLast("populateDriver", populateDriverHandler); - } - if (copyAttributesHandler != null) { pipeline.addLast("copyAttributes", copyAttributesHandler); } diff --git a/src/org/traccar/processing/CopyAttributesHandler.java b/src/org/traccar/processing/CopyAttributesHandler.java index 3a96ca98d..a9e761c3d 100644 --- a/src/org/traccar/processing/CopyAttributesHandler.java +++ b/src/org/traccar/processing/CopyAttributesHandler.java @@ -35,6 +35,7 @@ public class CopyAttributesHandler extends BaseDataHandler { position.getDeviceId(), "processing.copyAttributes", null, true); Position last = getLastPosition(position.getDeviceId()); if (attributesString != null && last != null) { + attributesString += Position.KEY_DRIVER_UNIQUE_ID + ","; for (String attribute : attributesString.split("[ ,]")) { if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) { position.getAttributes().put(attribute, last.getAttributes().get(attribute)); diff --git a/src/org/traccar/processing/PopulateDriverHandler.java b/src/org/traccar/processing/PopulateDriverHandler.java deleted file mode 100644 index 339cc5548..000000000 --- a/src/org/traccar/processing/PopulateDriverHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.processing; - -import org.traccar.BaseDataHandler; -import org.traccar.Context; -import org.traccar.model.Position; - -public class PopulateDriverHandler extends BaseDataHandler { - - private Position getLastPosition(long deviceId) { - if (Context.getIdentityManager() != null) { - return Context.getIdentityManager().getLastPosition(deviceId); - } - return null; - } - - @Override - protected Position handlePosition(Position position) { - if (position.getAttributes().containsKey(Position.KEY_RFID)) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, position.getString(Position.KEY_RFID)); - } else { - Position last = getLastPosition(position.getDeviceId()); - if (last != null && last.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, last.getString(Position.KEY_DRIVER_UNIQUE_ID)); - } - } - return position; - } - -} diff --git a/test/org/traccar/processing/PopulateDriverTest.java b/test/org/traccar/processing/PopulateDriverTest.java deleted file mode 100644 index 7c6ee9f06..000000000 --- a/test/org/traccar/processing/PopulateDriverTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.traccar.processing; - -import org.junit.Assert; -import org.junit.Test; -import org.traccar.model.Position; - -public class PopulateDriverTest { - - @Test - public void testPopulateDriver() { - Position position = new Position(); - PopulateDriverHandler populateDriverHandler = new PopulateDriverHandler(); - Assert.assertNull(populateDriverHandler.handlePosition(position).getString(Position.KEY_DRIVER_UNIQUE_ID)); - position.set(Position.KEY_DRIVER_UNIQUE_ID, "123"); - Assert.assertEquals("123", - populateDriverHandler.handlePosition(position).getString(Position.KEY_DRIVER_UNIQUE_ID)); - position.set(Position.KEY_RFID, "321"); - Assert.assertEquals("321", - populateDriverHandler.handlePosition(position).getString(Position.KEY_DRIVER_UNIQUE_ID)); - } -} -- cgit v1.2.3 From 9949cadcdf3f07a4590742e2f0303d82efb653f9 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 14 Jul 2017 11:34:58 +0500 Subject: Save driver identification (rfid/ibutton etc.) as driverUniqueId attribute --- src/org/traccar/model/Position.java | 1 - src/org/traccar/protocol/AplicomProtocolDecoder.java | 2 +- src/org/traccar/protocol/AstraProtocolDecoder.java | 2 +- src/org/traccar/protocol/AtrackProtocolDecoder.java | 2 +- src/org/traccar/protocol/FifotrackProtocolDecoder.java | 2 +- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 2 +- src/org/traccar/protocol/GnxProtocolDecoder.java | 2 +- src/org/traccar/protocol/Gps103ProtocolDecoder.java | 2 +- src/org/traccar/protocol/MegastekProtocolDecoder.java | 2 +- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 4 ++-- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 2 +- src/org/traccar/protocol/MxtProtocolDecoder.java | 2 +- src/org/traccar/protocol/OsmAndProtocolDecoder.java | 2 +- src/org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- src/org/traccar/protocol/StarLinkProtocolDecoder.java | 2 +- src/org/traccar/protocol/Stl060ProtocolDecoder.java | 2 +- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- src/org/traccar/protocol/TmgProtocolDecoder.java | 2 +- src/org/traccar/protocol/UlbotechProtocolDecoder.java | 3 ++- src/org/traccar/protocol/VisiontekProtocolDecoder.java | 2 +- src/org/traccar/protocol/WialonProtocolDecoder.java | 2 +- test/org/traccar/ProtocolTest.java | 4 ++-- 22 files changed, 24 insertions(+), 24 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 97b3f365f..9e7bac932 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -49,7 +49,6 @@ public class Position extends Message { public static final String KEY_FUEL_LEVEL = "fuel"; // liters public static final String KEY_FUEL_CONSUMPTION = "fuelConsumption"; // liters/hour - public static final String KEY_RFID = "rfid"; public static final String KEY_VERSION_FW = "versionFw"; public static final String KEY_VERSION_HW = "versionHw"; public static final String KEY_TYPE = "type"; diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 448cd94fc..6f63d0c17 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -263,7 +263,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0200) != 0) { - position.set(Position.KEY_RFID, + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); } diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java index ea6aa7b30..8d86cd2be 100644 --- a/src/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/org/traccar/protocol/AstraProtocolDecoder.java @@ -105,7 +105,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // geofence events if (BitUtil.check(status, 8)) { - position.set(Position.KEY_RFID, buf.readBytes(7).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readBytes(7).toString(StandardCharsets.US_ASCII)); position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000); position.set(Position.KEY_HOURS, buf.readUnsignedShort()); } diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 79b3c36cc..23cb67e15 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -327,7 +327,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.001); - position.set("driver", readString(buf)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, readString(buf)); position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1); position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1); diff --git a/src/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/org/traccar/protocol/FifotrackProtocolDecoder.java index f8f4fb078..304f6a2c3 100644 --- a/src/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -110,7 +110,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16)); } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); if (parser.hasNext()) { String[] sensors = parser.next().split("\\|"); diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index a3062c942..140d3300a 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -644,7 +644,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return null; } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); decodeLocation(position, parser); diff --git a/src/org/traccar/protocol/GnxProtocolDecoder.java b/src/org/traccar/protocol/GnxProtocolDecoder.java index 070d394e8..2274ec164 100644 --- a/src/org/traccar/protocol/GnxProtocolDecoder.java +++ b/src/org/traccar/protocol/GnxProtocolDecoder.java @@ -102,7 +102,7 @@ public class GnxProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); if (type.equals("MIF")) { - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); } return position; diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index f5ba3cff7..a9a72b110 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -258,7 +258,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { String rfid = parser.next(); if (alarm.equals("rfid")) { - position.set(Position.KEY_RFID, rfid); + position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); } String utcHours = parser.next(); diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 15a384cc0..994e2d983 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -327,7 +327,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { } } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); String battery = parser.next(); if (battery != null) { diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index 77e117262..dbbf61f71 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -253,7 +253,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext()) { - position.set(Position.KEY_RFID, String.valueOf(parser.nextHexInt(0))); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt(0))); } return position; @@ -370,7 +370,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { if (rfid != 0) { String card = String.format("%010d", rfid); position.set("card" + (i + 1), card); - position.set(Position.KEY_RFID, card); + position.set(Position.KEY_DRIVER_UNIQUE_ID, card); } } } diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 38ecde519..711697fc4 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -201,7 +201,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { if (eventData != null && !eventData.isEmpty()) { switch (event) { case 37: - position.set(Position.KEY_RFID, eventData); + position.set(Position.KEY_DRIVER_UNIQUE_ID, eventData); break; default: position.set("eventData", eventData); diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java index 49987ce57..6d82e4a4b 100644 --- a/src/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/org/traccar/protocol/MxtProtocolDecoder.java @@ -159,7 +159,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(infoGroups, 7)) { - position.set(Position.KEY_RFID, buf.readUnsignedInt()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedInt())); } buf.readerIndex(buf.writerIndex() - 3); diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 20cd54b2f..cb324aa86 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -129,7 +129,7 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); break; case "rfid": - position.set(Position.KEY_RFID, value); + position.set(Position.KEY_DRIVER_UNIQUE_ID, value); break; default: try { diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java index b1851f8ca..e12bbdf28 100644 --- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -129,7 +129,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); if (parser.hasNext()) { int value = parser.nextHexInt(0); diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java index e90dde455..38f6980f6 100644 --- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -196,7 +196,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { if (rfid.matches("0+")) { rfid = data[data.length - 2]; } - position.set(Position.KEY_RFID, rfid); + position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); } return position; diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java index c81e83aab..26817a5c8 100644 --- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -104,7 +104,7 @@ public class Stl060ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); position.set(Position.KEY_INPUT, parser.nextInt(0)); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); position.set(Position.KEY_ODOMETER, parser.nextInt(0)); position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0)); position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0)); diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index f1fd55d98..72e06c083 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -114,7 +114,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; case 78: - position.set(Position.KEY_RFID, String.valueOf(readValue(buf, length, false))); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(readValue(buf, length, false))); break; case 182: position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java index c10523117..b8458dd52 100644 --- a/src/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/org/traccar/protocol/TmgProtocolDecoder.java @@ -144,7 +144,7 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, parser.nextDouble(0)); position.set(Position.PREFIX_ADC + 2, parser.nextDouble(0)); position.set(Position.KEY_VERSION_FW, parser.next()); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); return position; } diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java index 1b22eeb75..31a3d2cfe 100644 --- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -308,7 +308,8 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { break; case DATA_RFID: - position.set(Position.KEY_RFID, buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, + buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII)); position.set("authorized", buf.readUnsignedByte() != 0); break; diff --git a/src/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/org/traccar/protocol/VisiontekProtocolDecoder.java index 636a3d640..f32c9fbfe 100644 --- a/src/org/traccar/protocol/VisiontekProtocolDecoder.java +++ b/src/org/traccar/protocol/VisiontekProtocolDecoder.java @@ -130,7 +130,7 @@ public class VisiontekProtocolDecoder extends BaseProtocolDecoder { position.setValid(parser.next().equals("A")); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); return position; } diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java index 82098413b..4eb3b9b8e 100644 --- a/src/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/org/traccar/protocol/WialonProtocolDecoder.java @@ -109,7 +109,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); if (parser.hasNext()) { String[] values = parser.next().split(","); diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index dc4f70981..cb9cdf759 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -245,8 +245,8 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_ARCHIVE) instanceof Boolean); } - if (attributes.containsKey(Position.KEY_RFID)) { - Assert.assertTrue(attributes.get(Position.KEY_RFID) instanceof String); + if (attributes.containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + Assert.assertTrue(attributes.get(Position.KEY_DRIVER_UNIQUE_ID) instanceof String); } if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { -- cgit v1.2.3 From 1b4bcb2cef3f4e3907ed0820478f2f3cae245c7f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 11:41:44 +1200 Subject: Fix TK103 identification issue --- src/org/traccar/protocol/Tk103ProtocolDecoder.java | 16 +++++----------- test/org/traccar/protocol/Tk103ProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index 4c7da12e0..0106e5bf3 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -200,17 +200,11 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { String id = sentence.substring(0, 12); String type = sentence.substring(12, 16); - if (type.equals("BP00") || type.equals("BP05")) { - String content = sentence.substring(16); - if (content.length() >= 15) { - getDeviceSession(channel, remoteAddress, content.substring(0, 15)); - } - if (type.equals("BP00")) { - channel.write("(" + id + "AP01HSO)"); - return null; - } else if (type.equals("BP05")) { - channel.write("(" + id + "AP05)"); - } + if (type.equals("BP00")) { + channel.write("(" + id + "AP01HSO)"); + return null; + } else if (type.equals("BP05")) { + channel.write("(" + id + "AP05)"); } } diff --git a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 4d872b082..f2ee8ffe5 100644 --- a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { Tk103ProtocolDecoder decoder = new Tk103ProtocolDecoder(new Tk103Protocol()); + verifyNull(decoder, text( + "(027044702512BP00027044702512HSO01A4)")); + verifyPosition(decoder, text( "(864768011069660,ZC11,250517,V,0000.0000N,00000.0000E,000.0,114725,000.0,0.00,11)")); -- cgit v1.2.3 From 7a17135f9b0b1ae127b9cb5ea4f29e0af98a813b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 12:05:36 +1200 Subject: Extend eelink protocol decoder --- .../traccar/protocol/EelinkProtocolDecoder.java | 41 +++++++++++++++++----- .../protocol/EelinkProtocolDecoderTest.java | 14 +++++++- 2 files changed, 45 insertions(+), 10 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 0f6551cc3..e16866977 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -96,6 +96,22 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeStatus(Position position, int status) { + if (BitUtil.check(status, 1)) { + position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); + } + if (BitUtil.check(status, 3)) { + position.set(Position.KEY_ARMED, BitUtil.check(status, 4)); + } + if (BitUtil.check(status, 5)) { + position.set(Position.KEY_BLOCKED, !BitUtil.check(status, 6)); + } + if (BitUtil.check(status, 7)) { + position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); + } + position.set(Position.KEY_STATUS, status); + } + private Position decodeOld(DeviceSession deviceSession, ChannelBuffer buf, int type, int index) { Position position = new Position(); @@ -119,16 +135,11 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); } - if (buf.readableBytes() >= 2 * 5) { + if (buf.readableBytes() >= 2) { + decodeStatus(position, buf.readUnsignedShort()); + } - int status = buf.readUnsignedShort(); - if (BitUtil.check(status, 1)) { - position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); - } - if (BitUtil.check(status, 7)) { - position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); - } - position.set(Position.KEY_STATUS, status); + if (buf.readableBytes() >= 2 * 4) { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); @@ -221,6 +232,18 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return decodeOld(deviceSession, buf, type, index); } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) { return decodeNew(deviceSession, buf, index); + } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) { + + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); + + getLastLocation(position, null); + + decodeStatus(position, buf.readUnsignedShort()); + + return position; + } } diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index 8aabf8375..46c85d89a 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,18 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "6767050022001F59643640000000000000000000000001CC0000249500142000015964A6C0006E")); + + verifyAttributes(decoder, binary( + "67670300040021006E")); + + verifyPosition(decoder, binary( + "676705002200255964369D000000000000000000000001CC0000249500142000025964A71D006A")); + + verifyAttributes(decoder, binary( + "67670300040028006A")); + verifyPosition(decoder, binary( "676712002d066c592cca6803002631a60b22127700240046005c08020d000301af000da0fd12007f11ce05820000001899c0")); @@ -46,7 +58,7 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000b001b035418804661834901")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "6767030004001A0001")); verifyNull(decoder, binary( -- cgit v1.2.3 From 7c3351939eca27d349417f053ef98a7e4e2668fd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 13:17:05 +1200 Subject: Implement GL200 frame decoder --- src/org/traccar/protocol/Gl200FrameDecoder.java | 96 ++++++++++++++++++++++ src/org/traccar/protocol/Gl200Protocol.java | 5 +- .../traccar/protocol/Gl200FrameDecoderTest.java | 28 +++++++ 3 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/org/traccar/protocol/Gl200FrameDecoder.java create mode 100644 test/org/traccar/protocol/Gl200FrameDecoderTest.java (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200FrameDecoder.java b/src/org/traccar/protocol/Gl200FrameDecoder.java new file mode 100644 index 000000000..960c3779a --- /dev/null +++ b/src/org/traccar/protocol/Gl200FrameDecoder.java @@ -0,0 +1,96 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class Gl200FrameDecoder extends FrameDecoder { + + private static final int MINIMUM_LENGTH = 11; + + private static final Set BINARY_HEADERS = new HashSet<>( + Arrays.asList("+RSP", "+BSP", "+EVT", "+BVT", "+INF", "+BNF", "+HBD", "+CRD", "+BRD")); + + public static boolean isBinary(ChannelBuffer buf) { + String header = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); + if (header.equals("+ACK")) { + return buf.getByte(buf.readerIndex() + header.length()) != (byte) ':'; + } else { + return BINARY_HEADERS.contains(header); + } + } + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + + if (buf.readableBytes() < MINIMUM_LENGTH) { + return null; + } + + if (isBinary(buf)) { + + int length; + switch (buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII)) { + case "+ACK": + length = buf.getUnsignedByte(buf.readerIndex() + 6); + break; + case "+INF": + case "+BNF": + length = buf.getUnsignedShort(buf.readerIndex() + 7); + break; + case "+HBD": + length = buf.getUnsignedByte(buf.readerIndex() + 5); + break; + case "+CRD": + case "+BRD": + length = buf.getUnsignedShort(buf.readerIndex() + 6); + break; + default: + length = buf.getUnsignedShort(buf.readerIndex() + 9); + break; + } + + if (buf.readableBytes() >= length) { + return buf.readBytes(length); + } + + } else { + + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '$'); + if (endIndex < 0) { + endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); + } + if (endIndex > 0) { + ChannelBuffer frame = buf.readBytes(endIndex - buf.readerIndex()); + buf.readByte(); // delimiter + return frame; + } + + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index b3743042c..3ea371085 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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,7 +21,6 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -44,7 +43,7 @@ public class Gl200Protocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(4096, "$", "\0")); + pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); diff --git a/test/org/traccar/protocol/Gl200FrameDecoderTest.java b/test/org/traccar/protocol/Gl200FrameDecoderTest.java new file mode 100644 index 000000000..54c35f084 --- /dev/null +++ b/test/org/traccar/protocol/Gl200FrameDecoderTest.java @@ -0,0 +1,28 @@ +package org.traccar.protocol; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Gl200FrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Gl200FrameDecoder decoder = new Gl200FrameDecoder(); + + Assert.assertEquals( + binary("2b41434b017f244501010108676231303000000000ffff07e1070b03112d054dfe030d0a"), + decoder.decode(null, null, binary("2b41434b017f244501010108676231303000000000ffff07e1070b03112d054dfe030d0a"))); + + Assert.assertEquals( + binary("2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a"), + decoder.decode(null, null, binary("2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a"))); + + Assert.assertEquals( + binary("2b524553503a47545354522c3430303330302c3836323336353033303134323238392c474c3530302c302c302c302c33392e342c39332c312c302e332c31372c3130352e382c32352e3934343234302c34342e3430333733362c32303137303532393134303533302c303232362c303030312c353643322c373038342c2c2c2c32303137303532393136303533302c30324441"), + decoder.decode(null, null, binary("2b524553503a47545354522c3430303330302c3836323336353033303134323238392c474c3530302c302c302c302c33392e342c39332c312c302e332c31372c3130352e382c32352e3934343234302c34342e3430333733362c32303137303532393134303533302c303232362c303030312c353643322c373038342c2c2c2c32303137303532393136303533302c3032444124"))); + + } + +} -- cgit v1.2.3 From 8bb68423f9a1e3c30f900e89f2016bfcc26a324b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 13:29:32 +1200 Subject: Rename GL200 text protocol decoder --- src/org/traccar/protocol/Gl200Protocol.java | 6 +- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 878 -------------------- .../traccar/protocol/Gl200TextProtocolDecoder.java | 880 +++++++++++++++++++++ .../traccar/protocol/Gl200ProtocolDecoderTest.java | 291 ------- .../protocol/Gl200TextProtocolDecoderTest.java | 291 +++++++ 5 files changed, 1173 insertions(+), 1173 deletions(-) delete mode 100644 src/org/traccar/protocol/Gl200ProtocolDecoder.java create mode 100644 src/org/traccar/protocol/Gl200TextProtocolDecoder.java delete mode 100644 test/org/traccar/protocol/Gl200ProtocolDecoderTest.java create mode 100644 test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index 3ea371085..dbcbf61c0 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -45,18 +45,16 @@ public class Gl200Protocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java deleted file mode 100644 index 140d3300a..000000000 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ /dev/null @@ -1,878 +0,0 @@ -/* - * Copyright 2012 - 2017 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.protocol; - -import org.jboss.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Gl200ProtocolDecoder extends BaseProtocolDecoder { - - private boolean ignoreFixTime; - - public Gl200ProtocolDecoder(Gl200Protocol protocol) { - super(protocol); - - ignoreFixTime = Context.getConfig().getBoolean(getProtocolName() + ".ignoreFixTime"); - } - - private static final Pattern PATTERN_ACK = new PatternBuilder() - .text("+ACK:GT") - .expression("...,") // type - .number("([0-9A-Z]{2}xxxx),") // protocol version - .number("(d{15}|x{14}),") // imei - .any().text(",") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_INF = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTINF,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17},)?") // vin - .expression("(?:[^,]+)?,") // device name - .number("(xx),") // state - .expression("(?:[0-9F]{20})?,") // iccid - .number("d{1,2},") - .number("d{1,2},") - .expression("[01],") // external power - .number("([d.]+)?,") // odometer or external power - .number("d*,") // backup battery or lightness - .number("(d+.d+),") // battery - .expression("([01]),") // charging - .number("(?:d),") // led - .number("(?:d)?,") // gps on need - .number("(?:d)?,") // gps antenna type - .number("(?:d),").optional() // gps antenna state - .number("d{14},") // last fix time - .groupBegin() - .number("(d+),") // battery percentage - .expression("[01]?,") // flash type - .number("(-?[d.]+)?,,,") // temperature - .or() - .expression("(?:[01])?,").optional() // pin15 mode - .number("(d+)?,") // adc1 - .number("(d+)?,").optional() // adc2 - .number("(xx)?,") // digital input - .number("(xx)?,") // digital output - .number("[-+]dddd,") // timezone - .expression("[01],") // daylight saving - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_VER = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTVER,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .expression("([^,]*),") // device type - .number("(xxxx),") // firmware version - .number("(xxxx),") // hardware version - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+)?,") // mcc - .number("(d+)?,") // mnc - .groupBegin() - .number("(d+),") // lac - .number("(d+),") // cid - .or() - .number("(x+)?,") // lac - .number("(x+)?,") // cid - .groupEnd() - .number("(?:d+|(d+.d))?,") // odometer - .compile(); - - private static final Pattern PATTERN_OBD = new PatternBuilder() - .text("+RESP:GTOBD,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17})?,") // vin - .expression("[^,]{0,20},") // device name - .expression("[01],") // report type - .number("x{1,8},") // report mask - .expression("(?:[0-9A-Z]{17})?,") // vin - .number("[01],") // obd connect - .number("(?:d{1,5})?,") // obd voltage - .number("(?:x{8})?,") // support pids - .number("(d{1,5})?,") // engine rpm - .number("(d{1,3})?,") // speed - .number("(-?d{1,3})?,") // coolant temp - .number("(d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d{1,5})?,") // dtcs cleared distance - .number("(?:d{1,5})?,") - .expression("([01])?,") // obd connect - .number("(d{1,3})?,") // number of dtcs - .number("(x*),") // dtcs - .number("(d{1,3})?,") // throttle - .number("(?:d{1,3})?,") // engine load - .number("(d{1,3})?,") // fuel level - .expression("(?:[0-9A],)?") // obd protocol - .number("(d+),") // odometer - .expression(PATTERN_LOCATION.pattern()) - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_FRI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTFRI,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:([0-9A-Z]{17}),)?") // vin - .expression("[^,]*,") // device name - .number("(d+)?,") // power - .number("d{1,2},") // report type - .number("d{1,2},") // count - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .number("(d+)?,") // rpm - .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d+)?,") // fuel level - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_ERI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTERI,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("x{8},") // mask - .number("(d+)?,") // power - .number("d{1,2},") // report type - .number("d{1,2},") // count - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .expression("(.*)") // additional data - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_IGN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTIG[NF],") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d+,") // ignition off duration - .expression(PATTERN_LOCATION.pattern()) - .number("(d{5}:dd:dd)?,") // hour meter - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_IDA = new PatternBuilder() - .text("+RESP:GTIDA,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,,") // device name - .number("([^,]+),") // rfid - .expression("[01],") // report type - .number("1,") // count - .expression(PATTERN_LOCATION.pattern()) - .number("(d+.d),") // odometer - .text(",,,,") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_WIF = new PatternBuilder() - .text("+RESP:GTWIF,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(d+),") // count - .number("((?:x{12},-?d+,,,,)+),,,,") // wifi - .number("(d{1,3}),") // battery - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_GSM = new PatternBuilder() - .text("+RESP:GTGSM,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:STR|CTN|NMR|RTL),") // fix type - .expression("(.*)") // cells - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d*,") - .number("(d{1,2}),") // report type - .number("d{1,2},") // count - .expression(PATTERN_LOCATION.pattern()) - .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() - .number("(d{1,7}.d)?,") // odometer - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_BASIC = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version - .number("(d{15}|x{14}),") // imei - .any() - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(x+),") // lac - .number("(x+),").optional(4) // cell - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN_ACK, sentence); - if (parser.matches()) { - String protocolVersion = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - if (type.equals("HBD")) { - if (channel != null) { - parser.skip(6); - channel.write("+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress); - } - } else { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, parser.nextDateTime()); - position.setValid(false); - position.set(Position.KEY_RESULT, "Command " + type + " accepted"); - return position; - } - } - return null; - } - - private Position initPosition(Parser parser, Channel channel, SocketAddress remoteAddress) { - if (parser.matches()) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession != null) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - return position; - } - } - return null; - } - - private void decodeDeviceTime(Position position, Parser parser) { - if (parser.hasNext(6)) { - if (ignoreFixTime) { - position.setTime(parser.nextDateTime()); - } else { - position.setDeviceTime(parser.nextDateTime()); - } - } - } - - private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_INF, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_STATUS, parser.next()); - - parser.next(); // odometer or external power - - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - position.set(Position.PREFIX_TEMP + 1, parser.next()); - - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - - getLastLocation(position, parser.nextDateTime()); - - position.set(Position.KEY_INDEX, parser.nextHexInt(0)); - - return position; - } - - private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_VER, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set("deviceType", parser.next()); - position.set(Position.KEY_VERSION_FW, parser.nextHexInt(0)); - position.set(Position.KEY_VERSION_HW, parser.nextHexInt(0)); - - getLastLocation(position, parser.nextDateTime()); - - return position; - } - - private void decodeLocation(Position position, Parser parser) { - int hdop = parser.nextInt(0); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext(8)) { - position.setValid(true); - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - position.setTime(parser.nextDateTime()); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(6)) { - int mcc = parser.nextInt(0); - int mnc = parser.nextInt(0); - if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(0), parser.nextInt(0)))); - } - if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0)))); - } - } - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - } - - private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_OBD, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_OBD_SPEED, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); - position.set("dtcsClearedDistance", parser.nextInt()); - position.set("odbConnect", parser.nextInt(0) == 1); - position.set("dtcsNumber", parser.nextInt()); - position.set("dtcsCodes", parser.next()); - position.set(Position.KEY_THROTTLE, parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.KEY_OBD_ODOMETER, parser.nextInt(0) * 1000); - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private void decodeStatus(Position position, Parser parser) { - if (parser.hasNext(3)) { - int ignition = parser.nextHexInt(0); - if (BitUtil.check(ignition, 4)) { - position.set(Position.KEY_IGNITION, false); - } else if (BitUtil.check(ignition, 5)) { - position.set(Position.KEY_IGNITION, true); - } - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); - } - } - - private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_FRI, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - LinkedList positions = new LinkedList<>(); - - String vin = parser.next(); - int power = parser.nextInt(0); - - Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); - while (itemParser.find()) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VIN, vin); - - decodeLocation(position, itemParser); - - positions.add(position); - } - - Position position = positions.getLast(); - - decodeLocation(position, parser); - - // power value only on some devices - if (power > 10) { - position.set(Position.KEY_POWER, power); - } - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - decodeStatus(position, parser); - - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - - decodeDeviceTime(position, parser); - - return positions; - } - - private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_ERI, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - LinkedList positions = new LinkedList<>(); - - int power = parser.nextInt(0); - - Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); - while (itemParser.find()) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - decodeLocation(position, itemParser); - - positions.add(position); - } - - Position position = positions.getLast(); - - decodeLocation(position, parser); - - position.set(Position.KEY_POWER, power); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - decodeStatus(position, parser); - - int index = 0; - String[] data = parser.next().split(","); - if (data.length > 1) { - int deviceType = Integer.parseInt(data[index++]); - if (deviceType == 2) { - int deviceCount = Integer.parseInt(data[index++]); - for (int i = 1; i <= deviceCount; i++) { - index++; // id - index++; // type - position.set(Position.PREFIX_TEMP + i, Short.parseShort(data[index++], 16) * 0.0625); - } - } - } - - decodeDeviceTime(position, parser); - - return positions; - } - - private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_IGN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - decodeLocation(position, parser); - - position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_IDA, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_WIF, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - Network network = new Network(); - - parser.nextInt(0); // count - Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next()); - while (matcher.find()) { - String mac = matcher.group(1).replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), Integer.parseInt(matcher.group(2)))); - } - - position.setNetwork(network); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - return position; - } - - private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_GSM, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - Network network = new Network(); - - String[] data = parser.next().split(","); - for (int i = 0; i < 6; i++) { - if (!data[i * 6].isEmpty()) { - network.addCellTower(CellTower.from( - Integer.parseInt(data[i * 6]), Integer.parseInt(data[i * 6 + 1]), - Integer.parseInt(data[i * 6 + 2], 16), Integer.parseInt(data[i * 6 + 3], 16), - Integer.parseInt(data[i * 6 + 4]))); - } - } - - position.setNetwork(network); - - return position; - } - - private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - int reportType = parser.nextInt(0); - if (type.equals("NMR")) { - position.set(Position.KEY_MOTION, reportType == 1); - } else if (type.equals("SOS")) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { - channel.write("+SACK:" + parser.next() + "$", remoteAddress); - } - - return position; - } - - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN_BASIC, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - int hdop = parser.nextInt(0); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext(2)) { - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(6)) { - position.setTime(parser.nextDateTime()); - } - - if (parser.hasNext(4)) { - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - } - - decodeDeviceTime(position, parser); - - switch (type) { - case "PNA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case "PFA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - case "EPN": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case "EPF": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "BPL": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "STT": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case "SWG": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); - break; - case "TMP": - case "TEM": - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case "JDR": - case "JDS": - position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); - break; - default: - break; - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - int typeIndex = sentence.indexOf(":GT"); - if (typeIndex < 0) { - return null; - } - - Object result; - String type = sentence.substring(typeIndex + 3, typeIndex + 6); - if (sentence.startsWith("+ACK")) { - result = decodeAck(channel, remoteAddress, sentence, type); - } else { - switch (type) { - case "INF": - result = decodeInf(channel, remoteAddress, sentence); - break; - case "OBD": - result = decodeObd(channel, remoteAddress, sentence); - break; - case "FRI": - result = decodeFri(channel, remoteAddress, sentence); - break; - case "ERI": - result = decodeEri(channel, remoteAddress, sentence); - break; - case "IGN": - case "IGF": - result = decodeIgn(channel, remoteAddress, sentence); - break; - case "IDA": - result = decodeIda(channel, remoteAddress, sentence); - break; - case "WIF": - result = decodeWif(channel, remoteAddress, sentence); - break; - case "GSM": - result = decodeGsm(channel, remoteAddress, sentence); - break; - case "VER": - result = decodeVer(channel, remoteAddress, sentence); - break; - default: - result = decodeOther(channel, remoteAddress, sentence, type); - break; - } - - if (result == null) { - result = decodeBasic(channel, remoteAddress, sentence, type); - } - - if (result != null) { - if (result instanceof Position) { - ((Position) result).set(Position.KEY_TYPE, type); - } else { - for (Position p : (List) result) { - p.set(Position.KEY_TYPE, type); - } - } - } - } - - return result; - } - -} diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java new file mode 100644 index 000000000..57fecc3fe --- /dev/null +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -0,0 +1,880 @@ +/* + * Copyright 2012 - 2017 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; +import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { + + private boolean ignoreFixTime; + + public Gl200TextProtocolDecoder(Gl200Protocol protocol) { + super(protocol); + + ignoreFixTime = Context.getConfig().getBoolean(getProtocolName() + ".ignoreFixTime"); + } + + private static final Pattern PATTERN_ACK = new PatternBuilder() + .text("+ACK:GT") + .expression("...,") // type + .number("([0-9A-Z]{2}xxxx),") // protocol version + .number("(d{15}|x{14}),") // imei + .any().text(",") + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_INF = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTINF,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:[0-9A-Z]{17},)?") // vin + .expression("(?:[^,]+)?,") // device name + .number("(xx),") // state + .expression("(?:[0-9F]{20})?,") // iccid + .number("d{1,2},") + .number("d{1,2},") + .expression("[01],") // external power + .number("([d.]+)?,") // odometer or external power + .number("d*,") // backup battery or lightness + .number("(d+.d+),") // battery + .expression("([01]),") // charging + .number("(?:d),") // led + .number("(?:d)?,") // gps on need + .number("(?:d)?,") // gps antenna type + .number("(?:d),").optional() // gps antenna state + .number("d{14},") // last fix time + .groupBegin() + .number("(d+),") // battery percentage + .expression("[01]?,") // flash type + .number("(-?[d.]+)?,,,") // temperature + .or() + .expression("(?:[01])?,").optional() // pin15 mode + .number("(d+)?,") // adc1 + .number("(d+)?,").optional() // adc2 + .number("(xx)?,") // digital input + .number("(xx)?,") // digital output + .number("[-+]dddd,") // timezone + .expression("[01],") // daylight saving + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_VER = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTVER,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .expression("([^,]*),") // device type + .number("(xxxx),") // firmware version + .number("(xxxx),") // hardware version + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .number("(d{1,2})?,") // hdop + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(d+)?,") // mcc + .number("(d+)?,") // mnc + .groupBegin() + .number("(d+),") // lac + .number("(d+),") // cid + .or() + .number("(x+)?,") // lac + .number("(x+)?,") // cid + .groupEnd() + .number("(?:d+|(d+.d))?,") // odometer + .compile(); + + private static final Pattern PATTERN_OBD = new PatternBuilder() + .text("+RESP:GTOBD,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:[0-9A-Z]{17})?,") // vin + .expression("[^,]{0,20},") // device name + .expression("[01],") // report type + .number("x{1,8},") // report mask + .expression("(?:[0-9A-Z]{17})?,") // vin + .number("[01],") // obd connect + .number("(?:d{1,5})?,") // obd voltage + .number("(?:x{8})?,") // support pids + .number("(d{1,5})?,") // engine rpm + .number("(d{1,3})?,") // speed + .number("(-?d{1,3})?,") // coolant temp + .number("(d+.?d*|Inf|NaN)?,") // fuel consumption + .number("(d{1,5})?,") // dtcs cleared distance + .number("(?:d{1,5})?,") + .expression("([01])?,") // obd connect + .number("(d{1,3})?,") // number of dtcs + .number("(x*),") // dtcs + .number("(d{1,3})?,") // throttle + .number("(?:d{1,3})?,") // engine load + .number("(d{1,3})?,") // fuel level + .expression("(?:[0-9A],)?") // obd protocol + .number("(d+),") // odometer + .expression(PATTERN_LOCATION.pattern()) + .number("(d{1,7}.d)?,") // odometer + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_FRI = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTFRI,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:([0-9A-Z]{17}),)?") // vin + .expression("[^,]*,") // device name + .number("(d+)?,") // power + .number("d{1,2},") // report type + .number("d{1,2},") // count + .expression("((?:") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+)") + .groupBegin() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .number("(d{5}:dd:dd)?,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,") // adc 2 + .number("(d{1,3})?,") // battery + .number("(?:(xx)(xx)(xx))?,") // device status + .number("(d+)?,") // rpm + .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption + .number("(d+)?,") // fuel level + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_ERI = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTERI,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("x{8},") // mask + .number("(d+)?,") // power + .number("d{1,2},") // report type + .number("d{1,2},") // count + .expression("((?:") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+)") + .number("(d{1,7}.d)?,") // odometer + .number("(d{5}:dd:dd)?,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,") // adc 2 + .number("(d{1,3})?,") // battery + .number("(?:(xx)(xx)(xx))?,") // device status + .expression("(.*)") // additional data + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_IGN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTIG[NF],") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d+,") // ignition off duration + .expression(PATTERN_LOCATION.pattern()) + .number("(d{5}:dd:dd)?,") // hour meter + .number("(d{1,7}.d)?,") // odometer + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_IDA = new PatternBuilder() + .text("+RESP:GTIDA,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,,") // device name + .number("([^,]+),") // rfid + .expression("[01],") // report type + .number("1,") // count + .expression(PATTERN_LOCATION.pattern()) + .number("(d+.d),") // odometer + .text(",,,,") + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_WIF = new PatternBuilder() + .text("+RESP:GTWIF,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d+),") // count + .number("((?:x{12},-?d+,,,,)+),,,,") // wifi + .number("(d{1,3}),") // battery + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_GSM = new PatternBuilder() + .text("+RESP:GTGSM,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:STR|CTN|NMR|RTL),") // fix type + .expression("(.*)") // cells + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d*,") + .number("(d{1,2}),") // report type + .number("d{1,2},") // count + .expression(PATTERN_LOCATION.pattern()) + .groupBegin() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)") // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_BASIC = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF)").text(":") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version + .number("(d{15}|x{14}),") // imei + .any() + .number("(d{1,2})?,") // hdop + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+),").optional(4) // cell + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) { + Parser parser = new Parser(PATTERN_ACK, sentence); + if (parser.matches()) { + String protocolVersion = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + if (type.equals("HBD")) { + if (channel != null) { + parser.skip(6); + channel.write("+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress); + } + } else { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, parser.nextDateTime()); + position.setValid(false); + position.set(Position.KEY_RESULT, "Command " + type + " accepted"); + return position; + } + } + return null; + } + + private Position initPosition(Parser parser, Channel channel, SocketAddress remoteAddress) { + if (parser.matches()) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession != null) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } + } + return null; + } + + private void decodeDeviceTime(Position position, Parser parser) { + if (parser.hasNext(6)) { + if (ignoreFixTime) { + position.setTime(parser.nextDateTime()); + } else { + position.setDeviceTime(parser.nextDateTime()); + } + } + } + + private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_INF, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.KEY_STATUS, parser.next()); + + parser.next(); // odometer or external power + + position.set(Position.KEY_BATTERY, parser.nextDouble(0)); + position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); + + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + position.set(Position.PREFIX_TEMP + 1, parser.next()); + + position.set(Position.PREFIX_ADC + 1, parser.next()); + position.set(Position.PREFIX_ADC + 2, parser.next()); + + position.set(Position.KEY_INPUT, parser.next()); + position.set(Position.KEY_OUTPUT, parser.next()); + + getLastLocation(position, parser.nextDateTime()); + + position.set(Position.KEY_INDEX, parser.nextHexInt(0)); + + return position; + } + + private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_VER, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set("deviceType", parser.next()); + position.set(Position.KEY_VERSION_FW, parser.nextHexInt(0)); + position.set(Position.KEY_VERSION_HW, parser.nextHexInt(0)); + + getLastLocation(position, parser.nextDateTime()); + + return position; + } + + private void decodeLocation(Position position, Parser parser) { + int hdop = parser.nextInt(0); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setCourse(parser.nextDouble(0)); + position.setAltitude(parser.nextDouble(0)); + + if (parser.hasNext(8)) { + position.setValid(true); + position.setLongitude(parser.nextDouble(0)); + position.setLatitude(parser.nextDouble(0)); + position.setTime(parser.nextDateTime()); + } else { + getLastLocation(position, null); + } + + if (parser.hasNext(6)) { + int mcc = parser.nextInt(0); + int mnc = parser.nextInt(0); + if (parser.hasNext(2)) { + position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(0), parser.nextInt(0)))); + } + if (parser.hasNext(2)) { + position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0)))); + } + } + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + } + + private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_OBD, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.KEY_RPM, parser.nextInt()); + position.set(Position.KEY_OBD_SPEED, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); + position.set("dtcsClearedDistance", parser.nextInt()); + position.set("odbConnect", parser.nextInt(0) == 1); + position.set("dtcsNumber", parser.nextInt()); + position.set("dtcsCodes", parser.next()); + position.set(Position.KEY_THROTTLE, parser.nextInt()); + position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + position.set(Position.KEY_OBD_ODOMETER, parser.nextInt(0) * 1000); + + decodeLocation(position, parser); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + return position; + } + + private void decodeStatus(Position position, Parser parser) { + if (parser.hasNext(3)) { + int ignition = parser.nextHexInt(0); + if (BitUtil.check(ignition, 4)) { + position.set(Position.KEY_IGNITION, false); + } else if (BitUtil.check(ignition, 5)) { + position.set(Position.KEY_IGNITION, true); + } + position.set(Position.KEY_INPUT, parser.nextHexInt(0)); + position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); + } + } + + private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_FRI, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + LinkedList positions = new LinkedList<>(); + + String vin = parser.next(); + int power = parser.nextInt(0); + + Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); + while (itemParser.find()) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_VIN, vin); + + decodeLocation(position, itemParser); + + positions.add(position); + } + + Position position = positions.getLast(); + + decodeLocation(position, parser); + + // power value only on some devices + if (power > 10) { + position.set(Position.KEY_POWER, power); + } + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.PREFIX_ADC + 1, parser.next()); + position.set(Position.PREFIX_ADC + 2, parser.next()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + decodeStatus(position, parser); + + position.set(Position.KEY_RPM, parser.nextInt()); + position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + + decodeDeviceTime(position, parser); + + return positions; + } + + private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_ERI, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + LinkedList positions = new LinkedList<>(); + + int power = parser.nextInt(0); + + Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); + while (itemParser.find()) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(position, itemParser); + + positions.add(position); + } + + Position position = positions.getLast(); + + decodeLocation(position, parser); + + position.set(Position.KEY_POWER, power); + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.PREFIX_ADC + 1, parser.next()); + position.set(Position.PREFIX_ADC + 2, parser.next()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + decodeStatus(position, parser); + + int index = 0; + String[] data = parser.next().split(","); + if (data.length > 1) { + int deviceType = Integer.parseInt(data[index++]); + if (deviceType == 2) { + int deviceCount = Integer.parseInt(data[index++]); + for (int i = 1; i <= deviceCount; i++) { + index++; // id + index++; // type + position.set(Position.PREFIX_TEMP + i, Short.parseShort(data[index++], 16) * 0.0625); + } + } + } + + decodeDeviceTime(position, parser); + + return positions; + } + + private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_IGN, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + decodeLocation(position, parser); + + position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + return position; + } + + private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_IDA, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + + decodeLocation(position, parser); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + return position; + } + + private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_WIF, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + getLastLocation(position, null); + + Network network = new Network(); + + parser.nextInt(0); // count + Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next()); + while (matcher.find()) { + String mac = matcher.group(1).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), Integer.parseInt(matcher.group(2)))); + } + + position.setNetwork(network); + + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + + return position; + } + + private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_GSM, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + getLastLocation(position, null); + + Network network = new Network(); + + String[] data = parser.next().split(","); + for (int i = 0; i < 6; i++) { + if (!data[i * 6].isEmpty()) { + network.addCellTower(CellTower.from( + Integer.parseInt(data[i * 6]), Integer.parseInt(data[i * 6 + 1]), + Integer.parseInt(data[i * 6 + 2], 16), Integer.parseInt(data[i * 6 + 3], 16), + Integer.parseInt(data[i * 6 + 4]))); + } + } + + position.setNetwork(network); + + return position; + } + + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { + Parser parser = new Parser(PATTERN, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int reportType = parser.nextInt(0); + if (type.equals("NMR")) { + position.set(Position.KEY_MOTION, reportType == 1); + } else if (type.equals("SOS")) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + + decodeLocation(position, parser); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { + channel.write("+SACK:" + parser.next() + "$", remoteAddress); + } + + return position; + } + + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) { + Parser parser = new Parser(PATTERN_BASIC, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int hdop = parser.nextInt(0); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setCourse(parser.nextDouble(0)); + position.setAltitude(parser.nextDouble(0)); + + if (parser.hasNext(2)) { + position.setLongitude(parser.nextDouble(0)); + position.setLatitude(parser.nextDouble(0)); + } else { + getLastLocation(position, null); + } + + if (parser.hasNext(6)) { + position.setTime(parser.nextDateTime()); + } + + if (parser.hasNext(4)) { + position.setNetwork(new Network(CellTower.from( + parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); + } + + decodeDeviceTime(position, parser); + + switch (type) { + case "PNA": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); + break; + case "PFA": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); + break; + case "EPN": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + break; + case "EPF": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case "BPL": + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + case "STT": + position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + break; + case "SWG": + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); + break; + case "TMP": + case "TEM": + position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); + break; + case "JDR": + case "JDS": + position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); + break; + default: + break; + } + + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = ((ChannelBuffer) msg).toString(StandardCharsets.US_ASCII); + + int typeIndex = sentence.indexOf(":GT"); + if (typeIndex < 0) { + return null; + } + + Object result; + String type = sentence.substring(typeIndex + 3, typeIndex + 6); + if (sentence.startsWith("+ACK")) { + result = decodeAck(channel, remoteAddress, sentence, type); + } else { + switch (type) { + case "INF": + result = decodeInf(channel, remoteAddress, sentence); + break; + case "OBD": + result = decodeObd(channel, remoteAddress, sentence); + break; + case "FRI": + result = decodeFri(channel, remoteAddress, sentence); + break; + case "ERI": + result = decodeEri(channel, remoteAddress, sentence); + break; + case "IGN": + case "IGF": + result = decodeIgn(channel, remoteAddress, sentence); + break; + case "IDA": + result = decodeIda(channel, remoteAddress, sentence); + break; + case "WIF": + result = decodeWif(channel, remoteAddress, sentence); + break; + case "GSM": + result = decodeGsm(channel, remoteAddress, sentence); + break; + case "VER": + result = decodeVer(channel, remoteAddress, sentence); + break; + default: + result = decodeOther(channel, remoteAddress, sentence, type); + break; + } + + if (result == null) { + result = decodeBasic(channel, remoteAddress, sentence, type); + } + + if (result != null) { + if (result instanceof Position) { + ((Position) result).set(Position.KEY_TYPE, type); + } else { + for (Position p : (List) result) { + p.set(Position.KEY_TYPE, type); + } + } + } + } + + return result; + } + +} diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java deleted file mode 100644 index 2fd15a5f6..000000000 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ /dev/null @@ -1,291 +0,0 @@ -package org.traccar.protocol; - -import org.junit.Test; -import org.traccar.ProtocolTest; - -public class Gl200ProtocolDecoderTest extends ProtocolTest { - - @Test - public void testDecode() throws Exception { - - Gl200ProtocolDecoder decoder = new Gl200ProtocolDecoder(new Gl200Protocol()); - - verifyPosition(decoder, text( - "+RESP:GTMPN,450102,865084030001323,gb100,0,1.6,0,-93.1,121.393023,31.164105,20170619103113,0460,0000,1806,2142,00,20170619103143,0512$")); - - verifyPosition(decoder, text( - "+RESP:GTTRI,862370030005908,1,0,99,1,0.0,354,18.5,18.821100,-34.084002,20170607152024,0655,0001,00DD,1CAE,00,0103010100,20170607172115,3E7D$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,060800,861074023677175,,00000002,12351,10,1,1,0.0,0,2862.4,-78.467273,-0.164998,20170529181717,,,,,,0.0,00259:11:50,,,0,210104,2,1,28E17436060000E2,1,015F,0,20170529181723,2824$")); - - verifyPosition(decoder, text( - "+RESP:GTSWG,110100,358688000000158,,1,0,2.1,0,27.1,121.390717,31.164424,20110901073917,0460,0000,1878,0873,,20110901154653,0015$")); - - verifyPosition(decoder, text( - "+RESP:GTTMP,110100,358688000000158,,2,60,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214093254,000F$")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,110100,358688000000158,,41,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,0022$")); - - verifyPosition(decoder, text( - "+RESP:GTBPL,110100,358688000000158,,3.53,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,001F$")); - - verifyNotNull(decoder, text( - "+BUFF:GTIGL,060228,862894020180553,,,00,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,20170407081824,9606$")); - - verifyNotNull(decoder, text( - "+RESP:GTFRI,060228,862894020180553,,14827,10,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,01070:43:13,13,180,0,220101,,,,20170407081824,9607$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,060502,861074023376992,,00000002,27239,10,1,1,0.2,312,183.3,-79.320820,-2.499110,20170401212005,0740,0000,EE4E,C98F,00,0.0,02114:36:35,,,90,220504,2,0,0,20170401212007,9E3D$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060502,861074023689626,,25202,10,1,1,0.0,0,2744.1,-78.261047,0.023452,20170401211940,,,,,,0.0,00079:19:15,,,51,110000,,,,20170401212003,4DA7$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,06020B,862170010196747,,00000000,,10,1,2,1.8,0,-2.5,117.198440,31.845219,20120802061037,0460,0000,5663,0358,00,0.0,,,,0,410000,20120802061040,0012$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,060502,861074023692562,,00000002,14197,10,1,1,0.2,220,491.8,-79.064212,-2.159754,20170401212007,0740,0000,EE49,CE25,00,0.0,01509:10:58,,,87,220104,2,0,0,20170401212010,D14D$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,210102,354524044925825,,1,1,1,29,2.8,0,133.7,-90.203063,32.265473,20170318005208,,,,,10800,4,20170318005208,0002$")); - - verifyPositions(decoder, false, text( - "+RESP:GTFRI,210102,354524044925825,,1,1,1,,,,,,,,310,410,51bc,ca1dae6,10800,1,20170318214333,0002$")); - - verifyAttributes(decoder, text( - "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,62a2,16,,0234,0015,003a,56a2,14,,0234,0015,003a,062a,13,,0234,0015,003a,32d9,11,,0234,0015,003a,56a0,11,,,,,,,,0234,0015,003a,7489,17,,20170219200048,0033$")); - - verifyAttributes(decoder, text( - "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,56a2,18,,0234,0015,003a,77bc,14,,0234,0015,003a,32d9,12,,0234,0015,003a,062a,12,,0234,0015,003a,62a2,11,,0234,0015,003a,56a0,10,,0234,0015,003a,7489,15,,20170219080049,0030$")); - - verifyAttributes(decoder, text( - "+RESP:GTGSM,400201,862365030034940,STR,0234,0030,0870,2469,19,,0234,0030,0870,35ee,18,,0234,0030,0870,16ac,12,,0234,0030,0870,16b2,11,,0234,0030,0870,360f,6,,0234,0030,0870,165d,6,,0234,0030,0870,35ef,17,,20170215220049,008D$")); - - verifyPosition(decoder, text( - "+RESP:GTSTR,400201,862365030034940,GL500,0,0,2,21.1,86,0,1.6,0,5.8,0.622831,51.582688,20170215090422,0234,0030,0870,35EF,,,,20170215220049,008C$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,2C0402,867162020000816,,0,0,1,2,0.3,337,245.7,-82.373387,34.634011,20170215003054,,,,,,63,20170215003241,3EAB$")); - - verifyNotNull(decoder, text( - "+RESP:GTWIF,210102,354524044608058,,4,c413e200ff14,-39,,,,c413e2010e55,-39,,,,c8d3ff04a837,-43,,,,42490f997c6d,-57,,,,,,,,100,20170201020055,0001$")); - - verifyNotNull(decoder, text( - "+RESP:GTWIF,210102,354524044484948,,1,08626693fb98,-36,,,,,,,,97,20170119071300,05E3$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,210102,A100004D9EF2AE,,41,,8,99,0,17.7,21,3.58,0,1,1,0,0,20161216135038,4,,,,,20161216135038,00AB$")); - - verifyAttributes(decoder, text( - "+RESP:GTSTR,400201,862365030034957,GL500,0,0,2,23.1,5,2,0.2,0,36.0,0.623089,51.582744,20161129174625,0234,0015,03C3,3550,,,,20161129174625,0026$")); - - verifyNotNull(decoder, text( - "+RESP:GTSTR,400201,862365030034957,GL500,0,1,2,21.8,100,0,,,,,,,0234,0015,03C3,3550,,,,20161129174009,0023$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,210102,A10000499AEF9B,,41,,0,0,0,15.0,9,3.87,0,1,1,0,0,20161101140211,72,,,,,20161101140211,00A3$")); - - verifyAttributes(decoder, text( - "+RESP:GTNMR,210102,A10000499AEF9B,,0,0,1,9,0.0,0,288.0,-76.902364,39.578828,20161101134145,,,,,00,73,20161101134145,009F$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,210102,A10000499AEF9B,,0,1,1,9,0.5,0,288.0,-76.902364,39.578828,20161101134124,,,,,00,73,20161101134123,009D$")); - - verifyAttributes(decoder, text( - "+RESP:GTRTL,210102,A10000499AEF9B,,0,0,1,10,0.2,0,305.4,-76.902274,39.578517,20161101155001,,,,,00,73,20161101155001,00A6$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,110100,358688000000158,,41,898600810906F8048812,18,99,0,33.23,1,4.19,1,1,1,0,0,20110714104934,100,,,,,20110714104934,0014$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,080100,135790246811220,,16,898600810906F8048812,16,0,1,11870,,4.1,0,0,0,,20090214013254,,12340,,00,00,+0800,0,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,040100,135790246811220,,16,898600810906F8048812,16,0,1,,0,4.4,0,0,0,0,20090214013254,13000,00,00,+0800,0,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,060100,135790246811220,,16,898600810906F8048812,16,0,1,12000,,4.4,0,0,0,0,20090214013254,0,1300,2000,00,00,+0800,0,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,17,0,1,26.6,,3.90,1,1,0,0,0,20161003184043,69,1,44,,,20161004040811,022C$")); - - verifyAttributes(decoder, text( - "+BUFF:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,23,0,1,204.7,,3.84,1,1,0,0,0,20161006072548,62,1,38,,,20161006082343,0C98$")); - - verifyPosition(decoder, text( - "+RESP:GTFRI,360100,864251020141408,3VWGW6AJ0FM237324,gv500,,10,1,1,0.0,0,2258.4,-99.256948,19.555800,20160929214743,0334,0020,0084,65AC,00,0.0,,,,100,410000,0,nan,,20160929214743,13BA$")); - - verifyPosition(decoder, text( - "+RESP:GTOBD,360201,864251020186064,4T1BE46KX7U018210,,0,19FFFF,4T1BE46KX7U018210,1,14283,983901C0,799,36,18,,33792,0,0,0,,,38,,6,53557,0,0.0,0,219.5,-76.661456,39.832588,20160507132153,20160507132154,0230$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,360201,864251020186064,1G1JC5444R7252367,,12802,10,1,0,0.0,0,219.5,-76.661456,39.832588,20160507132235,,,,,,20460.9,00080:03:37,,,100,210000,791,,56,20160507132239,0233$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,50,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,92,80,210100,,,50,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,060228,862894020178276,,21,0,0.0,0,411.3,-63.169745,-17.776330,20160319132220,0736,0003,6AD4,5BAA,00,20160319092223,1FBD$")); - - verifyPosition(decoder, text( - "+RESP:GTNMR,210102,A10000458356CE,,0,1,1,9,0.0,8,190.7,-85.765865,42.894837,20160316123202,,,,,60,30,20160316123202,0137$")); - - verifyPosition(decoder, text( - "+RESP:GTIDA,060228,862894020178276,,,01C68011010000C7,1,1,0,0.0,0,413.0,-63.169675,-17.776349,20160317222129,0736,0003,6AD4,32CF,00,34.9,,,,,20160317182130,1626$")); - - verifyPosition(decoder, text( - "+RESP:GTIGN,060228,862894020180553,,9860,0,0.2,189,420.0,-63.158195,-17.800608,20160309022951,0736,0003,6AD4,3471,00,,881.2,20160308222956,129A$")); - - verifyPosition(decoder, text( - "+BUFF:GTIGF,060228,862894020180553,,1958,0,0.0,240,390.3,-63.089213,-17.764712,20160309122854,0736,0003,6AB8,5A23,00,,936.8,20160309082858,1368$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060228,862894020180553,,,10,1,1,20.0,147,329.7,-62.899703,-17.720434,20160309113548,0736,0003,6AAE,3381,00,913.3,,,,0,220101,,,,20160309073554,132B$")); - - verifyPositions(decoder, text( - "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,2C0204,867162020003125,GL300W,0,0,2,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210433,0740,0000,7596,5891C,0.0,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210503,0740,0000,7596,5891C,0.0,88,20160215210506,1E78$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060228,862894020178276,,15153,10,1,1,0.0,0,431.7,-63.169571,-17.776235,20160210153458,0736,0003,6AD4,80EF,00,34.9,00117:31:26,13442,15163,0,210101,,,,20160210113503,38EE$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,110100,A5868800000015,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214013254,000C")); - - verifyNotNull(decoder, text( - "+RESP:GTFRI,210102,A10000458356CE,,0,1,1,15,1.4,0,190.6,-85.765763,42.894896,20160208164505,4126,210,0,18673,00,92,20160208164507,00A6")); - - verifyPositions(decoder, text( - "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); - - verifyPosition(decoder, text( - "+RESP:GTIDA,06020A,862170013895931,,,D2C4FBC5,1,1,1,0.8,0,22.2,117.198630,31.845229,20120802121626,0460,0000,5663,2BB9,00,0.0,,,,,20120802121627,008E$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); - - verifyPositions(decoder, false, text( - "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); - - verifyPosition(decoder, text( - "+RESP:GTOBD,1F0109,864251020135483,,gv500,0,78FFFF,,1,12613,,,,,,,,,,,,,,1286,0,0.0,0,17.1,3.379630,6.529701,20150813074639,0621,0030,51C0,A2B3,00,0.0,20150813074641,A7E6$")); - - verifyPosition(decoder, text( - "+RESP:GTOBD,1F0109,864251020135483,4T1BE46KX7U018210,gv500,0,78FFFF,4T1BE46KX7U018210,1,13411,981B81C0,787,3,43,,921,463,1,10,0300030103030304001200310351035203530354,20,55,,1286,0,6.5,74,21.6,3.379710,6.529714,20150813074824,0621,0030,51C0,A2B3,00,0.0,20150813074828,A7E9$")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,1A0401,860599000508846,,41,0,0.0,84,107.5,-76.657998,39.497203,20150623160622,0310,0260,B435,3B81,,20150623160622,0F54$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1A0401,860599000508846,,0,0,1,1,134.8,154,278.7,-76.671089,39.778885,20150623154301,0310,0260,043F,7761,,99,20150623154314,0F24$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1A0200,860599000165464,CRI001,0,0,1,2,,41,,-71.153137,42.301634,20150328020301,,,,,280.3,55,20150327220351,320C")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,02010D,867844001675407,,0,0,1,2,0.0,0,28.9,8.591011,56.476397,20140915213209,0238,0001,03CB,2871,,97,20140915213459,009A")); - - verifyNull(decoder, text( - "+RESP:GTINF,359464030073766,8938003990320469804f,18,99,100,1,0,+2.00,0,20131018084015,00EE,0103090402")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,04040C,359231038939904,,,10,1,2,0.0,117,346.0,8.924243,50.798077,20130618122040,0262,0002,0299,109C,00,0.0,,,,,,,,,20130618122045,00F6")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,04040C,359231038939904,,42,0,0.0,117,346.0,8.924243,50.798077,20130618125152,0262,0002,0299,109C,00,20130618125154,017A")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,020102,000035988863964,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,020102,135790246811220,,0,0,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPosition(decoder, text( - "+RESP:GTDOG,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0")); - - verifyPosition(decoder, text( - "+RESP:GTLBC,020102,135790246811220,,+8613800000000,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPosition(decoder, text( - "+RESP:GTGCR,020102,135790246811220,,3,50,180,2,0.4,296,-5.4,121.391055,31.164473,20100714104934,0460,0000,1878,0873,00,,20100714104934,000C")); - - verifyPosition(decoder, text( - "+RESP:GTFRI,07000D,868487001005941,,0,0,1,1,0.0,0,46.3,-77.039627,38.907573,20120731175232,0310,0260,B44B,EBC9,0015e96913a7,-58,,100,20120731175244,0114")); - - verifyPosition(decoder, text( - "+RESP:GTHBM,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTHBM,0F0100,135790246811220,,,11,1,1,24.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,02010C,867844001274144,,0,0,1,1,18.0,233,118.1,7.615551,51.515600,20140106130516,0262,0007,79E6,B956,,72,20140106140524,09CE$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,02010C,867844001274649,,0,0,1,1,0.0,0,122.5,7.684216,51.524512,20140106233722,0262,0007,79EE,1D22,,93,20140107003805,03C4$")); - - verifyPositions(decoder, text( - "+BUFF:GTFRI,210101,863286020016706,,,10,1,1,,,,49.903915,40.391669,20140818105815,,,,,,,,,,,210100,,,,,000C$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,240100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,80,,,,,,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,20090214093254,11F0$")); - - verifyNotNull(decoder, text( - "+RESP:GTSTT,280100,A1000043D20139,,42,0,0.1,321,228.6,-76.660884,39.832552,20150615120628,0310,0484,00600019,0A52,,20150615085741,0320$")); - - verifyNotNull(decoder, text( - "+RESP:GTRTL,280100,A1000043D20139,,0,0,1,1,0.1,321,239.1,-76.661047,39.832501,20150615114455,0310,0484,00600019,0A52,,87,20150615074456,031E$")); - - verifyAttributes(decoder, text( - "+BUFF:GTBPL,1A0800,860599000773978,GL300,3.55,0,0.0,0,257.1,60.565437,56.818277,20161006070553,,,,,204.7,20161006071028,0C75$")); - - verifyAttributes(decoder, text( - "+RESP:GTTEM,1A0102,860599000000448,,3,33,0,5.8,0,33.4,117.201191,31.832502,20130109061410,0460,0000,5678,2079,,20130109061517,0091$")); - - verifyAttributes(decoder, text( - "+RESP:GTJDR,0A0102,135790246811220,,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTJDS,0A0102,135790246811220,,2,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTSOS,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTVER,1A0800,860599000773978,GL300,GL300,0A03,0103,20161007041531,10F8$")); - - verifyNull(decoder, text( - "+ACK:GTHBD,1A0401,135790246811220,,20100214093254,11F0")); - - verifyAttributes(decoder, text( - "+ACK:GTRTO,1A0800,860599000773978,GL300,VER,FFFF,20161006053520,0C19")); - - verifyAttributes(decoder, text( - "+ACK:GTJDC,0A0102,135790246811220,,0016,20090214093254,11F0")); - - verifyAttributes(decoder, text( - "+ACK:GTGEO,1A0102,135790246811220,,0,0008,20100310172830,11F0")); - - } - -} diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java new file mode 100644 index 000000000..e694022f2 --- /dev/null +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -0,0 +1,291 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Gl200TextProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + + verifyPosition(decoder, buffer( + "+RESP:GTMPN,450102,865084030001323,gb100,0,1.6,0,-93.1,121.393023,31.164105,20170619103113,0460,0000,1806,2142,00,20170619103143,0512$")); + + verifyPosition(decoder, buffer( + "+RESP:GTTRI,862370030005908,1,0,99,1,0.0,354,18.5,18.821100,-34.084002,20170607152024,0655,0001,00DD,1CAE,00,0103010100,20170607172115,3E7D$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,060800,861074023677175,,00000002,12351,10,1,1,0.0,0,2862.4,-78.467273,-0.164998,20170529181717,,,,,,0.0,00259:11:50,,,0,210104,2,1,28E17436060000E2,1,015F,0,20170529181723,2824$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSWG,110100,358688000000158,,1,0,2.1,0,27.1,121.390717,31.164424,20110901073917,0460,0000,1878,0873,,20110901154653,0015$")); + + verifyPosition(decoder, buffer( + "+RESP:GTTMP,110100,358688000000158,,2,60,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214093254,000F$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,110100,358688000000158,,41,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,0022$")); + + verifyPosition(decoder, buffer( + "+RESP:GTBPL,110100,358688000000158,,3.53,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,001F$")); + + verifyNotNull(decoder, buffer( + "+BUFF:GTIGL,060228,862894020180553,,,00,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,20170407081824,9606$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTFRI,060228,862894020180553,,14827,10,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,01070:43:13,13,180,0,220101,,,,20170407081824,9607$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,060502,861074023376992,,00000002,27239,10,1,1,0.2,312,183.3,-79.320820,-2.499110,20170401212005,0740,0000,EE4E,C98F,00,0.0,02114:36:35,,,90,220504,2,0,0,20170401212007,9E3D$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060502,861074023689626,,25202,10,1,1,0.0,0,2744.1,-78.261047,0.023452,20170401211940,,,,,,0.0,00079:19:15,,,51,110000,,,,20170401212003,4DA7$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,06020B,862170010196747,,00000000,,10,1,2,1.8,0,-2.5,117.198440,31.845219,20120802061037,0460,0000,5663,0358,00,0.0,,,,0,410000,20120802061040,0012$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,060502,861074023692562,,00000002,14197,10,1,1,0.2,220,491.8,-79.064212,-2.159754,20170401212007,0740,0000,EE49,CE25,00,0.0,01509:10:58,,,87,220104,2,0,0,20170401212010,D14D$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,210102,354524044925825,,1,1,1,29,2.8,0,133.7,-90.203063,32.265473,20170318005208,,,,,10800,4,20170318005208,0002$")); + + verifyPositions(decoder, false, buffer( + "+RESP:GTFRI,210102,354524044925825,,1,1,1,,,,,,,,310,410,51bc,ca1dae6,10800,1,20170318214333,0002$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,62a2,16,,0234,0015,003a,56a2,14,,0234,0015,003a,062a,13,,0234,0015,003a,32d9,11,,0234,0015,003a,56a0,11,,,,,,,,0234,0015,003a,7489,17,,20170219200048,0033$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,56a2,18,,0234,0015,003a,77bc,14,,0234,0015,003a,32d9,12,,0234,0015,003a,062a,12,,0234,0015,003a,62a2,11,,0234,0015,003a,56a0,10,,0234,0015,003a,7489,15,,20170219080049,0030$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTGSM,400201,862365030034940,STR,0234,0030,0870,2469,19,,0234,0030,0870,35ee,18,,0234,0030,0870,16ac,12,,0234,0030,0870,16b2,11,,0234,0030,0870,360f,6,,0234,0030,0870,165d,6,,0234,0030,0870,35ef,17,,20170215220049,008D$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTR,400201,862365030034940,GL500,0,0,2,21.1,86,0,1.6,0,5.8,0.622831,51.582688,20170215090422,0234,0030,0870,35EF,,,,20170215220049,008C$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,2C0402,867162020000816,,0,0,1,2,0.3,337,245.7,-82.373387,34.634011,20170215003054,,,,,,63,20170215003241,3EAB$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTWIF,210102,354524044608058,,4,c413e200ff14,-39,,,,c413e2010e55,-39,,,,c8d3ff04a837,-43,,,,42490f997c6d,-57,,,,,,,,100,20170201020055,0001$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTWIF,210102,354524044484948,,1,08626693fb98,-36,,,,,,,,97,20170119071300,05E3$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,210102,A100004D9EF2AE,,41,,8,99,0,17.7,21,3.58,0,1,1,0,0,20161216135038,4,,,,,20161216135038,00AB$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTSTR,400201,862365030034957,GL500,0,0,2,23.1,5,2,0.2,0,36.0,0.623089,51.582744,20161129174625,0234,0015,03C3,3550,,,,20161129174625,0026$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTSTR,400201,862365030034957,GL500,0,1,2,21.8,100,0,,,,,,,0234,0015,03C3,3550,,,,20161129174009,0023$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,210102,A10000499AEF9B,,41,,0,0,0,15.0,9,3.87,0,1,1,0,0,20161101140211,72,,,,,20161101140211,00A3$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTNMR,210102,A10000499AEF9B,,0,0,1,9,0.0,0,288.0,-76.902364,39.578828,20161101134145,,,,,00,73,20161101134145,009F$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,210102,A10000499AEF9B,,0,1,1,9,0.5,0,288.0,-76.902364,39.578828,20161101134124,,,,,00,73,20161101134123,009D$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTRTL,210102,A10000499AEF9B,,0,0,1,10,0.2,0,305.4,-76.902274,39.578517,20161101155001,,,,,00,73,20161101155001,00A6$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,110100,358688000000158,,41,898600810906F8048812,18,99,0,33.23,1,4.19,1,1,1,0,0,20110714104934,100,,,,,20110714104934,0014$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,080100,135790246811220,,16,898600810906F8048812,16,0,1,11870,,4.1,0,0,0,,20090214013254,,12340,,00,00,+0800,0,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,040100,135790246811220,,16,898600810906F8048812,16,0,1,,0,4.4,0,0,0,0,20090214013254,13000,00,00,+0800,0,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,060100,135790246811220,,16,898600810906F8048812,16,0,1,12000,,4.4,0,0,0,0,20090214013254,0,1300,2000,00,00,+0800,0,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,17,0,1,26.6,,3.90,1,1,0,0,0,20161003184043,69,1,44,,,20161004040811,022C$")); + + verifyAttributes(decoder, buffer( + "+BUFF:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,23,0,1,204.7,,3.84,1,1,0,0,0,20161006072548,62,1,38,,,20161006082343,0C98$")); + + verifyPosition(decoder, buffer( + "+RESP:GTFRI,360100,864251020141408,3VWGW6AJ0FM237324,gv500,,10,1,1,0.0,0,2258.4,-99.256948,19.555800,20160929214743,0334,0020,0084,65AC,00,0.0,,,,100,410000,0,nan,,20160929214743,13BA$")); + + verifyPosition(decoder, buffer( + "+RESP:GTOBD,360201,864251020186064,4T1BE46KX7U018210,,0,19FFFF,4T1BE46KX7U018210,1,14283,983901C0,799,36,18,,33792,0,0,0,,,38,,6,53557,0,0.0,0,219.5,-76.661456,39.832588,20160507132153,20160507132154,0230$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,360201,864251020186064,1G1JC5444R7252367,,12802,10,1,0,0.0,0,219.5,-76.661456,39.832588,20160507132235,,,,,,20460.9,00080:03:37,,,100,210000,791,,56,20160507132239,0233$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,50,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,92,80,210100,,,50,20090214093254,11F0$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,060228,862894020178276,,21,0,0.0,0,411.3,-63.169745,-17.776330,20160319132220,0736,0003,6AD4,5BAA,00,20160319092223,1FBD$")); + + verifyPosition(decoder, buffer( + "+RESP:GTNMR,210102,A10000458356CE,,0,1,1,9,0.0,8,190.7,-85.765865,42.894837,20160316123202,,,,,60,30,20160316123202,0137$")); + + verifyPosition(decoder, buffer( + "+RESP:GTIDA,060228,862894020178276,,,01C68011010000C7,1,1,0,0.0,0,413.0,-63.169675,-17.776349,20160317222129,0736,0003,6AD4,32CF,00,34.9,,,,,20160317182130,1626$")); + + verifyPosition(decoder, buffer( + "+RESP:GTIGN,060228,862894020180553,,9860,0,0.2,189,420.0,-63.158195,-17.800608,20160309022951,0736,0003,6AD4,3471,00,,881.2,20160308222956,129A$")); + + verifyPosition(decoder, buffer( + "+BUFF:GTIGF,060228,862894020180553,,1958,0,0.0,240,390.3,-63.089213,-17.764712,20160309122854,0736,0003,6AB8,5A23,00,,936.8,20160309082858,1368$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060228,862894020180553,,,10,1,1,20.0,147,329.7,-62.899703,-17.720434,20160309113548,0736,0003,6AAE,3381,00,913.3,,,,0,220101,,,,20160309073554,132B$")); + + verifyPositions(decoder, buffer( + "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,2C0204,867162020003125,GL300W,0,0,2,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210433,0740,0000,7596,5891C,0.0,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210503,0740,0000,7596,5891C,0.0,88,20160215210506,1E78$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060228,862894020178276,,15153,10,1,1,0.0,0,431.7,-63.169571,-17.776235,20160210153458,0736,0003,6AD4,80EF,00,34.9,00117:31:26,13442,15163,0,210101,,,,20160210113503,38EE$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,110100,A5868800000015,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214013254,000C")); + + verifyNotNull(decoder, buffer( + "+RESP:GTFRI,210102,A10000458356CE,,0,1,1,15,1.4,0,190.6,-85.765763,42.894896,20160208164505,4126,210,0,18673,00,92,20160208164507,00A6")); + + verifyPositions(decoder, buffer( + "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); + + verifyPosition(decoder, buffer( + "+RESP:GTIDA,06020A,862170013895931,,,D2C4FBC5,1,1,1,0.8,0,22.2,117.198630,31.845229,20120802121626,0460,0000,5663,2BB9,00,0.0,,,,,20120802121627,008E$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); + + verifyPositions(decoder, false, buffer( + "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); + + verifyPosition(decoder, buffer( + "+RESP:GTOBD,1F0109,864251020135483,,gv500,0,78FFFF,,1,12613,,,,,,,,,,,,,,1286,0,0.0,0,17.1,3.379630,6.529701,20150813074639,0621,0030,51C0,A2B3,00,0.0,20150813074641,A7E6$")); + + verifyPosition(decoder, buffer( + "+RESP:GTOBD,1F0109,864251020135483,4T1BE46KX7U018210,gv500,0,78FFFF,4T1BE46KX7U018210,1,13411,981B81C0,787,3,43,,921,463,1,10,0300030103030304001200310351035203530354,20,55,,1286,0,6.5,74,21.6,3.379710,6.529714,20150813074824,0621,0030,51C0,A2B3,00,0.0,20150813074828,A7E9$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,1A0401,860599000508846,,41,0,0.0,84,107.5,-76.657998,39.497203,20150623160622,0310,0260,B435,3B81,,20150623160622,0F54$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1A0401,860599000508846,,0,0,1,1,134.8,154,278.7,-76.671089,39.778885,20150623154301,0310,0260,043F,7761,,99,20150623154314,0F24$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1A0200,860599000165464,CRI001,0,0,1,2,,41,,-71.153137,42.301634,20150328020301,,,,,280.3,55,20150327220351,320C")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,02010D,867844001675407,,0,0,1,2,0.0,0,28.9,8.591011,56.476397,20140915213209,0238,0001,03CB,2871,,97,20140915213459,009A")); + + verifyNull(decoder, buffer( + "+RESP:GTINF,359464030073766,8938003990320469804f,18,99,100,1,0,+2.00,0,20131018084015,00EE,0103090402")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,04040C,359231038939904,,,10,1,2,0.0,117,346.0,8.924243,50.798077,20130618122040,0262,0002,0299,109C,00,0.0,,,,,,,,,20130618122045,00F6")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,04040C,359231038939904,,42,0,0.0,117,346.0,8.924243,50.798077,20130618125152,0262,0002,0299,109C,00,20130618125154,017A")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,020102,000035988863964,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,020102,135790246811220,,0,0,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPosition(decoder, buffer( + "+RESP:GTDOG,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0")); + + verifyPosition(decoder, buffer( + "+RESP:GTLBC,020102,135790246811220,,+8613800000000,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPosition(decoder, buffer( + "+RESP:GTGCR,020102,135790246811220,,3,50,180,2,0.4,296,-5.4,121.391055,31.164473,20100714104934,0460,0000,1878,0873,00,,20100714104934,000C")); + + verifyPosition(decoder, buffer( + "+RESP:GTFRI,07000D,868487001005941,,0,0,1,1,0.0,0,46.3,-77.039627,38.907573,20120731175232,0310,0260,B44B,EBC9,0015e96913a7,-58,,100,20120731175244,0114")); + + verifyPosition(decoder, buffer( + "+RESP:GTHBM,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); + + verifyPosition(decoder, buffer( + "+RESP:GTHBM,0F0100,135790246811220,,,11,1,1,24.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,02010C,867844001274144,,0,0,1,1,18.0,233,118.1,7.615551,51.515600,20140106130516,0262,0007,79E6,B956,,72,20140106140524,09CE$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,02010C,867844001274649,,0,0,1,1,0.0,0,122.5,7.684216,51.524512,20140106233722,0262,0007,79EE,1D22,,93,20140107003805,03C4$")); + + verifyPositions(decoder, buffer( + "+BUFF:GTFRI,210101,863286020016706,,,10,1,1,,,,49.903915,40.391669,20140818105815,,,,,,,,,,,210100,,,,,000C$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,240100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,80,,,,,,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,20090214093254,11F0$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTSTT,280100,A1000043D20139,,42,0,0.1,321,228.6,-76.660884,39.832552,20150615120628,0310,0484,00600019,0A52,,20150615085741,0320$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTRTL,280100,A1000043D20139,,0,0,1,1,0.1,321,239.1,-76.661047,39.832501,20150615114455,0310,0484,00600019,0A52,,87,20150615074456,031E$")); + + verifyAttributes(decoder, buffer( + "+BUFF:GTBPL,1A0800,860599000773978,GL300,3.55,0,0.0,0,257.1,60.565437,56.818277,20161006070553,,,,,204.7,20161006071028,0C75$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTTEM,1A0102,860599000000448,,3,33,0,5.8,0,33.4,117.201191,31.832502,20130109061410,0460,0000,5678,2079,,20130109061517,0091$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTJDR,0A0102,135790246811220,,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTJDS,0A0102,135790246811220,,2,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTSOS,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTVER,1A0800,860599000773978,GL300,GL300,0A03,0103,20161007041531,10F8$")); + + verifyNull(decoder, buffer( + "+ACK:GTHBD,1A0401,135790246811220,,20100214093254,11F0")); + + verifyAttributes(decoder, buffer( + "+ACK:GTRTO,1A0800,860599000773978,GL300,VER,FFFF,20161006053520,0C19")); + + verifyAttributes(decoder, buffer( + "+ACK:GTJDC,0A0102,135790246811220,,0016,20090214093254,11F0")); + + verifyAttributes(decoder, buffer( + "+ACK:GTGEO,1A0102,135790246811220,,0,0008,20100310172830,11F0")); + + } + +} -- cgit v1.2.3 From 08cc944644cee5ce745a9faae0866b206c575407 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 14:01:52 +1200 Subject: Implement binary GL200 protocol --- .../protocol/Gl200BinaryProtocolDecoder.java | 103 +++++++++++++++++++++ src/org/traccar/protocol/Gl200Protocol.java | 5 +- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 48 ++++++++++ .../protocol/Gl200BinaryProtocolDecoderTest.java | 21 +++++ 4 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java create mode 100644 src/org/traccar/protocol/Gl200ProtocolDecoder.java create mode 100644 test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java new file mode 100644 index 000000000..cb0417528 --- /dev/null +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -0,0 +1,103 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; + +public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { + + public Gl200BinaryProtocolDecoder(Gl200Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + String header = buf.readBytes(4).toString(StandardCharsets.US_ASCII); + + if (header.equals("+EVT")) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + buf.readUnsignedByte(); // message type + + buf.readUnsignedInt(); // mask + + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version + + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); + + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedShort()); + + buf.readUnsignedByte(); // motion status + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setTime(dateBuilder.getDate()); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + return position; + + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index dbcbf61c0..799d7fe36 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; @@ -46,7 +45,7 @@ public class Gl200Protocol extends BaseProtocol { pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @@ -54,7 +53,7 @@ public class Gl200Protocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java new file mode 100644 index 000000000..0de7bb926 --- /dev/null +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; + +import java.net.SocketAddress; + +public class Gl200ProtocolDecoder extends BaseProtocolDecoder { + + private final Gl200TextProtocolDecoder textProtocolDecoder; + private final Gl200BinaryProtocolDecoder binaryProtocolDecoder; + + public Gl200ProtocolDecoder(Gl200Protocol protocol) { + super(protocol); + textProtocolDecoder = new Gl200TextProtocolDecoder(protocol); + binaryProtocolDecoder = new Gl200BinaryProtocolDecoder(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + if (Gl200FrameDecoder.isBinary(buf)) { + return binaryProtocolDecoder.decode(channel, remoteAddress, msg); + } else { + return textProtocolDecoder.decode(channel, remoteAddress, msg); + } + } + +} diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java new file mode 100644 index 000000000..42ccd4690 --- /dev/null +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + + verifyPosition(decoder, binary( + "2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a")); + + verifyNull(decoder, binary( + "2b41434b017f244501010108676231303000000000ffff07e1070b03112d054dfe030d0a")); + + } + +} -- cgit v1.2.3 From d62797376e7dc1d5810c1b8728da1e5443cc8e14 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Jul 2017 06:56:03 +1200 Subject: Refactor TAIP decoder --- src/org/traccar/protocol/TaipProtocolDecoder.java | 16 ++++++++++++++-- test/org/traccar/protocol/TaipProtocolDecoderTest.java | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index 7702a89fb..a08bb6f2b 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -104,15 +104,21 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(); position.setProtocol(getProtocolName()); + Integer event = null; + if (parser.hasNext(3)) { - position.set(Position.KEY_EVENT, parser.nextInt(0)); + event = parser.nextInt(); position.setTime(getTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0))); } else if (parser.hasNext()) { position.setTime(getTime(parser.nextInt(0))); } if (parser.hasNext()) { - position.set(Position.KEY_EVENT, parser.nextInt(0)); + event = parser.nextInt(); + } + + if (event != null) { + position.set(Position.KEY_EVENT, event); } if (parser.hasNext(6)) { @@ -150,6 +156,12 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { attributes = sentence.substring(beginIndex, endIndex).split(";"); } + return decodeAttributes(channel, remoteAddress, position, attributes); + } + + private Position decodeAttributes( + Channel channel, SocketAddress remoteAddress, Position position, String[] attributes) { + String uniqueId = null; DeviceSession deviceSession = null; String messageIndex = null; diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index 2251763cc..6d24a504f 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">REV011958000369+0307185+1016144400000032;IO=200;SV=9;BL=4158;CF=0,0,0;AD=12347;IX=10213040;FF=0,0,0,0;VO=338572;ID=357042063052352<")); + verifyPosition(decoder, text( ">REV421942237017+1170957-0701880200000032;ID=356612022463055<")); -- cgit v1.2.3 From a7c2aa4a3faddb007a82523b2119134eaa45bea7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Jul 2017 07:28:00 +1200 Subject: Implement additional Syrus data --- src/org/traccar/model/Position.java | 1 + src/org/traccar/protocol/TaipProtocolDecoder.java | 40 +++++++++++++++++----- .../traccar/protocol/TaipProtocolDecoderTest.java | 3 ++ 3 files changed, 36 insertions(+), 8 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 9e7bac932..4412b012c 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -111,6 +111,7 @@ public class Position extends Message { public static final String ALARM_TOW = "tow"; public static final String ALARM_ACCELERATION = "hardAcceleration"; public static final String ALARM_BREAKING = "hardBreaking"; + public static final String ALARM_CORNERING = "hardCornering"; public static final String ALARM_FATIGUE_DRIVING = "fatigueDriving"; public static final String ALARM_POWER_CUT = "powerCut"; public static final String ALARM_POWER_RESTORED = "powerRestored"; diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index a08bb6f2b..6edf4a93e 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.DateUtil; @@ -118,7 +119,24 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { } if (event != null) { - position.set(Position.KEY_EVENT, event); + switch (event) { + case 22: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 23: + position.set(Position.KEY_ALARM, Position.ALARM_BREAKING); + break; + case 24: + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + break; + case 26: + case 28: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + position.set(Position.KEY_EVENT, event); + break; + } } if (parser.hasNext(6)) { @@ -173,7 +191,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { String key = attribute.substring(0, index).toLowerCase(); String value = attribute.substring(index + 1); switch (key) { - case "id": uniqueId = value; deviceSession = getDeviceSession(channel, remoteAddress, value); @@ -181,23 +198,30 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); } break; - + case "io": + position.set(Position.KEY_IGNITION, BitUtil.check(value.charAt(0) - '0', 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(value.charAt(0) - '0', 1)); + position.set(Position.KEY_OUTPUT, value.charAt(1) - '0'); + position.set(Position.KEY_INPUT, value.charAt(2) - '0'); + break; + case "ix": + position.set(Position.PREFIX_IO + 1, value); + break; + case "ad": + position.set(Position.PREFIX_ADC + 1, Integer.parseInt(value)); + break; case "sv": position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); break; - case "bl": - position.set(Position.KEY_BATTERY, Integer.parseInt(value)); + position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.001); break; - case "vo": position.set(Position.KEY_ODOMETER, Long.parseLong(value)); break; - default: position.set(key, value); break; - } } else if (attribute.startsWith("#")) { messageIndex = attribute; diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index 6d24a504f..e2de26ec0 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">REV001958003965+0307178+1016144900031532;IO=300;SV=8;BL=4159;CF=8161,C,13;AD=14145;IX=10233040;FF=0,0,0,0;VO=338578;ID=357042063052352<")); + verifyPosition(decoder, text( ">REV011958000369+0307185+1016144400000032;IO=200;SV=9;BL=4158;CF=0,0,0;AD=12347;IX=10213040;FF=0,0,0,0;VO=338572;ID=357042063052352<")); -- cgit v1.2.3 From 73fb44dfb7dea5cdddcb3ab939e9b7a64ae49abb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2017 04:09:19 +1200 Subject: Support Sinocastel version 3 protocol --- src/org/traccar/protocol/CastelProtocolDecoder.java | 2 +- test/org/traccar/protocol/CastelProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index 83664fa5a..3a0ccea78 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -440,7 +440,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } - } else if (version == 4) { + } else if (version == 3 || version == 4) { return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); diff --git a/test/org/traccar/protocol/CastelProtocolDecoderTest.java b/test/org/traccar/protocol/CastelProtocolDecoderTest.java index bbc5f1f37..6b52373e1 100644 --- a/test/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class CastelProtocolDecoderTest extends ProtocolTest { CastelProtocolDecoder decoder = new CastelProtocolDecoder(new CastelProtocol()); + verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "40408200033231334c323031373030303131370000000000001001000c6759a10d67590a9e1200000000000e3e0000000000020000000e4e791c000004010d0711060515083017086cd1181f000040067d4944442d3231334c2056312e312e3120323031372d30352d3038004944442d3231334c2056312e312e3000000066e30d0a")); + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, "404043000432313345503230313630303035383500000000004006a2021d5810031d58ae940400da050000f6040000070000000400076401680000000001001bd20d0a")); -- cgit v1.2.3 From 5b56c2cc17fa23251b1985aa4d8f56dd6552b970 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2017 21:23:48 +1200 Subject: Implement JV200 ignition support --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 10 +++++++--- test/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 24bedcabf..aea3a29f4 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -336,7 +336,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); buf.readUnsignedShort(); // type - // Timezone offset if (dataLength > 10) { int extensionBits = buf.readUnsignedShort(); int hours = (extensionBits >> 4) / 100; @@ -405,7 +404,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mcc = buf.readUnsignedShort(); int mnc = buf.readUnsignedByte(); - Network network = new Network(); for (int i = 0; i < 7; i++) { network.addCellTower(CellTower.from( @@ -441,10 +439,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { decodeStatus(position, buf); } - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { + if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } + if (type == MSG_GPS_LBS_2 && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + } else { buf.skipBytes(dataLength); diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 0ac51f4b2..2e6a53b06 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "787822221106160a1016c60278019407c7783800040001940504700046fc01030100065f570d0a")); + verifyAttributes(decoder, binary( "797900143311070609020b00000000a0030046000109e4610d0a")); -- cgit v1.2.3 From 00ca2ad8bc38258199b8891a537ac54f4c3d3741 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Jul 2017 07:15:49 +1200 Subject: Add Teltonika extended test case --- test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 50e8600cf..a945178a1 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -61,6 +61,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { decoder.setExtended(true); + verifyPositions(decoder, false, binary( + "0000000000000158080b0000015d4b4dc07a00d5dbd13eec04324e020e0000120000000000000000000000015d4b4cd5e800d5dbd13eec04324e020e0000120000000000000000000000015d4b4beb8800d5dbd13eec04324e020e0000130000000000000000000000015d4b4b012800d5dbd13eec04324e020e0000120000000000000000000000015d4b4a16c800d5dbd13eec04324e020f0000110000000000000000000000015d4b492c6800d5dbd13eec04324e020f0000110000000000000000000000015d4b48420800d5dbd13eec04324e020f0000120000000000000000000000015d4b4757a800d5dbd13eec04324e020f00000f0000000000000000000000015d4b466d4800d5dbd13eec04324e020f0000100000000000000000000000015d4b4582e800d5dbd13eec04324e020f0000110000000000000000000000015d4b44988800d5dbd13eec04324e020f0000110000000000000000000b0000ec10")); + verifyPositions(decoder, false, binary( "00000000000003b5080b0000015ab5642a8800d5db1769ec01d70a020a00e3040004000e0501010200030004006000060900100a00010b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab5642e7000d5db178aec01d6d6020a0070040003000e0501010200030004006000060900100a00000b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab567050000d5db1805ec01da3c02060101040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000046f7000000000001cb000000000000000000000000000000000000015ab56708e800d5db1723ec01d9ec020600e5040006000e05010102000300040060000609000f0a00010b0000130000422f1018000502c700000003f7000000000001cb000000000000000000000000000000000000015ab5685cc000d5db20f7ec01d8fa02080033050007000e05010102000300040060000609000f0a00010b0000130000422f0a18000502c700000030f7000000000001cb000000000000000000000000000000000000015ab5693b6800d5db2367ec01d9430211011b040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000027f7000000000001cb000000000000000000000000000000000000015ab569433800d5db1fb2ec01d9310211008b040006000e0501010200030004006000060900110a00000b0000130000422f1318000402c700000009f7000000000001cb000000000000000000000000000000000000015ab56a0e5800d5db22a2ec01da5502100041050007000e05010102000300040060000609000f0a00000b0000130000422f1118000602c70000000ef7000000000001cb000000000000000000000000000000000000015ab56a700000d5db2afcec01ddb2020a0012050008000e05010102000300040060000609000e0a00000b0000130000422f0918000502c700000026f7000000000001cb000000000000000000000000000000000000015ab56a73e800d5db2ad8ec01de65020a014e050008000e05010102000300040060000609000f0a00010b0000130000422f0818000702c700000002f7000000000001cb000000000000000000000000000000000000015ab56a7bb800d5db2971ec01e00e020a013f040008000e0501010200030004006000060900100a00020b0000130000422f0b18000802c700000004f7000000000001cb000000000000000000000000000000000b00007c5f")); -- cgit v1.2.3 From d7d66e3b724cde1a681e5e7f24e930d2bddfe703 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Jul 2017 07:35:52 +1200 Subject: Fix Aplicom E driver decoding --- .../traccar/protocol/AplicomProtocolDecoder.java | 25 ++++++++++++++++------ .../protocol/AplicomProtocolDecoderTest.java | 3 +++ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 6f63d0c17..ef02cda7e 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -352,15 +352,28 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, buf.readBytes(18).toString(StandardCharsets.US_ASCII).trim()); } + if ((selector & 0x2000) != 0) { + buf.readUnsignedByte(); // card 1 type + buf.readUnsignedByte(); // card 1 country code + String card = buf.readBytes(20).toString(StandardCharsets.US_ASCII).trim(); + if (!card.isEmpty()) { + position.set("card1", card); + } + } + + if ((selector & 0x4000) != 0) { + buf.readUnsignedByte(); // card 2 type + buf.readUnsignedByte(); // card 2 country code + String card = buf.readBytes(20).toString(StandardCharsets.US_ASCII).trim(); + if (!card.isEmpty()) { + position.set("card2", card); + } + } + if ((selector & 0x10000) != 0) { int count = buf.readUnsignedByte(); for (int i = 1; i <= count; i++) { - ChannelBuffer driver = buf.readBytes(22); - int endIndex = driver.indexOf(0, driver.writerIndex(), (byte) 0); - if (endIndex < 0) { - endIndex = driver.writerIndex(); - } - position.set("driver" + i, driver.toString(0, endIndex, StandardCharsets.US_ASCII).trim()); + position.set("driver" + i, buf.readBytes(22).toString(StandardCharsets.US_ASCII).trim()); position.set("driverTime" + i, buf.readUnsignedInt()); } } diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 3c71e86b3..2498d94b3 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol()); + verifyAttributes(decoder, binary( + "45c20144f667c06ff9005d0161ef17000104596da2dc4b10c0c01d99020d6c04004cba7a010d44463030303235333731363238303030000000000000000000000000000000000000000000000000000001010d44463030303235333731363238303030000000000000031c")); + verifyAttributes(decoder, binary( "45c20144f667c07287008c01ffff6d01000059368963d0340a0616207d7f4b10c0c019e6000039d7000039d71f40ffff5001574442393036363035533132333435363700014142432d33343520202020202000011231303331373139343039303030303031000000000000000000000000000000000000000000000000000001011231303331373139343039303030303031000000000000005a")); -- cgit v1.2.3 From 2e157393d036f765687d5ff38797e6e600d986e5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 12:24:55 +1200 Subject: Add binary INF support --- .../protocol/Gl200BinaryProtocolDecoder.java | 170 ++++++++++++++++----- .../protocol/Gl200BinaryProtocolDecoderTest.java | 3 + 2 files changed, 132 insertions(+), 41 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index cb0417528..a7ecf40d5 100644 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -27,6 +27,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Date; public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { @@ -34,70 +35,157 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Date decodeTime(ChannelBuffer buf) { + DateBuilder dateBuilder = new DateBuilder() + .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + return dateBuilder.getDate(); + } - ChannelBuffer buf = (ChannelBuffer) msg; + private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { - String header = buf.readBytes(4).toString(StandardCharsets.US_ASCII); + Position position = new Position(); + position.setProtocol(getProtocolName()); - if (header.equals("+EVT")) { + buf.readUnsignedByte(); // message type + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version - Position position = new Position(); - position.setProtocol(getProtocolName()); + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - buf.readUnsignedByte(); // message type + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedInt(); // mask + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedShort()); - buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // device type - buf.readUnsignedShort(); // protocol version + buf.readUnsignedByte(); // motion status - position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_INDEX, buf.readUnsignedByte()); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, String.format("%015d", buf.readLong())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + position.setTime(decodeTime(buf)); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + return position; + } + + public static final int MSG_INF_GPS = 2; + public static final int MSG_INF_CID = 4; + public static final int MSG_INF_CSQ = 5; + public static final int MSG_INF_VER = 6; + public static final int MSG_INF_BAT = 7; + public static final int MSG_INF_TMZ = 9; + public static final int MSG_INF_GIR = 10; + + private Position decodeInformation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + int type = buf.readUnsignedByte(); + + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // motion status + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - int hdop = buf.readUnsignedByte(); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); + if (type == MSG_INF_VER) { + buf.readUnsignedShort(); // hardware version + buf.readUnsignedShort(); // mcu version + buf.readUnsignedShort(); // reserved + } - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); - position.setCourse(buf.readUnsignedShort()); - position.setAltitude(buf.readShort()); - position.setLongitude(buf.readInt() * 0.000001); - position.setLatitude(buf.readInt() * 0.000001); + buf.readUnsignedByte(); // motion status + buf.readUnsignedByte(); // reserved + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // mode + buf.skipBytes(7); // last fix time + buf.readUnsignedByte(); // reserved + buf.readUnsignedByte(); + buf.readUnsignedShort(); // response report mask + buf.readUnsignedShort(); // ign interval + buf.readUnsignedShort(); // igf interval + buf.readUnsignedInt(); // reserved + buf.readUnsignedByte(); // reserved + + if (type == MSG_INF_BAT) { + position.set(Position.KEY_CHARGE, buf.readUnsignedByte() != 0); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); + buf.skipBytes(10); // iccid + if (type == MSG_INF_CSQ) { + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + buf.readUnsignedByte(); + } + + buf.readUnsignedByte(); // time zone flags + buf.readUnsignedShort(); // time zone offset + + if (type == MSG_INF_GIR) { + buf.readUnsignedByte(); // gir trigger + buf.readUnsignedByte(); // cell number position.setNetwork(new Network(CellTower.from( buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort()))); + buf.readUnsignedByte(); // ta + buf.readUnsignedByte(); // rx level + } - buf.readUnsignedByte(); // reserved + getLastLocation(position, decodeTime(buf)); - return position; + return position; + } - } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - return null; + ChannelBuffer buf = (ChannelBuffer) msg; + + switch (buf.readBytes(4).toString(StandardCharsets.US_ASCII)) { + case "+INF": + return decodeInformation(channel, remoteAddress, buf); + case "+EVT": + return decodeEvent(channel, remoteAddress, buf); + default: + return null; + } } } diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index 42ccd4690..24830a953 100644 --- a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, binary( + "2b494e4601fd7f0076676231303000000045010202090104020500004100054007e107150b061d0000003f010e02580000000000d0312a1013648935103226313921591f1200000000000302680003189c1ac3001b02680003189c1ac4000d02680003189c1ac5001207e107150b0d3704f658060d0a")); + verifyPosition(decoder, binary( "2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a")); -- cgit v1.2.3 From 8b74b160890b9dbdd4a2d660d74d2879df6ceced Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 17:45:51 +1200 Subject: Another GT06 LBS and WiFi message type --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 122 ++++++++++++--------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 9 ++ 2 files changed, 79 insertions(+), 52 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index aea3a29f4..36358b6e5 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -31,6 +31,7 @@ import org.traccar.model.CellTower; import org.traccar.model.Device; import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; @@ -68,6 +69,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_1 = 0x16; public static final int MSG_GPS_LBS_STATUS_2 = 0x26; public static final int MSG_GPS_LBS_STATUS_3 = 0x27; + public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_PHONE = 0x17; public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; @@ -390,82 +392,98 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else { - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - position.setProtocol(getProtocolName()); + return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - if (type == MSG_LBS_EXTEND) { + } - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + return null; + } - getLastLocation(position, dateBuilder.getDate()); + private Object decodeBasicOther(Channel channel, ChannelBuffer buf, + DeviceSession deviceSession, int type, int dataLength) throws Exception { - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - Network network = new Network(); - for (int i = 0; i < 7; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); - } - position.setNetwork(network); + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); - } else if (type == MSG_STRING) { + if (type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { - getLastLocation(position, null); + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - int commandLength = buf.readUnsignedByte(); + getLastLocation(position, dateBuilder.getDate()); - if (commandLength > 0) { - buf.readUnsignedByte(); // server flag (reserved) - position.set(Position.KEY_RESULT, - buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); - } + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + Network network = new Network(); + for (int i = 0; i < 7; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); + } - } else if (isSupported(type)) { + buf.readUnsignedByte(); // time leads - if (hasGps(type)) { - decodeGps(position, buf, false); - } else { - getLastLocation(position, null); - } + int wifiCount = buf.readUnsignedByte(); + for (int i = 0; i < wifiCount; i++) { + String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + } - if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); - } + position.setNetwork(network); - if (hasStatus(type)) { - decodeStatus(position, buf); - } + } else if (type == MSG_STRING) { - if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } + getLastLocation(position, null); - if (type == MSG_GPS_LBS_2 && buf.readableBytes() >= 3 + 6) { - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); - } + int commandLength = buf.readUnsignedByte(); + if (commandLength > 0) { + buf.readUnsignedByte(); // server flag (reserved) + position.set(Position.KEY_RESULT, + buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); + } + + } else if (isSupported(type)) { + + if (hasGps(type)) { + decodeGps(position, buf, false); } else { + getLastLocation(position, null); + } - buf.skipBytes(dataLength); - if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { - sendResponse(channel, false, type); - } - return null; + if (hasLbs(type)) { + decodeLbs(position, buf, hasStatus(type)); + } + if (hasStatus(type)) { + decodeStatus(position, buf); } - sendResponse(channel, false, type); + if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } - return position; + if (type == MSG_GPS_LBS_2 && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + + } else { + + buf.skipBytes(dataLength); + if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { + sendResponse(channel, false, type); + } + return null; } - return null; + sendResponse(channel, false, type); + + return position; } private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 2e6a53b06..3c767c908 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,12 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "7878412c11030b011c1f013604cb8a00b17754cb8a00bef357cb8a00b73f5fcb8900b0e25fcb8900b6655fcb8a00b74960cb8a00b178620701001801eb40393800bbbde10d0a")); + + verifyNotNull(decoder, binary( + "7878412c11030b012629013604cb8a00b17757cb8a00b73f5bcb8a00b7495ecb8900b0e25fcb8a00b1b9620000000000ff0000000000ffff01001801eb40393e00c0e6340d0a")); + verifyPosition(decoder, binary( "787822221106160a1016c60278019407c7783800040001940504700046fc01030100065f570d0a")); @@ -149,6 +155,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "787811010123456789012345100B3201000171930D0A")); + verifyNull(decoder, binary( + "78780d1f000000000000000200b196a20d0a")); + } } -- cgit v1.2.3 From abe8232585103b9e4856a4eabb0df122c17db052 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 19:32:35 +1200 Subject: Support GP6000 packed messages --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 141 +++++++++++---------- .../traccar/protocol/Jt600ProtocolDecoderTest.java | 20 ++- 2 files changed, 87 insertions(+), 74 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 2bd02d3f1..3b68cd82a 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2017 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,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -31,6 +32,8 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; import java.util.regex.Pattern; public class Jt600ProtocolDecoder extends BaseProtocolDecoder { @@ -45,10 +48,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes / 60; } - private Position decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { + private List decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { - Position position = new Position(); - position.setProtocol(getProtocolName()); + List positions = new LinkedList<>(); buf.readByte(); // header @@ -59,97 +61,102 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession == null) { return null; } - position.setDeviceId(deviceSession.getDeviceId()); if (longFormat) { buf.readUnsignedByte(); // protocol } - int version = buf.readUnsignedByte() >> 4; + int version = BitUtil.from(buf.readUnsignedByte(), 4); buf.readUnsignedShort(); // length - DateBuilder dateBuilder = new DateBuilder() - .setDay(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setYear(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); - double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - - byte flags = buf.readByte(); - position.setValid((flags & 0x1) == 0x1); - if ((flags & 0x2) == 0) { - latitude = -latitude; - } - position.setLatitude(latitude); - if ((flags & 0x4) == 0) { - longitude = -longitude; - } - position.setLongitude(longitude); + while (buf.readableBytes() > 1) { - position.setSpeed(BcdUtil.readInteger(buf, 2)); - position.setCourse(buf.readUnsignedByte() * 2.0); + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - if (longFormat) { + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)) + .setTime(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); + position.setTime(dateBuilder.getDate()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); + double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - buf.readUnsignedInt(); // vehicle id combined + byte flags = buf.readByte(); + position.setValid((flags & 0x1) == 0x1); + if ((flags & 0x2) == 0) { + latitude = -latitude; + } + position.setLatitude(latitude); + if ((flags & 0x4) == 0) { + longitude = -longitude; + } + position.setLongitude(longitude); - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + position.setSpeed(BcdUtil.readInteger(buf, 2)); + position.setCourse(buf.readUnsignedByte() * 2.0); - int battery = buf.readUnsignedByte(); - if (battery == 0xff) { - position.set(Position.KEY_CHARGE, true); - } else { - position.set(Position.KEY_BATTERY_LEVEL, battery); - } + if (longFormat) { + + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - position.setNetwork(new Network(cellTower)); + buf.readUnsignedInt(); // vehicle id combined - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + position.set(Position.KEY_STATUS, buf.readUnsignedShort()); - } else if (version == 1) { + int battery = buf.readUnsignedByte(); + if (battery == 0xff) { + position.set(Position.KEY_CHARGE, true); + } else { + position.set(Position.KEY_BATTERY_LEVEL, battery); + } - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedByte()); + CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); + cellTower.setSignalStrength((int) buf.readUnsignedByte()); + position.setNetwork(new Network(cellTower)); - buf.readByte(); // other flags and sensors + } else if (version == 1) { - position.setAltitude(buf.readUnsignedShort()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedByte()); - int cid = buf.readUnsignedShort(); - int lac = buf.readUnsignedShort(); - int rssi = buf.readUnsignedByte(); + buf.readByte(); // other flags and sensors - if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); - cellTower.setSignalStrength(rssi); - position.setNetwork(new Network(cellTower)); - } else { - position.set(Position.KEY_RSSI, rssi); - } + position.setAltitude(buf.readUnsignedShort()); + + int cid = buf.readUnsignedShort(); + int lac = buf.readUnsignedShort(); + int rssi = buf.readUnsignedByte(); + + if (cid != 0 && lac != 0) { + CellTower cellTower = CellTower.fromCidLac(cid, lac); + cellTower.setSignalStrength(rssi); + position.setNetwork(new Network(cellTower)); + } else { + position.set(Position.KEY_RSSI, rssi); + } - } else if (version == 2) { + } else if (version == 2) { - int fuel = buf.readUnsignedByte() << 8; + int fuel = buf.readUnsignedByte() << 8; - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - fuel += buf.readUnsignedByte(); - position.set(Position.KEY_FUEL_LEVEL, fuel); + fuel += buf.readUnsignedByte(); + position.set(Position.KEY_FUEL_LEVEL, fuel); + + } + + positions.add(position); } - return position; + buf.readUnsignedByte(); // index + + return positions; } private static final Pattern PATTERN_W01 = new PatternBuilder() diff --git a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 3b040297d..eb82d8c23 100644 --- a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -11,13 +11,19 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { Jt600ProtocolDecoder decoder = new Jt600ProtocolDecoder(new Jt600Protocol()); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( + "24624090196121001b19071703493631277203074235752f295800005308010000768b0822")); + + verifyPositions(decoder, binary( + "24624090196123019519071703412131285623074214252f10560000130801000076850819071703420631282832074215165f172c0000030801000076850919071703422131282792074216635f222e0000130801000076850919071703423631282808074218261f212a0000130801000076860819071703435131283678074222928f08350000930801000076860919071703440631283003074223174f19500000930801000076870819071703445131279872074224584f07380000930801000076870819071703453631280643074227091f1b220000530801000076880919071703455131281043074228216f0a260000530801000076880819071703460631281229074228988f0c260000530801000076880819071703462131281551074229954f1f220000530801000076880919071703463631281289074230503f114e0000530801000076880819071703465131281186074230884f094f0000530801000076880819071703470631280308074231240f17500000530801000076880619071703472131280358074231636f0b1d0000530801000076890821")); + + verifyPositions(decoder, binary( "2475604055531611002311111600311326144436028210791d016c0000001f070000000020c03c4f6d07d80ccf")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "2475201509260111002313101503464722331560113555309F00000000002D0500CB206800F064109326381A03")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "2475605035891613002328091601152806086750106533350c00000000000a000000000000e1ff4f97007f1607")); verifyPosition(decoder, buffer( @@ -50,17 +56,17 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, buffer( "(3460311327,U06,10,220916,140619,T,9.552495,N,13.658227,W,0.43,0,7,0%,00101001000000,11012,10,0,0,0,126,0,30)")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24311021600111001B16021105591022329862114046227B0598095080012327951435161F"), position("2011-02-16 05:59:10.000", true, 22.54977, -114.07705)); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24312082002911001B171012052831243810120255336425001907190003FD2B91044D1FA0")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24312082002911001B1710120533052438099702553358450004061E0003EE000000000C00")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24608111888821001B09060908045322564025113242329F0598000001003F0000002D00AB")); verifyPosition(decoder, buffer( -- cgit v1.2.3 From 027256c9524cace22f9718f3fa2d929e845de479 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 25 Jul 2017 01:12:18 +1200 Subject: Add Carscop unit test case --- test/org/traccar/protocol/CarscopProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/CarscopProtocolDecoderTest.java b/test/org/traccar/protocol/CarscopProtocolDecoderTest.java index da3ac510f..2d6ea208f 100644 --- a/test/org/traccar/protocol/CarscopProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CarscopProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class CarscopProtocolDecoderTest extends ProtocolTest { CarscopProtocolDecoder decoder = new CarscopProtocolDecoder(new CarscopProtocol()); + verifyNull(decoder, text( + "*170724163029UB05ORANGE000000010061825V0000.0000N00000.0000E000.0040331309.62")); + verifyNull(decoder, text( "*160618233129UB00HSO")); -- cgit v1.2.3 From c8e5c5e3da63646fd7c84d4f522bc8d7e5109982 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 25 Jul 2017 04:31:13 +1200 Subject: Implement missing XT2400 parameters --- src/org/traccar/protocol/Xt2400ProtocolDecoder.java | 15 +++++++++++++-- test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java | 5 +++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java index a42c6175f..15e8558be 100644 --- a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -25,6 +25,7 @@ import org.traccar.model.Position; import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -77,8 +78,6 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { for (int i : l4) { TAG_LENGTH_MAP.put(i, 4); } - TAG_LENGTH_MAP.put(0x65, 17); - TAG_LENGTH_MAP.put(0x73, 16); TAG_LENGTH_MAP.put(0x95, 24); } @@ -163,12 +162,24 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { case 0x13: position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0x14: + position.set(Position.KEY_RSSI, buf.readShort()); + break; case 0x16: position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); break; case 0x17: position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); break; + case 0x57: + position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + break; + case 0x65: + position.set(Position.KEY_VIN, buf.readBytes(17).toString(StandardCharsets.US_ASCII)); + break; + case 0x73: + position.set(Position.KEY_VERSION_FW, buf.readBytes(16).toString(StandardCharsets.US_ASCII).trim()); + break; default: buf.skipBytes(getTagLength(tag)); break; diff --git a/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java index 3cc0c22ec..35ca282b2 100644 --- a/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java @@ -10,6 +10,11 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest { Xt2400ProtocolDecoder decoder = new Xt2400ProtocolDecoder(new Xt2400Protocol()); + decoder.setConfig("\n:wycfg pcr[0] 001001030406070809570a13121714100565\n"); + + verifyPosition(decoder, binary( + "000a344f1f0259766ae002074289f8f1c4b200e80000026712068000130000029300883559464255524845364650323433343235")); + decoder.setConfig("\n:wycfg pcr[0] 000f01030406070809570a131217141005\n"); verifyPosition(decoder, binary( -- cgit v1.2.3 From d31f68d80a8e3ae75fa0c2f02b9ca258486a3cad Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 26 Jul 2017 17:52:27 +0500 Subject: - Implement base manager classes as generics - Remame getDeviceById and getDeviceByUniqueId functions --- src/org/traccar/BaseProtocolDecoder.java | 2 +- src/org/traccar/BaseProtocolEncoder.java | 4 +-- src/org/traccar/FilterHandler.java | 2 +- src/org/traccar/MainEventHandler.java | 2 +- src/org/traccar/WebDataHandler.java | 2 +- .../traccar/api/resource/AttributeResource.java | 2 +- src/org/traccar/api/resource/CalendarResource.java | 9 ++++-- src/org/traccar/api/resource/DeviceResource.java | 4 +-- src/org/traccar/api/resource/DriverResource.java | 2 +- src/org/traccar/api/resource/GeofenceResource.java | 2 +- src/org/traccar/api/resource/GroupResource.java | 2 +- src/org/traccar/api/resource/PositionResource.java | 2 +- src/org/traccar/api/resource/UserResource.java | 2 +- src/org/traccar/database/AttributesManager.java | 13 ++------- src/org/traccar/database/BaseObjectManager.java | 28 +++++++++--------- src/org/traccar/database/CalendarManager.java | 7 +---- src/org/traccar/database/ConnectionManager.java | 2 +- src/org/traccar/database/DeviceManager.java | 34 +++++++++------------- src/org/traccar/database/DriversManager.java | 25 ++++++---------- .../traccar/database/ExtendedObjectManager.java | 4 +-- src/org/traccar/database/GeofenceManager.java | 7 +---- src/org/traccar/database/GroupsManager.java | 19 +++++------- src/org/traccar/database/IdentityManager.java | 4 +-- src/org/traccar/database/PermissionsManager.java | 5 ++-- src/org/traccar/database/SimpleObjectManager.java | 5 ++-- src/org/traccar/database/UsersManager.java | 21 +++++-------- src/org/traccar/events/FuelDropEventHandler.java | 2 +- src/org/traccar/events/GeofenceEventHandler.java | 11 ++++--- src/org/traccar/events/IgnitionEventHandler.java | 2 +- .../traccar/events/MaintenanceEventHandler.java | 2 +- src/org/traccar/events/MotionEventHandler.java | 2 +- src/org/traccar/events/OverspeedEventHandler.java | 2 +- src/org/traccar/notification/EventForwarder.java | 2 +- .../notification/NotificationFormatter.java | 2 +- .../processing/ComputedAttributesHandler.java | 4 +-- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 4 +-- src/org/traccar/reports/Events.java | 2 +- src/org/traccar/reports/ReportUtils.java | 4 +-- src/org/traccar/reports/Route.java | 2 +- src/org/traccar/reports/Stops.java | 2 +- src/org/traccar/reports/Summary.java | 2 +- src/org/traccar/reports/Trips.java | 2 +- test/org/traccar/BaseTest.java | 4 +-- 44 files changed, 112 insertions(+), 152 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index b7ceabb5c..cc16000f4 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -75,7 +75,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { try { for (String uniqueId : uniqueIds) { if (uniqueId != null) { - Device device = Context.getIdentityManager().getDeviceByUniqueId(uniqueId); + Device device = Context.getIdentityManager().getByUniqueId(uniqueId); if (device != null) { deviceId = device.getId(); break; diff --git a/src/org/traccar/BaseProtocolEncoder.java b/src/org/traccar/BaseProtocolEncoder.java index 3c2d08471..2c8a81868 100644 --- a/src/org/traccar/BaseProtocolEncoder.java +++ b/src/org/traccar/BaseProtocolEncoder.java @@ -25,12 +25,12 @@ import org.traccar.model.Device; public abstract class BaseProtocolEncoder extends OneToOneEncoder { protected String getUniqueId(long deviceId) { - return Context.getIdentityManager().getDeviceById(deviceId).getUniqueId(); + return Context.getIdentityManager().getById(deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - Device device = Context.getIdentityManager().getDeviceById(command.getDeviceId()); + Device device = Context.getIdentityManager().getById(command.getDeviceId()); String password = device.getString(Command.KEY_DEVICE_PASSWORD); if (password != null) { command.set(Command.KEY_DEVICE_PASSWORD, password); diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 71c0a1cf5..1f5fffc86 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -184,7 +184,7 @@ public class FilterHandler extends BaseDataHandler { message.append("Position filtered by "); message.append(filterType.toString()); message.append("filters from device: "); - message.append(Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId()); + message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); message.append(" with id: "); message.append(position.getDeviceId()); diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index a005ee44b..8e88e15b9 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -55,7 +55,7 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { Log.warning(error); } - String uniqueId = Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId(); + String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); // Log position StringBuilder s = new StringBuilder(); diff --git a/src/org/traccar/WebDataHandler.java b/src/org/traccar/WebDataHandler.java index eaf0978ef..c64dcc81b 100644 --- a/src/org/traccar/WebDataHandler.java +++ b/src/org/traccar/WebDataHandler.java @@ -75,7 +75,7 @@ public class WebDataHandler extends BaseDataHandler { public String formatRequest(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); String request = url .replace("{name}", device.getName()) diff --git a/src/org/traccar/api/resource/AttributeResource.java b/src/org/traccar/api/resource/AttributeResource.java index 7b81d3ffb..c12fcd9e6 100644 --- a/src/org/traccar/api/resource/AttributeResource.java +++ b/src/org/traccar/api/resource/AttributeResource.java @@ -81,7 +81,7 @@ public class AttributeResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(attributesManager.getDeviceItems(deviceId)); } - return attributesManager.getItems(Attribute.class, result); + return attributesManager.getItems(result); } diff --git a/src/org/traccar/api/resource/CalendarResource.java b/src/org/traccar/api/resource/CalendarResource.java index a0f8656af..f8d78a847 100644 --- a/src/org/traccar/api/resource/CalendarResource.java +++ b/src/org/traccar/api/resource/CalendarResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import java.sql.SQLException; import java.util.Collection; +import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -47,20 +48,22 @@ public class CalendarResource extends BaseResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { CalendarManager calendarManager = Context.getCalendarManager(); + Set result = null; if (all) { if (Context.getPermissionsManager().isAdmin(getUserId())) { - return calendarManager.getItems(Calendar.class, calendarManager.getAllItems()); + result = calendarManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - return calendarManager.getItems(Calendar.class, calendarManager.getManagedItems(getUserId())); + result = calendarManager.getManagedItems(getUserId()); } } else { if (userId == 0) { userId = getUserId(); } Context.getPermissionsManager().checkUser(getUserId(), userId); - return calendarManager.getItems(Calendar.class, calendarManager.getUserItems(userId)); + result = calendarManager.getUserItems(userId); } + return calendarManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java index c621d4304..a473b7bde 100644 --- a/src/org/traccar/api/resource/DeviceResource.java +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -68,7 +68,7 @@ public class DeviceResource extends BaseResource { } else { result = new HashSet(); for (String uniqueId : uniqueIds) { - Device device = deviceManager.getDeviceByUniqueId(uniqueId); + Device device = deviceManager.getByUniqueId(uniqueId); Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); result.add(device.getId()); } @@ -77,7 +77,7 @@ public class DeviceResource extends BaseResource { result.add(deviceId); } } - return deviceManager.getItems(Device.class, result); + return deviceManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/DriverResource.java b/src/org/traccar/api/resource/DriverResource.java index 72eadb711..d44979998 100644 --- a/src/org/traccar/api/resource/DriverResource.java +++ b/src/org/traccar/api/resource/DriverResource.java @@ -79,7 +79,7 @@ public class DriverResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(driversManager.getDeviceItems(deviceId)); } - return driversManager.getItems(Driver.class, result); + return driversManager.getItems(result); } diff --git a/src/org/traccar/api/resource/GeofenceResource.java b/src/org/traccar/api/resource/GeofenceResource.java index 47f889e9c..9a110fbcf 100644 --- a/src/org/traccar/api/resource/GeofenceResource.java +++ b/src/org/traccar/api/resource/GeofenceResource.java @@ -78,7 +78,7 @@ public class GeofenceResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(geofenceManager.getDeviceItems(deviceId)); } - return geofenceManager.getItems(Geofence.class, result); + return geofenceManager.getItems(result); } diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java index f832660b2..4482f06c0 100644 --- a/src/org/traccar/api/resource/GroupResource.java +++ b/src/org/traccar/api/resource/GroupResource.java @@ -60,7 +60,7 @@ public class GroupResource extends BaseResource { Context.getPermissionsManager().checkUser(getUserId(), userId); result = groupsManager.getUserItems(userId); } - return groupsManager.getItems(Group.class, result); + return groupsManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index 9d3cd9ae6..6dab51744 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -87,7 +87,7 @@ public class PositionResource extends BaseResource { @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getDeviceById(deviceId).getName()); + GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getById(deviceId).getName()); gpx.addPositions(Context.getDataManager().getPositions( deviceId, DateUtil.parseDate(from), DateUtil.parseDate(to))); return Response.ok(gpx.build()).header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_GPX).build(); diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java index 9998ed346..deb2dd2b4 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -58,7 +58,7 @@ public class UserResource extends BaseResource { } else { throw new SecurityException("Admin or manager access required"); } - return usersManager.getItems(User.class, result); + return usersManager.getItems(result); } @PermitAll diff --git a/src/org/traccar/database/AttributesManager.java b/src/org/traccar/database/AttributesManager.java index e80d57c4e..28816645a 100644 --- a/src/org/traccar/database/AttributesManager.java +++ b/src/org/traccar/database/AttributesManager.java @@ -17,23 +17,16 @@ package org.traccar.database; import org.traccar.model.Attribute; -import org.traccar.model.BaseModel; -public class AttributesManager extends ExtendedObjectManager { +public class AttributesManager extends ExtendedObjectManager { public AttributesManager(DataManager dataManager) { super(dataManager, Attribute.class); } @Override - public Attribute getById(long calendarId) { - return (Attribute) super.getById(calendarId); - } - - @Override - public void updateCachedItem(BaseModel item) { - Attribute attribute = (Attribute) item; - Attribute cachedAttribute = getById(item.getId()); + public void updateCachedItem(Attribute attribute) { + Attribute cachedAttribute = getById(attribute.getId()); cachedAttribute.setDescription(attribute.getDescription()); cachedAttribute.setAttribute(attribute.getAttribute()); cachedAttribute.setExpression(attribute.getExpression()); diff --git a/src/org/traccar/database/BaseObjectManager.java b/src/org/traccar/database/BaseObjectManager.java index 92cfd9b6b..cc1dbde5f 100644 --- a/src/org/traccar/database/BaseObjectManager.java +++ b/src/org/traccar/database/BaseObjectManager.java @@ -27,14 +27,14 @@ import java.util.concurrent.ConcurrentHashMap; import org.traccar.helper.Log; import org.traccar.model.BaseModel; -public class BaseObjectManager { +public class BaseObjectManager { private final DataManager dataManager; - private Map items; - private Class baseClass; + private Map items; + private Class baseClass; - protected BaseObjectManager(DataManager dataManager, Class baseClass) { + protected BaseObjectManager(DataManager dataManager, Class baseClass) { this.dataManager = dataManager; this.baseClass = baseClass; refreshItems(); @@ -44,23 +44,23 @@ public class BaseObjectManager { return dataManager; } - protected final Class getBaseClass() { + protected final Class getBaseClass() { return baseClass; } - public BaseModel getById(long itemId) { + public T getById(long itemId) { return items.get(itemId); } public void refreshItems() { if (dataManager != null) { try { - Collection databaseItems = dataManager.getObjects(baseClass); + Collection databaseItems = dataManager.getObjects(baseClass); if (items == null) { items = new ConcurrentHashMap<>(databaseItems.size()); } Set databaseItemIds = new HashSet<>(); - for (BaseModel item : databaseItems) { + for (T item : databaseItems) { databaseItemIds.add(item.getId()); if (items.containsKey(item.getId())) { updateCachedItem(item); @@ -79,20 +79,20 @@ public class BaseObjectManager { } } - protected void addNewItem(BaseModel item) { + protected void addNewItem(T item) { items.put(item.getId(), item); } - public void addItem(BaseModel item) throws SQLException { + public void addItem(T item) throws SQLException { dataManager.addObject(item); addNewItem(item); } - protected void updateCachedItem(BaseModel item) { + protected void updateCachedItem(T item) { items.put(item.getId(), item); } - public void updateItem(BaseModel item) throws SQLException { + public void updateItem(T item) throws SQLException { dataManager.updateObject(item); updateCachedItem(item); } @@ -109,10 +109,10 @@ public class BaseObjectManager { } } - public final Collection getItems(Class clazz, Set itemIds) { + public final Collection getItems(Set itemIds) { Collection result = new LinkedList<>(); for (long itemId : itemIds) { - result.add((T) getById(itemId)); + result.add(getById(itemId)); } return result; } diff --git a/src/org/traccar/database/CalendarManager.java b/src/org/traccar/database/CalendarManager.java index b8d0914ee..44ced1082 100644 --- a/src/org/traccar/database/CalendarManager.java +++ b/src/org/traccar/database/CalendarManager.java @@ -18,15 +18,10 @@ package org.traccar.database; import org.traccar.model.Calendar; -public class CalendarManager extends SimpleObjectManager { +public class CalendarManager extends SimpleObjectManager { public CalendarManager(DataManager dataManager) { super(dataManager, Calendar.class); } - @Override - public Calendar getById(long calendarId) { - return (Calendar) super.getById(calendarId); - } - } diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 0baafb578..1445fb785 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -70,7 +70,7 @@ public class ConnectionManager { } public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return; } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 1fe7ddfa5..4aafe6631 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -30,7 +30,6 @@ import org.traccar.BaseProtocol; import org.traccar.Config; import org.traccar.Context; import org.traccar.helper.Log; -import org.traccar.model.BaseModel; import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; @@ -39,7 +38,7 @@ import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; -public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { +public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { public static final long DEFAULT_REFRESH_DELAY = 300; @@ -73,12 +72,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - public Device getDeviceById(long id) { - return (Device) getById(id); - } - - @Override - public Device getDeviceByUniqueId(String uniqueId) throws SQLException { + public Device getByUniqueId(String uniqueId) throws SQLException { boolean forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean("database.ignoreUnknown"); updateDeviceCache(forceUpdate); @@ -105,7 +99,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } public Collection getAllDevices() { - return getItems(Device.class, getAllItems()); + return getItems(getAllItems()); } @Override @@ -142,9 +136,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - Device device = (Device) item; + protected void addNewItem(Device device) { + super.addNewItem(device); putUniqueDeviceId(device); if (device.getPhone() != null && !device.getPhone().isEmpty()) { putPhone(device); @@ -158,9 +151,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - protected void updateCachedItem(BaseModel item) { - Device device = (Device) item; - Device cachedDevice = getDeviceById(device.getId()); + protected void updateCachedItem(Device device) { + Device cachedDevice = getById(device.getId()); cachedDevice.setName(device.getName()); cachedDevice.setGroupId(device.getGroupId()); cachedDevice.setCategory(device.getCategory()); @@ -182,7 +174,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, @Override protected void removeCachedItem(long deviceId) { - Device cachedDevice = getDeviceById(deviceId); + Device cachedDevice = getById(deviceId); if (cachedDevice != null) { String deviceUniqueId = cachedDevice.getUniqueId(); String phone = cachedDevice.getPhone(); @@ -197,7 +189,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, public void updateDeviceStatus(Device device) throws SQLException { getDataManager().updateDeviceStatus(device); - Device cachedDevice = getDeviceById(device.getId()); + Device cachedDevice = getById(device.getId()); if (cachedDevice != null) { cachedDevice.setStatus(device.getStatus()); } @@ -226,7 +218,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, getDataManager().updateLatestPosition(position); - Device device = getDeviceById(position.getDeviceId()); + Device device = getById(position.getDeviceId()); if (device != null) { device.setPositionId(position.getId()); } @@ -305,7 +297,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, private String lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { String result = null; - Device device = getDeviceById(deviceId); + Device device = getById(deviceId); if (device != null) { result = device.getString(attributeName); if (result == null && lookupGroupsAttribute) { @@ -352,9 +344,9 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, Position lastPosition = getLastPosition(deviceId); if (lastPosition != null) { BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(getDeviceById(deviceId).getPhone(), command); + protocol.sendTextCommand(getById(deviceId).getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmppManager().sendMessageSync(((Device) getById(deviceId)).getPhone(), + Context.getSmppManager().sendMessageSync(getById(deviceId).getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java index 420824dbb..d3866a5f0 100644 --- a/src/org/traccar/database/DriversManager.java +++ b/src/org/traccar/database/DriversManager.java @@ -20,37 +20,30 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.traccar.model.Driver; -import org.traccar.model.BaseModel; -public class DriversManager extends ExtendedObjectManager { +public class DriversManager extends ExtendedObjectManager { - private Map driversByUniqueId; + private Map driversByUniqueId; public DriversManager(DataManager dataManager) { super(dataManager, Driver.class); } - @Override - public Driver getById(long driverId) { - return (Driver) super.getById(driverId); - } - private void putUniqueDriverId(Driver driver) { if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); + driversByUniqueId = new ConcurrentHashMap<>(getAllItems().size()); } - driversByUniqueId.put(driver.getUniqueId(), driver); + driversByUniqueId.put(driver.getUniqueId(), driver.getId()); } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - putUniqueDriverId((Driver) item); + protected void addNewItem(Driver driver) { + super.addNewItem(driver); + putUniqueDriverId(driver); } @Override - protected void updateCachedItem(BaseModel item) { - Driver driver = (Driver) item; + protected void updateCachedItem(Driver driver) { Driver cachedDriver = getById(driver.getId()); cachedDriver.setName(driver.getName()); if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { @@ -72,6 +65,6 @@ public class DriversManager extends ExtendedObjectManager { } public Driver getDriverByUniqueId(String uniqueId) { - return driversByUniqueId.get(uniqueId); + return getById(driversByUniqueId.get(uniqueId)); } } diff --git a/src/org/traccar/database/ExtendedObjectManager.java b/src/org/traccar/database/ExtendedObjectManager.java index 19c9ca5b2..16785cb37 100644 --- a/src/org/traccar/database/ExtendedObjectManager.java +++ b/src/org/traccar/database/ExtendedObjectManager.java @@ -30,13 +30,13 @@ import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.BaseModel; -public abstract class ExtendedObjectManager extends SimpleObjectManager { +public abstract class ExtendedObjectManager extends SimpleObjectManager { private final Map> deviceItems = new ConcurrentHashMap<>(); private final Map> deviceItemsWithGroups = new ConcurrentHashMap<>(); private final Map> groupItems = new ConcurrentHashMap<>(); - protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { + protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); refreshExtendedPermissions(); } diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java index 4bc3909cd..a32847cf9 100644 --- a/src/org/traccar/database/GeofenceManager.java +++ b/src/org/traccar/database/GeofenceManager.java @@ -23,17 +23,12 @@ import org.traccar.model.Device; import org.traccar.model.Geofence; import org.traccar.model.Position; -public class GeofenceManager extends ExtendedObjectManager { +public class GeofenceManager extends ExtendedObjectManager { public GeofenceManager(DataManager dataManager) { super(dataManager, Geofence.class); } - @Override - public Geofence getById(long geofenceId) { - return (Geofence) super.getById(geofenceId); - } - @Override public final void refreshExtendedPermissions() { super.refreshExtendedPermissions(); diff --git a/src/org/traccar/database/GroupsManager.java b/src/org/traccar/database/GroupsManager.java index 095e7a22c..20b403d55 100644 --- a/src/org/traccar/database/GroupsManager.java +++ b/src/org/traccar/database/GroupsManager.java @@ -26,7 +26,7 @@ import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Group; -public class GroupsManager extends BaseObjectManager implements ManagableObjects { +public class GroupsManager extends BaseObjectManager implements ManagableObjects { private AtomicLong groupsLastUpdate = new AtomicLong(); private final long dataRefreshDelay; @@ -37,11 +37,6 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects DeviceManager.DEFAULT_REFRESH_DELAY) * 1000; } - @Override - public Group getById(long groupId) { - return (Group) super.getById(groupId); - } - private void checkGroupCycles(BaseModel group) { Set groups = new HashSet<>(); while (group != null) { @@ -76,15 +71,15 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects } @Override - protected void addNewItem(BaseModel item) { - checkGroupCycles(item); - super.addNewItem(item); + protected void addNewItem(Group group) { + checkGroupCycles(group); + super.addNewItem(group); } @Override - protected void updateCachedItem(BaseModel item) { - checkGroupCycles(item); - super.updateCachedItem(item); + protected void updateCachedItem(Group group) { + checkGroupCycles(group); + super.updateCachedItem(group); } @Override diff --git a/src/org/traccar/database/IdentityManager.java b/src/org/traccar/database/IdentityManager.java index c8c593a54..82d905963 100644 --- a/src/org/traccar/database/IdentityManager.java +++ b/src/org/traccar/database/IdentityManager.java @@ -20,9 +20,9 @@ import org.traccar.model.Position; public interface IdentityManager { - Device getDeviceById(long id); + Device getById(long id); - Device getDeviceByUniqueId(String uniqueId) throws Exception; + Device getByUniqueId(String uniqueId) throws Exception; Position getLastPosition(long deviceId); diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 54e5ed979..3b03c1900 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -18,6 +18,7 @@ package org.traccar.database; import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Attribute; +import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; @@ -99,7 +100,7 @@ public class PermissionsManager { devicePermissions.clear(); try { GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Group.class, Context.getGroupsManager().getAllItems()), + Context.getGroupsManager().getAllItems()), Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); @@ -284,7 +285,7 @@ public class PermissionsManager { public void checkPermission(Class object, long userId, long objectId) throws SecurityException { - SimpleObjectManager manager = null; + SimpleObjectManager manager = null; if (object.equals(Device.class)) { checkDevice(userId, objectId); diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java index fa41f30b6..0b4d11378 100644 --- a/src/org/traccar/database/SimpleObjectManager.java +++ b/src/org/traccar/database/SimpleObjectManager.java @@ -28,11 +28,12 @@ import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.model.User; -public abstract class SimpleObjectManager extends BaseObjectManager implements ManagableObjects { +public abstract class SimpleObjectManager extends BaseObjectManager + implements ManagableObjects { private Map> userItems; - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { + protected SimpleObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); } diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java index e53409b4f..28e6a31b2 100644 --- a/src/org/traccar/database/UsersManager.java +++ b/src/org/traccar/database/UsersManager.java @@ -21,10 +21,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.traccar.model.BaseModel; import org.traccar.model.User; -public class UsersManager extends SimpleObjectManager { +public class UsersManager extends SimpleObjectManager { private Map usersTokens; @@ -32,11 +31,6 @@ public class UsersManager extends SimpleObjectManager { super(dataManager, User.class); } - @Override - public User getById(long userId) { - return (User) super.getById(userId); - } - private void putToken(User user) { if (usersTokens == null) { usersTokens = new ConcurrentHashMap<>(); @@ -47,16 +41,15 @@ public class UsersManager extends SimpleObjectManager { } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - putToken((User) item); + protected void addNewItem(User user) { + super.addNewItem(user); + putToken(user); } @Override - protected void updateCachedItem(BaseModel item) { - User user = (User) item; - User cachedUser = getById(item.getId()); - super.updateCachedItem(item); + protected void updateCachedItem(User user) { + User cachedUser = getById(user.getId()); + super.updateCachedItem(user); if (user.getToken() != null) { usersTokens.put(user.getToken(), user.getId()); } diff --git a/src/org/traccar/events/FuelDropEventHandler.java b/src/org/traccar/events/FuelDropEventHandler.java index e9a261aea..4e09bd4fa 100644 --- a/src/org/traccar/events/FuelDropEventHandler.java +++ b/src/org/traccar/events/FuelDropEventHandler.java @@ -31,7 +31,7 @@ public class FuelDropEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java index 516df9d69..79e5d0f8e 100644 --- a/src/org/traccar/events/GeofenceEventHandler.java +++ b/src/org/traccar/events/GeofenceEventHandler.java @@ -25,7 +25,6 @@ import org.traccar.database.GeofenceManager; 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; public class GeofenceEventHandler extends BaseEventHandler { @@ -38,7 +37,7 @@ public class GeofenceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } @@ -59,8 +58,8 @@ public class GeofenceEventHandler extends BaseEventHandler { Collection events = new ArrayList<>(); for (long geofenceId : newGeofences) { - long calendarId = ((Geofence) geofenceManager.getById(geofenceId)).getCalendarId(); - Calendar calendar = calendarId != 0 ? (Calendar) Context.getCalendarManager().getById(calendarId) : null; + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? Context.getCalendarManager().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); @@ -68,8 +67,8 @@ public class GeofenceEventHandler extends BaseEventHandler { } } for (long geofenceId : oldGeofences) { - long calendarId = ((Geofence) geofenceManager.getById(geofenceId)).getCalendarId(); - Calendar calendar = calendarId != 0 ? (Calendar) Context.getCalendarManager().getById(calendarId) : null; + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? Context.getCalendarManager().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); diff --git a/src/org/traccar/events/IgnitionEventHandler.java b/src/org/traccar/events/IgnitionEventHandler.java index c628cc107..5519135bf 100644 --- a/src/org/traccar/events/IgnitionEventHandler.java +++ b/src/org/traccar/events/IgnitionEventHandler.java @@ -29,7 +29,7 @@ public class IgnitionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MaintenanceEventHandler.java b/src/org/traccar/events/MaintenanceEventHandler.java index 86836f6af..ffeefc8c5 100644 --- a/src/org/traccar/events/MaintenanceEventHandler.java +++ b/src/org/traccar/events/MaintenanceEventHandler.java @@ -32,7 +32,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index e6fd10f3e..ed81176a8 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -29,7 +29,7 @@ public class MotionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 00c3845d2..795892f40 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -37,7 +37,7 @@ public class OverspeedEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java index 08f55df75..ac37f980c 100644 --- a/src/org/traccar/notification/EventForwarder.java +++ b/src/org/traccar/notification/EventForwarder.java @@ -69,7 +69,7 @@ public final class EventForwarder { data.put(KEY_POSITION, position); } if (event.getDeviceId() != 0) { - Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId()); + Device device = Context.getIdentityManager().getById(event.getDeviceId()); if (device != null) { data.put(KEY_DEVICE, device); } diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java index cd9959671..33fd2cdc7 100644 --- a/src/org/traccar/notification/NotificationFormatter.java +++ b/src/org/traccar/notification/NotificationFormatter.java @@ -40,7 +40,7 @@ public final class NotificationFormatter { public static VelocityContext prepareContext(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId()); + Device device = Context.getIdentityManager().getById(event.getDeviceId()); VelocityContext velocityContext = new VelocityContext(); velocityContext.put("user", user); diff --git a/src/org/traccar/processing/ComputedAttributesHandler.java b/src/org/traccar/processing/ComputedAttributesHandler.java index d6a762535..f1f371475 100644 --- a/src/org/traccar/processing/ComputedAttributesHandler.java +++ b/src/org/traccar/processing/ComputedAttributesHandler.java @@ -51,7 +51,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private MapContext prepareContext(Position position) { MapContext result = new MapContext(); if (mapDeviceAttributes) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device != null) { for (Object key : device.getAttributes().keySet()) { result.set((String) key, device.getAttributes().get(key)); @@ -86,7 +86,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Collection attributes = Context.getAttributesManager().getItems(Attribute.class, + Collection attributes = Context.getAttributesManager().getItems( Context.getAttributesManager().getAllDeviceItems(position.getDeviceId())); for (Attribute attribute : attributes) { if (attribute.getAttribute() != null) { diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 36358b6e5..186867b9d 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -555,7 +555,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = Context.getDeviceManager().getDeviceById(deviceSession.getDeviceId()); + Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg"); photos.remove(pictureId); } diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 711697fc4..469ef3f76 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -160,7 +160,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } } - String deviceModel = Context.getIdentityManager().getDeviceById(deviceSession.getDeviceId()).getModel(); + String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } @@ -316,7 +316,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case "D03": if (channel != null) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String imei = Context.getIdentityManager().getDeviceById(deviceSession.getDeviceId()).getUniqueId(); + String imei = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); channel.write("@@O46," + imei + ",D00,camera_picture.jpg,0*00\r\n"); } return null; diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 348e6077f..63077de32 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -88,7 +88,7 @@ public final class Events { } } DeviceReport deviceEvents = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index bc58d28df..cf94030ab 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -176,7 +176,7 @@ public final class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + trip.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -210,7 +210,7 @@ public final class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + stop.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index 69be55155..1c53a15cc 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -57,7 +57,7 @@ public final class Route { Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); DeviceReport deviceRoutes = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 20a6c1ce3..886fd7915 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -74,7 +74,7 @@ public final class Stops { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReport deviceStops = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java index 5aaf33fae..dd9877cd7 100644 --- a/src/org/traccar/reports/Summary.java +++ b/src/org/traccar/reports/Summary.java @@ -38,7 +38,7 @@ public final class Summary { private static SummaryReport calculateSummaryResult(long deviceId, Date from, Date to) throws SQLException { SummaryReport result = new SummaryReport(); result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); Collection positions = Context.getDataManager().getPositions(deviceId, from, to); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 7b5df0248..68b03a819 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -73,7 +73,7 @@ public final class Trips { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReport deviceTrips = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/test/org/traccar/BaseTest.java b/test/org/traccar/BaseTest.java index 6af8610cd..37956f11d 100644 --- a/test/org/traccar/BaseTest.java +++ b/test/org/traccar/BaseTest.java @@ -18,12 +18,12 @@ public class BaseTest { } @Override - public Device getDeviceById(long id) { + public Device getById(long id) { return createDevice(); } @Override - public Device getDeviceByUniqueId(String uniqueId) { + public Device getByUniqueId(String uniqueId) { return createDevice(); } -- cgit v1.2.3 From 194263a9dc8040ebcbf62c80733aca5097eb3e36 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Jul 2017 01:32:21 +1200 Subject: Extend VT200 protocol decoder --- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- test/org/traccar/protocol/Vt200ProtocolDecoderTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index b9af11b43..f9683f12f 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -57,7 +57,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedShort(); buf.readUnsignedShort(); // length - if (type == 0x2084) { + if (type == 0x2084 || type == 0x2082) { Position position = new Position(); position.setProtocol(getProtocolName()); diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index e61c5f9f2..d63bf0062 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -10,6 +10,21 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { Vt200ProtocolDecoder decoder = new Vt200ProtocolDecoder(new Vt200Protocol()); + verifyNull(decoder, binary( + "28631037309456008e000801042307171804584229")); + + verifyNull(decoder, binary( + "28631037309456108800002e29")); + + verifyPosition(decoder, binary( + "28631037309456208200210103302307171805444417097301147188170198090f0000073a002000007e00074429")); + + verifyNull(decoder, binary( + "286310373094563089001200032f2107171740144417075001147188872c29")); + + verifyNull(decoder, binary( + "2863103730945630880062032f862631037309456f222014604362936f21071717373221071717401400a100000cd700000004020d3c8e0000000000000000000000000000000000000000000000000000000000000000000a000000040000000e009700000cc9000000000000e929")); + verifyPosition(decoder, binary( "28631037309456208400340102dc0906171616454415760201144494473f920a0c0000030500200100417c1f383a9d1090510000006a00007000000e00180ee129")); -- cgit v1.2.3 From 233f54da4216cd1b3bf4bdc864e23e3fedc98ff1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 29 Jul 2017 10:13:10 +1200 Subject: Add H02 test case --- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index bd4de3363..48f4d987e 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyPosition(decoder, binary( + "2442091341332059572807175137358006000183640e000000fffffbfdff001f080000000000ea1e0000000021")); + verifyNull(decoder, buffer( "*HQ,4109198974,#")); -- cgit v1.2.3 From b65dd20c5e8c7fc9b26cb27154394d2afdbd5316 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 29 Jul 2017 10:17:58 +1200 Subject: Add IDD-213L Sinocastel test --- test/org/traccar/protocol/CastelProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/CastelProtocolDecoderTest.java b/test/org/traccar/protocol/CastelProtocolDecoderTest.java index 6b52373e1..bdf69e1af 100644 --- a/test/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class CastelProtocolDecoderTest extends ProtocolTest { CastelProtocolDecoder decoder = new CastelProtocolDecoder(new CastelProtocol()); + verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "40408200033231334c32303137303031313039000000000000100136477b5964477b590400000000000000dc410f000000000204000709207910008304011c07110e110dd41a160714a95a0f00001e058c4944442d3231334c2056312e312e3120323031372d30352d3038004944442d3231334c2056312e312e300000006da10d0a")); + verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN, "40408200033231334c323031373030303131370000000000001001000c6759a10d67590a9e1200000000000e3e0000000000020000000e4e791c000004010d0711060515083017086cd1181f000040067d4944442d3231334c2056312e312e3120323031372d30352d3038004944442d3231334c2056312e312e3000000066e30d0a")); -- cgit v1.2.3 From ae76cbf971bfc9e47ef21e87606dacc7c0e3ddc6 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 31 Jul 2017 14:08:36 +0500 Subject: Implement SQL requests construction --- schema/changelog-3.14.xml | 4 +- setup/default.xml | 406 +-------------------- src/org/traccar/Config.java | 4 + src/org/traccar/api/resource/EventResource.java | 2 +- src/org/traccar/api/resource/PositionResource.java | 2 +- src/org/traccar/database/DataManager.java | 210 ++++++++--- src/org/traccar/database/QueryAdditional.java | 27 ++ src/org/traccar/database/StatisticsManager.java | 2 +- src/org/traccar/model/Device.java | 7 + src/org/traccar/model/Position.java | 9 + src/org/traccar/model/Server.java | 2 + src/org/traccar/model/User.java | 6 + test/org/traccar/database/DataManagerTest.java | 79 ++++ 13 files changed, 299 insertions(+), 461 deletions(-) create mode 100644 src/org/traccar/database/QueryAdditional.java create mode 100644 test/org/traccar/database/DataManagerTest.java (limited to 'test/org') diff --git a/schema/changelog-3.14.xml b/schema/changelog-3.14.xml index 7965bc020..f6cda4c1f 100644 --- a/schema/changelog-3.14.xml +++ b/schema/changelog-3.14.xml @@ -61,5 +61,7 @@ + + - \ No newline at end of file + diff --git a/setup/default.xml b/setup/default.xml index f0f9ef4a3..ea8c32fbd 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -29,163 +29,16 @@ true ./schema/changelog-master.xml - - - SELECT * FROM server - - - - UPDATE server SET - registration = :registration, - readonly = :readonly, - deviceReadonly = :deviceReadonly, - map = :map, - bingKey = :bingKey, - mapUrl = :mapUrl, - distanceUnit = :distanceUnit, - speedUnit = :speedUnit, - latitude = :latitude, - longitude = :longitude, - zoom = :zoom, - twelveHourFormat = :twelveHourFormat, - coordinateFormat = :coordinateFormat, - forceSettings = :forceSettings, - timezone = :timezone, - attributes = :attributes - WHERE id = :id - - + SELECT * FROM users WHERE email = :email - - SELECT * FROM users - - - - INSERT INTO users (name, email, phone, hashedPassword, salt, readonly, admin, map, distanceUnit, speedUnit, latitude, longitude, zoom, twelveHourFormat, coordinateFormat, disabled, expirationTime, deviceLimit, userLimit, deviceReadonly, token, timezone, attributes) - VALUES (:name, :email, :phone, :hashedPassword, :salt, :readonly, :admin, :map, :distanceUnit, :speedUnit, :latitude, :longitude, :zoom, :twelveHourFormat, :coordinateFormat, :disabled, :expirationTime, :deviceLimit, :userLimit, :deviceReadonly, :token, :timezone, :attributes) - - - - UPDATE users SET - name = :name, - email = :email, - phone = :phone, - readonly = :readonly, - admin = :admin, - map = :map, - distanceUnit = :distanceUnit, - speedUnit = :speedUnit, - latitude = :latitude, - longitude = :longitude, - zoom = :zoom, - twelveHourFormat = :twelveHourFormat, - coordinateFormat = :coordinateFormat, - disabled = :disabled, - expirationTime = :expirationTime, - deviceLimit = :deviceLimit, - userLimit = :userLimit, - deviceReadonly = :deviceReadonly, - token = :token, - timezone = :timezone, - attributes = :attributes - WHERE id = :id - - - - UPDATE users SET hashedPassword = :hashedPassword, salt = :salt WHERE id = :id - - - - DELETE FROM users WHERE id = :id - - - - SELECT userId, deviceId FROM user_device - - - - SELECT userId, groupId FROM user_group - - - - SELECT * FROM devices - - - - INSERT INTO devices (name, uniqueId, groupId, attributes, phone, model, contact, category) - VALUES (:name, :uniqueId, :groupId, :attributes, :phone, :model, :contact, :category) - - - - UPDATE devices SET - name = :name, - uniqueId = :uniqueId, - groupId = :groupId, - attributes = :attributes, - phone = :phone, - model = :model, - contact = :contact, - category = :category - WHERE id = :id - - - - UPDATE devices SET lastUpdate = :lastUpdate WHERE id = :id - - - - DELETE FROM devices WHERE id = :id - - - - INSERT INTO user_device (userId, deviceId) VALUES (:userId, :deviceId) - - - - DELETE FROM user_device WHERE userId = :userId AND deviceId = :deviceId - - - - SELECT * FROM groups - - - - INSERT INTO groups (name, groupId, attributes) VALUES (:name, :groupId, :attributes) - - - - UPDATE groups SET name = :name, groupId = :groupId, attributes = :attributes WHERE id = :id - - - - DELETE FROM groups WHERE id = :id - - - - INSERT INTO user_group (userId, groupId) VALUES (:userId, :groupId) - - - - DELETE FROM user_group WHERE userId = :userId AND groupId = :groupId - - SELECT * FROM positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime - - SELECT * FROM positions WHERE id = :id - - - - INSERT INTO positions (deviceId, protocol, serverTime, deviceTime, fixTime, valid, latitude, longitude, altitude, speed, course, address, attributes, accuracy, network) - VALUES (:deviceId, :protocol, :now, :deviceTime, :fixTime, :valid, :latitude, :longitude, :altitude, :speed, :course, :address, :attributes, :accuracy, :network) - - SELECT positions.* FROM positions INNER JOIN devices ON positions.id = devices.positionid; @@ -194,102 +47,10 @@ UPDATE devices SET positionId = :id WHERE id = :deviceId - - SELECT * FROM events WHERE id = :id - - - - INSERT INTO events (type, serverTime, deviceId, positionId, geofenceId, attributes) - VALUES (:type, :serverTime, :deviceId, :positionId, :geofenceId, :attributes) - - SELECT * FROM events WHERE deviceId = :deviceId AND serverTime BETWEEN :from AND :to ORDER BY serverTime - - SELECT * FROM geofences - - - - INSERT INTO geofences (name, description, calendarid, area, attributes) - VALUES (:name, :description, :calendarid, :area, :attributes) - - - - UPDATE geofences SET - name = :name, - description = :description, - calendarid = :calendarid, - area = :area, - attributes = :attributes - WHERE id = :id - - - - DELETE FROM geofences WHERE id = :id - - - - SELECT userId, geofenceId FROM user_geofence - - - - INSERT INTO user_geofence (userId, geofenceId) VALUES (:userId, :geofenceId) - - - - DELETE FROM user_geofence WHERE userId = :userId AND geofenceId = :geofenceId - - - - SELECT groupId, geofenceId FROM group_geofence - - - - INSERT INTO group_geofence (groupId, geofenceId) VALUES (:groupId, :geofenceId) - - - - DELETE FROM group_geofence WHERE groupId = :groupId AND geofenceId = :geofenceId - - - - SELECT deviceId, geofenceId FROM device_geofence - - - - INSERT INTO device_geofence (deviceId, geofenceId) VALUES (:deviceId, :geofenceId) - - - - DELETE FROM device_geofence WHERE deviceId = :deviceId AND geofenceId = :geofenceId - - - - SELECT * FROM notifications - - - - INSERT INTO notifications (userId, type, web, mail, sms, attributes) - VALUES (:userId, :type, :web, :mail, :sms, :attributes) - - - - UPDATE notifications SET - userId = :userId, - type = :type, - web = :web, - mail = :mail, - sms = :sms, - attributes = :attributes - WHERE id = :id - - - - DELETE FROM notifications WHERE id = :id - - DELETE FROM positions WHERE serverTime < :serverTime AND id NOT IN (SELECT positionId FROM devices) @@ -323,171 +84,6 @@ SELECT * FROM statistics WHERE captureTime BETWEEN :from AND :to ORDER BY captureTime - - INSERT INTO statistics (captureTime, activeUsers, activeDevices, requests, messagesReceived, messagesStored, mailSent, smsSent, geocoderRequests, geolocationRequests, attributes) - VALUES (:captureTime, :activeUsers, :activeDevices, :requests, :messagesReceived, :messagesStored, :mailSent, :smsSent, :geocoderRequests, :geolocationRequests, :attributes) - - - - SELECT * FROM calendars - - - - INSERT INTO calendars (name, data, attributes) - VALUES (:name, :data, :attributes) - - - - UPDATE calendars SET - name = :name, - data = :data, - attributes = :attributes - WHERE id = :id - - - - DELETE FROM calendars WHERE id = :id - - - - SELECT userId, calendarId FROM user_calendar - - - - INSERT INTO user_calendar (userId, calendarId) VALUES (:userId, :calendarId) - - - - DELETE FROM user_calendar WHERE userId = :userId AND calendarId = :calendarId - - - - SELECT userId, managedUserId FROM user_user - - - - INSERT INTO user_user (userId, managedUserId) VALUES (:userId, :managedUserId) - - - - DELETE FROM user_user WHERE userId = :userId AND managedUserId = :managedUserId - - - - SELECT * FROM attributes - - - - INSERT INTO attributes (description, type, attribute, expression) - VALUES (:description, :type, :attribute, :expression) - - - - UPDATE attributes SET - description = :description, - type = :type, - attribute = :attribute, - expression = :expression - WHERE id = :id - - - - DELETE FROM attributes WHERE id = :id - - - - SELECT userId, attributeId FROM user_attribute - - - - INSERT INTO user_attribute (userId, attributeId) VALUES (:userId, :attributeId) - - - - DELETE FROM user_attribute WHERE userId = :userId AND attributeId = :attributeId - - - - SELECT groupId, attributeId FROM group_attribute - - - - INSERT INTO group_attribute (groupId, attributeId) VALUES (:groupId, :attributeId) - - - - DELETE FROM group_attribute WHERE groupId = :groupId AND attributeId = :attributeId - - - - SELECT deviceId, attributeId FROM device_attribute - - - - INSERT INTO device_attribute (deviceId, attributeId) VALUES (:deviceId, :attributeId) - - - - DELETE FROM device_attribute WHERE deviceId = :deviceId AND attributeId = :attributeId - - - - SELECT * FROM drivers - - - - INSERT INTO drivers (name, uniqueId, attributes) - VALUES (:name, :uniqueId, :attributes) - - - - UPDATE drivers SET - name = :name, - uniqueId = :uniqueId, - attributes = :attributes - WHERE id = :id - - - - DELETE FROM drivers WHERE id = :id - - - - SELECT userId, driverId FROM user_driver - - - - INSERT INTO user_driver (userId, driverId) VALUES (:userId, :driverId) - - - - DELETE FROM user_driver WHERE userId = :userId AND driverId = :driverId - - - - SELECT groupId, driverId FROM group_driver - - - - INSERT INTO group_driver (groupId, driverId) VALUES (:groupId, :driverId) - - - - DELETE FROM group_driver WHERE groupId = :groupId AND driverId = :driverId - - - - SELECT deviceId, driverId FROM device_driver - - - - INSERT INTO device_driver (deviceId, driverId) VALUES (:deviceId, :driverId) - - - - DELETE FROM device_driver WHERE deviceId = :deviceId AND driverId = :driverId - - 5001 diff --git a/src/org/traccar/Config.java b/src/org/traccar/Config.java index 0bc3cafaa..a0f3f8c2e 100644 --- a/src/org/traccar/Config.java +++ b/src/org/traccar/Config.java @@ -96,4 +96,8 @@ public class Config { return key.replaceAll("\\.", "_").replaceAll("(\\p{Lu})", "_$1").toUpperCase(); } + public void setString(String key, String value) { + properties.putIfAbsent(key, value); + } + } diff --git a/src/org/traccar/api/resource/EventResource.java b/src/org/traccar/api/resource/EventResource.java index b7fda6f73..a7cf9edbd 100644 --- a/src/org/traccar/api/resource/EventResource.java +++ b/src/org/traccar/api/resource/EventResource.java @@ -23,7 +23,7 @@ public class EventResource extends BaseResource { @Path("{id}") @GET public Event get(@PathParam("id") long id) throws SQLException { - Event event = Context.getDataManager().getEvent(id); + Event event = Context.getDataManager().getObject(Event.class, id); Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId()); if (event.getGeofenceId() != 0) { Context.getPermissionsManager().checkPermission(Geofence.class, getUserId(), event.getGeofenceId()); diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index 6dab51744..c031b842f 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -54,7 +54,7 @@ public class PositionResource extends BaseResource { if (!positionIds.isEmpty()) { ArrayList positions = new ArrayList<>(); for (Long positionId : positionIds) { - Position position = Context.getDataManager().getPosition(positionId); + Position position = Context.getDataManager().getObject(Position.class, positionId); Context.getPermissionsManager().checkDevice(getUserId(), position.getDeviceId()); positions.add(position); } diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 07ad0be44..a753c311b 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -21,8 +21,11 @@ import java.net.URL; import java.net.URLClassLoader; import java.sql.SQLException; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.HashSet; +import java.util.Set; import javax.naming.InitialContext; import javax.sql.DataSource; @@ -58,6 +61,12 @@ import com.zaxxer.hikari.HikariDataSource; public class DataManager { + public static final String ACTION_SELECT_ALL = "selectAll"; + public static final String ACTION_SELECT = "select"; + public static final String ACTION_INSERT = "insert"; + public static final String ACTION_UPDATE = "update"; + public static final String ACTION_DELETE = "delete"; + private final Config config; private DataSource dataSource; @@ -115,6 +124,73 @@ public class DataManager { } } + public static String constructObjectQuery(String action, Class clazz, boolean additional) { + switch (action) { + case ACTION_INSERT: + case ACTION_UPDATE: + StringBuilder result = new StringBuilder(); + StringBuilder fields = new StringBuilder(); + StringBuilder values = new StringBuilder(); + + Set methods = new HashSet<>(Arrays.asList(clazz.getMethods())); + methods.removeAll(Arrays.asList(Object.class.getMethods())); + methods.removeAll(Arrays.asList(BaseModel.class.getMethods())); + for (Method method : methods) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 + && (additional ? method.isAnnotationPresent(QueryAdditional.class) + : !method.isAnnotationPresent(QueryIgnore.class) + && !method.isAnnotationPresent(QueryAdditional.class))) { + String name = method.getName().substring(3, 4).toLowerCase() + + method.getName().substring(4); + if (action.equals(ACTION_INSERT)) { + fields.append(name).append(", "); + values.append(":").append(name).append(", "); + } else { + fields.append(name).append(" = :").append(name).append(",\n"); + } + } + } + fields.setLength(fields.length() - 2); + if (action.equals(ACTION_INSERT)) { + values.setLength(values.length() - 2); + result.append("INSERT INTO ").append(getObjectsTableName(clazz)).append(" ("); + result.append(fields).append(")\n"); + result.append("VALUES (").append(values).append(")"); + } else { + result.append("UPDATE ").append(getObjectsTableName(clazz)).append(" SET\n"); + result.append(fields); + result.append("\nWHERE id = :id"); + } + return result.toString(); + case ACTION_SELECT_ALL: + return "SELECT * FROM " + getObjectsTableName(clazz); + case ACTION_SELECT: + return "SELECT * FROM " + getObjectsTableName(clazz) + " WHERE id = :id"; + case ACTION_DELETE: + return "DELETE FROM " + getObjectsTableName(clazz) + " WHERE id = :id"; + default: + throw new IllegalArgumentException("Unknown action"); + } + } + + public static String constructPermissionQuery(String action, Class owner, Class property) { + switch (action) { + case ACTION_SELECT_ALL: + return "SELECT " + makeNameId(owner) + ", " + makeNameId(property) + " FROM " + + getPermissionsTableName(owner, property); + case ACTION_INSERT: + return "INSERT INTO " + getPermissionsTableName(owner, property) + + " (" + makeNameId(owner) + ", " + makeNameId(property) + ") VALUES (:" + + makeNameId(owner) + ", :" + makeNameId(property) + ")"; + case ACTION_DELETE: + return "DELETE FROM " + getPermissionsTableName(owner, property) + + " WHERE " + makeNameId(owner) + " = :" + makeNameId(owner) + + " AND " + makeNameId(property) + " = :" + makeNameId(property); + default: + throw new IllegalArgumentException("Unknown action"); + } + } + private String getQuery(String key) { String query = config.getString(key); if (query == null) { @@ -123,6 +199,59 @@ public class DataManager { return query; } + public String getQuery(String action, Class clazz) { + return getQuery(action, clazz, false); + } + + public String getQuery(String action, Class clazz, boolean additional) { + String queryName; + if (action.equals(ACTION_SELECT_ALL)) { + queryName = "database.select" + clazz.getSimpleName() + "s"; + } else { + queryName = "database." + action.toLowerCase() + clazz.getSimpleName(); + } + String query = config.getString(queryName); + if (query == null) { + query = constructObjectQuery(action, clazz, additional); + config.setString(queryName, query); + } + + return query; + } + + public String getQuery(String action, Class owner, Class property) { + String queryName; + if (action.equals(ACTION_SELECT_ALL)) { + queryName = "database.select" + owner.getSimpleName() + property.getSimpleName() + "s"; + } else if (action.equals(ACTION_INSERT)) { + queryName = "database.link" + owner.getSimpleName() + property.getSimpleName(); + } else { + queryName = "database.unlink" + owner.getSimpleName() + property.getSimpleName(); + } + String query = config.getString(queryName); + if (query == null) { + query = constructPermissionQuery(action, owner, property.equals(User.class) ? ManagedUser.class : property); + config.setString(queryName, query); + } + + return query; + } + + private static String getPermissionsTableName(Class owner, Class property) { + String ownerName = owner.getSimpleName(); + String propertyName = property.getSimpleName(); + if (propertyName.equals("ManagedUser")) { + propertyName = "User"; + } + return ownerName.substring(0, 1).toLowerCase() + ownerName.substring(1) + "_" + + propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1); + } + + private static String getObjectsTableName(Class clazz) { + String name = clazz.getSimpleName(); + return name.substring(0, 1).toLowerCase() + name.substring(1) + "s"; + } + private void initDatabaseSchema() throws SQLException, LiquibaseException { if (config.hasKey("database.changelog")) { @@ -155,19 +284,8 @@ public class DataManager { } } - public void updateUser(User user) throws SQLException { - QueryBuilder.create(dataSource, getQuery("database.updateUser")) - .setObject(user) - .executeUpdate(); - if (user.getHashedPassword() != null) { - QueryBuilder.create(dataSource, getQuery("database.updateUserPassword")) - .setObject(user) - .executeUpdate(); - } - } - public void updateDeviceStatus(Device device) throws SQLException { - QueryBuilder.create(dataSource, getQuery("database.updateDeviceStatus")) + QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, Device.class, true)) .setObject(device) .executeUpdate(); } @@ -180,16 +298,10 @@ public class DataManager { .executeQuery(Position.class); } - public Position getPosition(long positionId) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectPosition")) - .setLong("id", positionId) - .executeQuerySingle(Position.class); - } - public void addPosition(Position position) throws SQLException { - position.setId(QueryBuilder.create(dataSource, getQuery("database.insertPosition"), true) - .setDate("now", new Date()) + position.setId(QueryBuilder.create(dataSource, getQuery(ACTION_INSERT, Position.class), true) .setObject(position) + .setDate("serverTime", new Date()) .executeUpdate()); } @@ -220,16 +332,10 @@ public class DataManager { } public Server getServer() throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectServers")) + return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, Server.class)) .executeQuerySingle(Server.class); } - public Event getEvent(long eventId) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectEvent")) - .setLong("id", eventId) - .executeQuerySingle(Event.class); - } - public Collection getEvents(long deviceId, Date from, Date to) throws SQLException { return QueryBuilder.create(dataSource, getQuery("database.selectEvents")) .setLong("deviceId", deviceId) @@ -268,12 +374,6 @@ public class DataManager { .executeQuery(Statistics.class); } - public void addStatistics(Statistics statistics) throws SQLException { - statistics.setId(QueryBuilder.create(dataSource, getQuery("database.insertStatistics"), true) - .setObject(statistics) - .executeUpdate()); - } - public static Class getClassByName(String name) throws ClassNotFoundException { switch (name.toLowerCase().replace("id", "")) { case "device": @@ -302,44 +402,50 @@ public class DataManager { return name.substring(0, 1).toLowerCase() + name.substring(1) + (name.indexOf("Id") == -1 ? "Id" : ""); } + public Collection getPermissions(Class owner, Class property) + throws SQLException, ClassNotFoundException { + return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, owner, property)) + .executePermissionsQuery(); + } + public void linkObject(Class owner, long ownerId, Class property, long propertyId, boolean link) throws SQLException { - String query = "database." + (link ? "link" : "unlink") + owner.getSimpleName() + property.getSimpleName(); - QueryBuilder queryBuilder = QueryBuilder.create(dataSource, getQuery(query)); - - queryBuilder.setLong(makeNameId(owner), ownerId); - queryBuilder.setLong(makeNameId(property), propertyId); - queryBuilder.executeUpdate(); + QueryBuilder.create(dataSource, getQuery(link ? ACTION_INSERT : ACTION_DELETE, owner, property)) + .setLong(makeNameId(owner), ownerId) + .setLong(makeNameId(property), propertyId) + .executeUpdate(); } - public Collection getObjects(Class clazz) throws SQLException { - String query = "database.select" + clazz.getSimpleName() + "s"; - return QueryBuilder.create(dataSource, getQuery(query)).executeQuery(clazz); + public T getObject(Class clazz, long entityId) throws SQLException { + return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT, clazz)) + .setLong("id", entityId) + .executeQuerySingle(clazz); } - public Collection getPermissions(Class owner, - Class property) throws SQLException, ClassNotFoundException { - String query = "database.select" + owner.getSimpleName() + property.getSimpleName() + "s"; - return QueryBuilder.create(dataSource, getQuery(query)).executePermissionsQuery(); + public Collection getObjects(Class clazz) throws SQLException { + return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, clazz)) + .executeQuery(clazz); } public void addObject(BaseModel entity) throws SQLException { - String query = "database.insert" + entity.getClass().getSimpleName(); - entity.setId(QueryBuilder.create(dataSource, getQuery(query), true) + entity.setId(QueryBuilder.create(dataSource, getQuery(ACTION_INSERT, entity.getClass()), true) .setObject(entity) .executeUpdate()); } public void updateObject(BaseModel entity) throws SQLException { - String query = "database.update" + entity.getClass().getSimpleName(); - QueryBuilder.create(dataSource, getQuery(query)) + QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, entity.getClass())) .setObject(entity) .executeUpdate(); + if (entity instanceof User && ((User) entity).getHashedPassword() != null) { + QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, User.class, true)) + .setObject(entity) + .executeUpdate(); + } } public void removeObject(Class clazz, long entityId) throws SQLException { - String query = "database.delete" + clazz.getSimpleName(); - QueryBuilder.create(dataSource, getQuery(query)) + QueryBuilder.create(dataSource, getQuery(ACTION_DELETE, clazz)) .setLong("id", entityId) .executeUpdate(); } diff --git a/src/org/traccar/database/QueryAdditional.java b/src/org/traccar/database/QueryAdditional.java new file mode 100644 index 000000000..7a42c1875 --- /dev/null +++ b/src/org/traccar/database/QueryAdditional.java @@ -0,0 +1,27 @@ +/* + * 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.database; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface QueryAdditional { +} diff --git a/src/org/traccar/database/StatisticsManager.java b/src/org/traccar/database/StatisticsManager.java index 5b42416ad..06a3e7b35 100644 --- a/src/org/traccar/database/StatisticsManager.java +++ b/src/org/traccar/database/StatisticsManager.java @@ -61,7 +61,7 @@ public class StatisticsManager { statistics.setGeolocationRequests(geolocationRequests); try { - Context.getDataManager().addStatistics(statistics); + Context.getDataManager().addObject(statistics); } catch (SQLException e) { Log.warning(e); } diff --git a/src/org/traccar/model/Device.java b/src/org/traccar/model/Device.java index 6a13c2b77..cd5dd12c4 100644 --- a/src/org/traccar/model/Device.java +++ b/src/org/traccar/model/Device.java @@ -18,6 +18,9 @@ package org.traccar.model; import java.util.Date; import java.util.List; +import org.traccar.database.QueryAdditional; +import org.traccar.database.QueryIgnore; + public class Device extends ExtendedModel { private String name; @@ -46,6 +49,7 @@ public class Device extends ExtendedModel { private String status; + @QueryIgnore public String getStatus() { return status != null ? status : STATUS_OFFLINE; } @@ -56,6 +60,7 @@ public class Device extends ExtendedModel { private Date lastUpdate; + @QueryAdditional public Date getLastUpdate() { if (lastUpdate != null) { return new Date(lastUpdate.getTime()); @@ -74,6 +79,7 @@ public class Device extends ExtendedModel { private long positionId; + @QueryIgnore public long getPositionId() { return positionId; } @@ -94,6 +100,7 @@ public class Device extends ExtendedModel { private List geofenceIds; + @QueryIgnore public List getGeofenceIds() { return geofenceIds; } diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 4412b012c..66a6f91ce 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -17,6 +17,8 @@ package org.traccar.model; import java.util.Date; +import org.traccar.database.QueryIgnore; + public class Position extends Message { public static final String KEY_ORIGINAL = "raw"; @@ -196,6 +198,7 @@ public class Position extends Message { private boolean outdated; + @QueryIgnore public boolean getOutdated() { return outdated; } @@ -294,4 +297,10 @@ public class Position extends Message { this.network = network; } + @Override + @QueryIgnore + public String getType() { + return super.getType(); + } + } diff --git a/src/org/traccar/model/Server.java b/src/org/traccar/model/Server.java index cd5b0624e..246be0b4f 100644 --- a/src/org/traccar/model/Server.java +++ b/src/org/traccar/model/Server.java @@ -17,10 +17,12 @@ package org.traccar.model; import java.util.TimeZone; +import org.traccar.database.QueryIgnore; import org.traccar.helper.Log; public class Server extends ExtendedModel { + @QueryIgnore public String getVersion() { return Log.getAppVersion(); } diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index 6e6a079c2..72b53ee5d 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -16,6 +16,9 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.traccar.database.QueryAdditional; +import org.traccar.database.QueryIgnore; import org.traccar.helper.Hashing; import java.util.Date; @@ -228,6 +231,7 @@ public class User extends ExtendedModel { } } + @QueryIgnore public String getPassword() { return null; } @@ -243,6 +247,7 @@ public class User extends ExtendedModel { private String hashedPassword; @JsonIgnore + @QueryAdditional public String getHashedPassword() { return hashedPassword; } @@ -254,6 +259,7 @@ public class User extends ExtendedModel { private String salt; @JsonIgnore + @QueryAdditional public String getSalt() { return salt; } diff --git a/test/org/traccar/database/DataManagerTest.java b/test/org/traccar/database/DataManagerTest.java new file mode 100644 index 000000000..3383c3d22 --- /dev/null +++ b/test/org/traccar/database/DataManagerTest.java @@ -0,0 +1,79 @@ +package org.traccar.database; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.model.Attribute; +import org.traccar.model.Device; +import org.traccar.model.Driver; +import org.traccar.model.Geofence; +import org.traccar.model.Group; +import org.traccar.model.ManagedUser; +import org.traccar.model.Position; +import org.traccar.model.User; + +public class DataManagerTest { + + @Test + public void constructObjectQuery() { + Assert.assertEquals("SELECT * FROM users", + DataManager.constructObjectQuery(DataManager.ACTION_SELECT_ALL, User.class, false)); + Assert.assertEquals("DELETE FROM groups WHERE id = :id", + DataManager.constructObjectQuery(DataManager.ACTION_DELETE, Group.class, false)); + Assert.assertEquals("SELECT * FROM positions WHERE id = :id", + DataManager.constructObjectQuery(DataManager.ACTION_SELECT, Position.class, false)); + + String insertDevice = DataManager.constructObjectQuery(DataManager.ACTION_INSERT, Device.class, false); + Assert.assertFalse(insertDevice.contains("class")); + Assert.assertFalse(insertDevice.contains("id")); + Assert.assertFalse(insertDevice.contains("status")); + Assert.assertFalse(insertDevice.contains("lastUpdate")); + Assert.assertFalse(insertDevice.contains("geofenceIds")); + + String updateDeviceStatus = DataManager.constructObjectQuery("update", Device.class, true); + Assert.assertTrue(updateDeviceStatus.contains("lastUpdate")); + + String updateUser = DataManager.constructObjectQuery(DataManager.ACTION_UPDATE, User.class, false); + Assert.assertFalse(updateUser.contains("class")); + Assert.assertFalse(updateUser.contains("password")); + Assert.assertFalse(updateUser.contains("salt")); + + String updateUserPassword = DataManager.constructObjectQuery(DataManager.ACTION_UPDATE, User.class, true); + Assert.assertFalse(updateUserPassword.contains("name")); + Assert.assertTrue(updateUserPassword.contains("hashedPassword")); + Assert.assertTrue(updateUserPassword.contains("salt")); + + String insertPosition = DataManager.constructObjectQuery(DataManager.ACTION_INSERT, Position.class, false); + Assert.assertFalse(insertPosition.contains("type")); + Assert.assertFalse(insertPosition.contains("outdated")); + + } + + @Test + public void constructPermissionsQuery() { + Assert.assertEquals("SELECT userId, deviceId FROM user_device", + DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, User.class, Device.class)); + + Assert.assertEquals("SELECT userId, managedUserId FROM user_user", + DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, User.class, ManagedUser.class)); + + Assert.assertEquals("SELECT deviceId, driverId FROM device_driver", + DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, Device.class, Driver.class)); + + Assert.assertEquals("SELECT groupId, geofenceId FROM group_geofence", + DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, Group.class, Geofence.class)); + + Assert.assertEquals("INSERT INTO user_device (userId, deviceId) VALUES (:userId, :deviceId)", + DataManager.constructPermissionQuery(DataManager.ACTION_INSERT, User.class, Device.class)); + + Assert.assertEquals("DELETE FROM user_user WHERE userId = :userId AND managedUserId = :managedUserId", + DataManager.constructPermissionQuery(DataManager.ACTION_DELETE, User.class, ManagedUser.class)); + + Assert.assertEquals("INSERT INTO device_geofence (deviceId, geofenceId) VALUES (:deviceId, :geofenceId)", + DataManager.constructPermissionQuery(DataManager.ACTION_INSERT, Device.class, Geofence.class)); + + Assert.assertEquals("DELETE FROM group_attribute WHERE groupId = :groupId AND attributeId = :attributeId", + DataManager.constructPermissionQuery(DataManager.ACTION_DELETE, Group.class, Attribute.class)); + + } + +} -- cgit v1.2.3 From 566f6b0dda38da75ed1fc89c9f5d29769fc1fbe9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Aug 2017 06:53:55 +1200 Subject: Update GB100 binary decoder --- src/org/traccar/helper/BitBuffer.java | 12 +- .../protocol/Gl200BinaryProtocolDecoder.java | 221 ++++++++++++++++++++- test/org/traccar/ProtocolTest.java | 2 +- .../protocol/Gl200BinaryProtocolDecoderTest.java | 12 ++ 4 files changed, 241 insertions(+), 6 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/helper/BitBuffer.java b/src/org/traccar/helper/BitBuffer.java index 7626988cc..ac307efdf 100644 --- a/src/org/traccar/helper/BitBuffer.java +++ b/src/org/traccar/helper/BitBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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,7 +20,7 @@ import org.jboss.netty.buffer.ChannelBuffers; public class BitBuffer { - private ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + private final ChannelBuffer buffer; private int writeByte; private int writeCount; @@ -28,6 +28,14 @@ public class BitBuffer { private int readByte; private int readCount; + public BitBuffer() { + buffer = ChannelBuffers.dynamicBuffer(); + } + + public BitBuffer(ChannelBuffer buffer) { + this.buffer = buffer; + } + public void writeEncoded(byte[] bytes) { for (byte b : bytes) { b -= 48; diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index a7ecf40d5..071960e49 100644 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -19,6 +19,8 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitBuffer; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; @@ -28,6 +30,8 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.LinkedList; +import java.util.List; public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { @@ -42,12 +46,171 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { return dateBuilder.getDate(); } + public static final int MSG_RSP_LCB = 3; + public static final int MSG_RSP_GEO = 8; + public static final int MSG_RSP_COMPRESSED = 100; + + private List decodeLocation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + List positions = new LinkedList<>(); + + int type = buf.readUnsignedByte(); + + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version + buf.readUnsignedShort(); // firmware version + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + + int battery = buf.readUnsignedByte(); + int power = buf.readUnsignedShort(); + + if (type == MSG_RSP_GEO) { + buf.readUnsignedByte(); // reserved + buf.readUnsignedByte(); // reserved + } + + buf.readUnsignedByte(); // motion status + int satellites = buf.readUnsignedByte(); + + if (type != MSG_RSP_COMPRESSED) { + buf.readUnsignedByte(); // index + } + + if (type == MSG_RSP_LCB) { + buf.readUnsignedByte(); // phone length + for (int b = buf.readUnsignedByte();; b = buf.readUnsignedByte()) { + if ((b & 0xf) == 0xf || (b & 0xf0) == 0xf0) { + break; + } + } + } + + if (type == MSG_RSP_COMPRESSED) { + + int count = buf.readUnsignedShort(); + + BitBuffer bits; + int speed = 0; + int heading = 0; + int latitude = 0; + int longitude = 0; + long time = 0; + + for (int i = 0; i < count; i++) { + + if (time > 0) { + time += 1; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + switch (BitUtil.from(buf.getUnsignedByte(buf.readerIndex()), 8 - 2)) { + case 1: + bits = new BitBuffer(buf.readBytes(3)); + bits.readUnsigned(2); // point attribute + bits.readUnsigned(1); // fix type + speed = bits.readUnsigned(12); + heading = bits.readUnsigned(9); + longitude = buf.readInt(); + latitude = buf.readInt(); + if (time == 0) { + time = buf.readUnsignedInt(); + } + break; + case 2: + bits = new BitBuffer(buf.readBytes(5)); + bits.readUnsigned(2); // point attribute + bits.readUnsigned(1); // fix type + speed += bits.readSigned(7); + heading += bits.readSigned(7); + longitude += bits.readSigned(12); + latitude += bits.readSigned(11); + break; + default: + buf.readUnsignedByte(); // invalid or same + continue; + } + + position.setValid(true); + position.setTime(new Date(time * 1000)); + position.setSpeed(UnitsConverter.knotsFromKph(speed * 0.1)); + position.setCourse(heading); + position.setLongitude(longitude * 0.000001); + position.setLatitude(latitude * 0.000001); + + positions.add(position); + + } + + } else { + + int count = buf.readUnsignedByte(); + + for (int i = 0; i < count; i++) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_BATTERY_LEVEL, battery); + position.set(Position.KEY_POWER, power); + position.set(Position.KEY_SATELLITES, satellites); + + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium() * 0.1)); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + position.setTime(decodeTime(buf)); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + positions.add(position); + + } + + } + + return positions; + } + + public static final int MSG_EVT_BPL = 6; + public static final int MSG_EVT_VGN = 45; + public static final int MSG_EVT_VGF = 46; + public static final int MSG_EVT_UPD = 15; + public static final int MSG_EVT_IDF = 17; + public static final int MSG_EVT_GSS = 21; + public static final int MSG_EVT_GES = 26; + public static final int MSG_EVT_GPJ = 31; + public static final int MSG_EVT_RMD = 35; + public static final int MSG_EVT_JDS = 33; + public static final int MSG_EVT_CRA = 23; + public static final int MSG_EVT_UPC = 34; + private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { Position position = new Position(); position.setProtocol(getProtocolName()); - buf.readUnsignedByte(); // message type + int type = buf.readUnsignedByte(); + buf.readUnsignedInt(); // mask buf.readUnsignedShort(); // length buf.readUnsignedByte(); // device type @@ -67,13 +230,63 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // motion status position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + + switch (type) { + case MSG_EVT_BPL: + buf.readUnsignedShort(); // backup battery voltage + break; + case MSG_EVT_VGN: + case MSG_EVT_VGF: + buf.readUnsignedShort(); // reserved + buf.readUnsignedByte(); // report type + buf.readUnsignedInt(); // ignition duration + break; + case MSG_EVT_UPD: + buf.readUnsignedShort(); // code + buf.readUnsignedByte(); // retry + break; + case MSG_EVT_IDF: + buf.readUnsignedInt(); // idling duration + break; + case MSG_EVT_GSS: + buf.readUnsignedByte(); // gps signal status + buf.readUnsignedInt(); // reserved + break; + case MSG_EVT_GES: + buf.readUnsignedShort(); // trigger geo id + buf.readUnsignedByte(); // trigger geo enable + buf.readUnsignedByte(); // trigger mode + buf.readUnsignedInt(); // radius + buf.readUnsignedInt(); // check interval + break; + case MSG_EVT_GPJ: + buf.readUnsignedByte(); // cw jamming value + buf.readUnsignedByte(); // gps jamming state + break; + case MSG_EVT_RMD: + buf.readUnsignedByte(); // roaming state + break; + case MSG_EVT_JDS: + buf.readUnsignedByte(); // jamming state + break; + case MSG_EVT_CRA: + buf.readUnsignedByte(); // crash counter + break; + case MSG_EVT_UPC: + buf.readUnsignedByte(); // command id + buf.readUnsignedShort(); // result + break; + default: + break; + } + + buf.readUnsignedByte(); // count int hdop = buf.readUnsignedByte(); position.setValid(hdop > 0); position.set(Position.KEY_HDOP, hdop); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium() * 0.1)); position.setCourse(buf.readUnsignedShort()); position.setAltitude(buf.readShort()); position.setLongitude(buf.readInt() * 0.000001); @@ -179,6 +392,8 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; switch (buf.readBytes(4).toString(StandardCharsets.US_ASCII)) { + case "+RSP": + return decodeLocation(channel, remoteAddress, buf); case "+INF": return decodeInformation(channel, remoteAddress, buf); case "+EVT": diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index cb9cdf759..8a1602de7 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -118,7 +118,7 @@ public class ProtocolTest extends BaseTest { Assert.assertNotNull("list is null", decodedObject); Assert.assertTrue("not a list", decodedObject instanceof List); - Assert.assertFalse("list if empty", ((List) decodedObject).isEmpty()); + Assert.assertFalse("list is empty", ((List) decodedObject).isEmpty()); for (Object item : (List) decodedObject) { verifyDecodedPosition(item, checkLocation, false, expected); diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index 24830a953..ebcd4139b 100644 --- a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -10,6 +10,18 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + verifyPosition(decoder, binary( + "2b4556542d00fc1fbf0063450102020956325403000343056437f8220700000200000000010000160100f2007eff75a1f0025c6b1a07e1080108241a02680003189c1ac500000000000002100800000000000000000007e1080108241a19e24e4e0d0a")); + + verifyPositions(decoder, binary( + "2b5253506400fc1fbf058e450102020956325403000343056438ed2205010e61c6f0ff75a1b4025c6af959803d8ba07ffe17dea03f7e1fdda0007df7dfa03e7e3fd0a0befdf7cea001fddfd8a000fdefdca042fd9fe1a0427d6fe9a0017db7dca0407d47e7a0027d67e5bfc0fd77eca03ffd8fe4bfff7dcfddbffd7dbfdebffdfddfe2bfbe7e0fe1bf7f7e67e2bf7bfed7e2bf7c7f5fe2bffbffc7e3a12880a7daa0b9013fe3a0f801b7dfa0bd81efe1a03f8207e0a03e8217e4a07e023fe9a0bd824feca03a02affda07b02d004a07f02e007a00002d808a041830001a003834fefa00402b7eebf8382a7ebbfc28267e9bf81821fe3bf0181d7e3bf01016fe9bf010117edbf4080c7f6bf7f8087fabfbf805ff9a0fa8097fca23401300aa0b4016019a13a817026a13b81883ea0be81a83fa0bd81b03ba00101d83abfc0039874bfc081b835bfbf819834bfc081982fa01004702ea00502500da002827802bfc0825fffbf41821fffbf4081d801bf3f816802bec180fffebec20077fdbf80002801bfc0000800a000000800e0e0a202804ffba14a8127eea0460107e4a0cc809fd9a0c4004fcda0c2004fcaa080007fbfa0410067bebfc100c7b6a03f8037c1bfbf004fc6a03f0057c6a0410027c5a081001fbaa0418017baa001001fb8a0007fe7bca000ffdfb7a0817fc7b7a040ffbfb3a0407fb7b4a0407fb7b1bf807fbfb3a0007fb7b5a0007fb7b1a0007fb7b2a0007fbfb3a0407fafaba000ffb7ada0017f97aba040ff7faca001ff77b6bf3fff67b3bf007f87bea082ff47b4bfc27f17c1bfffff3fc2bebdff9fcabe3effbfe0bf3cff47e9a03c002ff0a1740097e9a1f8813fe1a12f01f7fca0fa028ff8a07f02a7fea041829007a00302bff8bf810287f2a0080257e1a0050207dbbfc481cfd3a044819fcda043015fc3a043810fc2a0c680a7b2a0448027b0a0857fa7aea0c37f67a2a0017ee7a7a0407f0f9fa000ff079fa03ffeffa1a03ffeffa2a07fff17a0a03fff1fa0a03fff2fa2a03fff3fa0a07fff47a2a0007f579fa03fff4f9da03fff679ca0007f679ea000ff4f9ca07fff5f9ca0007f579cbfc07f5f9fbf407f6fa6bf807f6fabbfc07f7fadbf807f87b2a0407f87b0a0407f77aba000ff77afbfc07f77aea03fff7fada07fff7faca000ff7fada0007f77abbfc0ff77b0a000ff7faea042ff2faba0037ee7ada0437e57a1a0037e27abbfc1fdf7bcbf827defc5bf01fe0fcebf017e3fd5bfc17e2fdca0ff7e27d7a13cfe27cba0bd7e0fa7a07d7e6fb9a07d7eb7b3a07efedfaea03ffef7afa0c07eefa7a07f7f07a3a03fff0fa3a03f7f27a2a03f7f37a4bfff7f6fa3bfff7f5fa3a07eff979fa03f7fbfa2a03f7fdfa1bfbf8017a5bfbf0037adbeff004fb8bfbf004fc1beff804fcbbf7f8047d5bf408027debf408007e8a03e804fdebf7e8027f2bf00ffefffa0400017efa0418017f1a041002feca0410017edbf007fbffea0007fdff6a1018027e4bf81ffc7f6a1008017dca0c10087bea0018097baa083ffc7cda0837fafc7a102ff0fc8a0c27effb9a0c2fe87c1a143fbf78ea07f7dcfc0a0bd7dffb3a03d7e47b1a03ffe77afa07ffe77ada0007e77aebfc07e77afbfc07e8faea03ffea7afbfbf7ecfb4bfbcfeffbbbf7bff8fb8bf7d0027bebffb809fc7bffa00ffc9bf78813fd9a03d8197e1a03b81d7e6a07e01efdda00081bfdda00101bfdba03f81a7dfbfc001afdbbfbd81a7f1bfbe0187eebf80814feea0028127e7a081813fe2a0010147e6a03e8147f4a0408167eca040817fe7a0018157e4bfc8011fdaa08b002fd1a009ffa7d5a009fe57f6a04b7df7f4a0097e07eca0027df7edbf807e2feca000fe3feca07ffe37f0a0407e0ff7a040fde7f0a0007de7eea000fdcff4a001fddffaa000fdcff8a0027dcffda07f7dbff3a03f7dc7f402680003189c355300000109000002120700000000000000000007e1080108290019e63b5c0d0a")); + + verifyNotNull(decoder, binary( + "2B5253500300FC1FFF0064450102020867623130302D446F642F442105007018217345005F010100000001100045073C4D4101DB86BD07E106130B2B0F0460000018770013000000030000000106020F2300002714301107E106130B2B1003424EFB0D0A")); + + verifyPositions(decoder, binary( + "2b5253500700fc1fbf005d4501020209563254030003430564377e42071001000000000000007eff75a151025c6a8107e10801081a2a02680003189c1ac500000000000002100700000000000000000007e1080108241019e17ebe0d0a")); + verifyAttributes(decoder, binary( "2b494e4601fd7f0076676231303000000045010202090104020500004100054007e107150b061d0000003f010e02580000000000d0312a1013648935103226313921591f1200000000000302680003189c1ac3001b02680003189c1ac4000d02680003189c1ac5001207e107150b0d3704f658060d0a")); -- cgit v1.2.3 From 237c80296fe947c6857c9509ba1b947ed02b354f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Aug 2017 07:52:33 +1200 Subject: Implement TLV communication protocol --- setup/default.xml | 1 + src/org/traccar/protocol/TlvProtocol.java | 43 ++++++++ src/org/traccar/protocol/TlvProtocolDecoder.java | 109 +++++++++++++++++++++ .../traccar/protocol/TlvProtocolDecoderTest.java | 24 +++++ 4 files changed, 177 insertions(+) create mode 100644 src/org/traccar/protocol/TlvProtocol.java create mode 100644 src/org/traccar/protocol/TlvProtocolDecoder.java create mode 100644 test/org/traccar/protocol/TlvProtocolDecoderTest.java (limited to 'test/org') diff --git a/setup/default.xml b/setup/default.xml index 2c126e6dd..ff0447652 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -234,5 +234,6 @@ 5143 5144 5145 + 5146 diff --git a/src/org/traccar/protocol/TlvProtocol.java b/src/org/traccar/protocol/TlvProtocol.java new file mode 100644 index 000000000..da8d88b8a --- /dev/null +++ b/src/org/traccar/protocol/TlvProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class TlvProtocol extends BaseProtocol { + + public TlvProtocol() { + super("tlv"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder('\0')); + pipeline.addLast("objectDecoder", new TlvProtocolDecoder(TlvProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/TlvProtocolDecoder.java b/src/org/traccar/protocol/TlvProtocolDecoder.java new file mode 100644 index 000000000..41d65be09 --- /dev/null +++ b/src/org/traccar/protocol/TlvProtocolDecoder.java @@ -0,0 +1,109 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class TlvProtocolDecoder extends BaseProtocolDecoder { + + public TlvProtocolDecoder(TlvProtocol protocol) { + super(protocol); + } + + private void sendResponse(Channel channel, String type, String... arguments) { + if (channel != null) { + ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + response.writeBytes(ChannelBuffers.copiedBuffer(type, StandardCharsets.US_ASCII)); + for (String argument : arguments) { + response.writeByte(argument.length()); + response.writeBytes(ChannelBuffers.copiedBuffer(argument, StandardCharsets.US_ASCII)); + } + response.writeByte(0); + channel.write(response); + } + } + + private String readArgument(ChannelBuffer buf) { + return buf.readBytes(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + String type = buf.readBytes(2).toString(StandardCharsets.US_ASCII); + + if (channel != null) { + switch (type) { + case "0A": + case "0C": + sendResponse(channel, type); + break; + case "0B": + sendResponse(channel, type, "1482202689", "10", "20", "15"); + break; + case "0E": + case "0F": + sendResponse(channel, type, "30", "Unknown"); + break; + default: + break; + } + } + + if (type.equals("0E")) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readArgument(buf)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(new Date(Long.parseLong(readArgument(buf)) * 1000)); + + readArgument(buf); // location identifier + + position.setLongitude(Double.parseDouble(readArgument(buf))); + position.setLatitude(Double.parseDouble(readArgument(buf))); + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(readArgument(buf)))); + position.setCourse(Double.parseDouble(readArgument(buf))); + + position.set(Position.KEY_SATELLITES, Integer.parseInt(readArgument(buf))); + + return position; + + } + + return null; + } + +} diff --git a/test/org/traccar/protocol/TlvProtocolDecoderTest.java b/test/org/traccar/protocol/TlvProtocolDecoderTest.java new file mode 100644 index 000000000..6c37c4dbb --- /dev/null +++ b/test/org/traccar/protocol/TlvProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TlvProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + TlvProtocolDecoder decoder = new TlvProtocolDecoder(new TlvProtocol()); + + verifyNull(decoder, binary( + "30430f383630323437303330303934333931ff10393233323132323030303834353433340f533636385f415f56312e30315f454eff1130303a30433a45373a30303a30303a30300132")); + + verifyNull(decoder, binary( + "30410f383630323437303330303934333931")); + + verifyNull(decoder, binary( + "30420f3836303234373033303039343339310131")); + + } + +} -- cgit v1.2.3 From 4d35ef57f3dff21348d9ae9fe269176cd885c127 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Aug 2017 02:17:58 +1200 Subject: Add VT400 test cases --- .../org/traccar/protocol/Vt200ProtocolDecoderTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index d63bf0062..19155af5a 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -10,6 +10,24 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { Vt200ProtocolDecoder decoder = new Vt200ProtocolDecoder(new Vt200Protocol()); + verifyNull(decoder, binary( + "286310373094563082002701033d00010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); + + verifyNull(decoder, binary( + "286310373094562086002101033d0001081714333d15441790420114817637207d090a00000847002001207f00d6f229")); + + verifyNull(decoder, binary( + "286310373094562086002101033d000108171433354417932101148139772c9d080a00000847002001207f00dc6729")); + + verifyNull(decoder, binary( + "2863103730945600880012180108171433004418103801148375470000dd29")); + + verifyNull(decoder, binary( + "28631037309456108800002e29")); + + verifyNull(decoder, binary( + "2863103730945630880062033c862631037309456f222014604362936f01081713365601081713571904c800001b2c000034f66827f0840000000000000000000000000047000006e7000001b9022a000023ff000007f2018a00000a10000003f300cd00000d8d0300000302002729")); + verifyNull(decoder, binary( "28631037309456008e000801042307171804584229")); -- cgit v1.2.3 From c6760e2ca84a0118c1439a6cbee0da42ed4a1c92 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Aug 2017 00:39:09 +1200 Subject: Improve frame decoder testing --- test/org/traccar/ProtocolTest.java | 10 +++++----- test/org/traccar/protocol/Vt200FrameDecoderTest.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'test/org') diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 8a1602de7..daa495a17 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -270,14 +270,14 @@ public class ProtocolTest extends BaseTest { protected void verifyCommand( BaseProtocolEncoder encoder, Command command, ChannelBuffer expected) throws Exception { - verifyDecodedCommand(encoder.encodeCommand(command), expected); + verifyFrame(expected, encoder.encodeCommand(command)); } - private void verifyDecodedCommand(Object decodedObject, ChannelBuffer expected) { + protected void verifyFrame(ChannelBuffer expected, Object object) { - Assert.assertNotNull("command is null", decodedObject); - Assert.assertTrue("not a buffer", decodedObject instanceof ChannelBuffer); - Assert.assertEquals(ChannelBuffers.hexDump(expected), ChannelBuffers.hexDump((ChannelBuffer) decodedObject)); + Assert.assertNotNull("buffer is null", object); + Assert.assertTrue("not a buffer", object instanceof ChannelBuffer); + Assert.assertEquals(ChannelBuffers.hexDump(expected), ChannelBuffers.hexDump((ChannelBuffer) object)); } diff --git a/test/org/traccar/protocol/Vt200FrameDecoderTest.java b/test/org/traccar/protocol/Vt200FrameDecoderTest.java index b31e14b7d..a9fff6c33 100644 --- a/test/org/traccar/protocol/Vt200FrameDecoderTest.java +++ b/test/org/traccar/protocol/Vt200FrameDecoderTest.java @@ -11,11 +11,11 @@ public class Vt200FrameDecoderTest extends ProtocolTest { Vt200FrameDecoder decoder = new Vt200FrameDecoder(); - Assert.assertEquals( + verifyFrame( binary("28631037309456208400340102dc0906171616454415760201144494473f920a0c0000030500200100417c1f383a9d1090510000006a00007000000e00180ee129"), decoder.decode(null, null, binary("28631037309456208400340102dc0906171616454415760201144494473f920a0c0000030500200100417c1f383a9d1090510000006a00007000000e00180ee129"))); - Assert.assertEquals( + verifyFrame( binary("28631037309456208400340102f51306171327294418267501208948170231071f0000044300200100005f02180000667500000000000000000000080000624629"), decoder.decode(null, null, binary("28631037309456208400340102f513061713273d144418267501208948170231071f0000044300200100005f02180000667500000000000000000000080000624629"))); -- cgit v1.2.3 From f182ae04a9857e13482421957140e1a70af2302b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Aug 2017 00:40:48 +1200 Subject: Improve VT400 protocol decoder --- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- test/org/traccar/protocol/Vt200ProtocolDecoderTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index f9683f12f..111c29313 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -57,7 +57,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedShort(); buf.readUnsignedShort(); // length - if (type == 0x2084 || type == 0x2082) { + if (type == 0x2086 || type == 0x2084 || type == 0x2082) { Position position = new Position(); position.setProtocol(getProtocolName()); diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index 19155af5a..37d9c46d9 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -11,13 +11,13 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { Vt200ProtocolDecoder decoder = new Vt200ProtocolDecoder(new Vt200Protocol()); verifyNull(decoder, binary( - "286310373094563082002701033d00010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); + "286310373094563082002701033d010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); - verifyNull(decoder, binary( - "286310373094562086002101033d0001081714333d15441790420114817637207d090a00000847002001207f00d6f229")); + verifyPosition(decoder, binary( + "286310373094562086002101033d010817143328441790420114817637207d090a00000847002001207f00d6f229")); - verifyNull(decoder, binary( - "286310373094562086002101033d000108171433354417932101148139772c9d080a00000847002001207f00dc6729")); + verifyPosition(decoder, binary( + "286310373094562086002101033d0108171433354417932101148139772c9d080a00000847002001207f00dc6729")); verifyNull(decoder, binary( "2863103730945600880012180108171433004418103801148375470000dd29")); -- cgit v1.2.3 From 3bc4e07dff292c22e29a1fa3bf9d07796d2e89b7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Aug 2017 02:06:51 +1200 Subject: Decode GV500VC rssi value --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 8 +++++++- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 57fecc3fe..63adb1c70 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -66,7 +66,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:[^,]+)?,") // device name .number("(xx),") // state .expression("(?:[0-9F]{20})?,") // iccid - .number("d{1,2},") + .number("(d{1,2}),") // rssi .number("d{1,2},") .expression("[01],") // external power .number("([d.]+)?,") // odometer or external power @@ -388,6 +388,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { + + org.traccar.helper.PatternUtil.MatchResult matchResult = + org.traccar.helper.PatternUtil.checkPattern(PATTERN_INF.pattern(), sentence); + Parser parser = new Parser(PATTERN_INF, sentence); Position position = initPosition(parser, channel, remoteAddress); if (position == null) { @@ -396,6 +400,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, parser.next()); + position.set(Position.KEY_RSSI, parser.nextInt()); + parser.next(); // odometer or external power position.set(Position.KEY_BATTERY, parser.nextDouble(0)); diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index e694022f2..9e2571916 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyNull(decoder, buffer( + "+RESP:GTINF,280500,A1000043D20139,GL300VC,41,,31,0,0,,,3.87,0,1,1,,,20170802150751,70,,48.0,,,20170802112145,03AC$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,2D0300,A1000043D20139,1G1JC5444R7252367,,11,,31,0,1,12986,,4.16,0,2,,,20170802145640,,,,,,+0000,0,20170802145643,CD5A$")); + verifyPosition(decoder, buffer( "+RESP:GTMPN,450102,865084030001323,gb100,0,1.6,0,-93.1,121.393023,31.164105,20170619103113,0460,0000,1806,2142,00,20170619103143,0512$")); -- cgit v1.2.3 From adf043bb8167ddb25fe96fcabc4cc35ff2deaf37 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 4 Aug 2017 16:32:56 +0500 Subject: Write all fields on insert action --- src/org/traccar/database/DataManager.java | 2 +- test/org/traccar/database/DataManagerTest.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index ea90d4d67..17c1299e8 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -146,7 +146,7 @@ public class DataManager { skip = !method.isAnnotationPresent(QueryExtended.class); } else { skip = method.isAnnotationPresent(QueryIgnore.class) - || method.isAnnotationPresent(QueryExtended.class); + || method.isAnnotationPresent(QueryExtended.class) && !action.equals(ACTION_INSERT); } if (!skip && method.getName().startsWith("get") && method.getParameterTypes().length == 0) { String name = Introspector.decapitalize(method.getName().substring(3)); diff --git a/test/org/traccar/database/DataManagerTest.java b/test/org/traccar/database/DataManagerTest.java index 3383c3d22..3d6f5201e 100644 --- a/test/org/traccar/database/DataManagerTest.java +++ b/test/org/traccar/database/DataManagerTest.java @@ -26,7 +26,6 @@ public class DataManagerTest { Assert.assertFalse(insertDevice.contains("class")); Assert.assertFalse(insertDevice.contains("id")); Assert.assertFalse(insertDevice.contains("status")); - Assert.assertFalse(insertDevice.contains("lastUpdate")); Assert.assertFalse(insertDevice.contains("geofenceIds")); String updateDeviceStatus = DataManager.constructObjectQuery("update", Device.class, true); -- cgit v1.2.3 From 94a922eaf167a73a0188255398fb1c6799767e18 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 8 Aug 2017 09:53:31 +0500 Subject: Implement motion detection similar to trips detection --- src/org/traccar/database/ConnectionManager.java | 45 ++++++++++++- src/org/traccar/database/DeviceManager.java | 12 ++++ src/org/traccar/events/MotionEventHandler.java | 75 ++++++++++++++++++---- src/org/traccar/model/DeviceState.java | 41 ++++++++++++ src/org/traccar/reports/ReportUtils.java | 2 +- .../org/traccar/events/MotionEventHandlerTest.java | 56 +++++++++++++--- 6 files changed, 207 insertions(+), 24 deletions(-) create mode 100644 src/org/traccar/model/DeviceState.java (limited to 'test/org') diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 1445fb785..b3b00fefa 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -23,8 +23,11 @@ import org.traccar.GlobalTimer; import org.traccar.Protocol; import org.traccar.helper.Log; 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 java.net.SocketAddress; import java.sql.SQLException; @@ -41,6 +44,7 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean enableStatusEvents; + private TripsConfig tripsConfig = null; private final Map activeDevices = new ConcurrentHashMap<>(); private final Map> listeners = new ConcurrentHashMap<>(); @@ -49,6 +53,9 @@ public class ConnectionManager { public ConnectionManager() { deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; enableStatusEvents = Context.getConfig().getBoolean("event.enable"); + if (Context.getConfig().getBoolean("status.updateDeviceState")) { + tripsConfig = ReportUtils.initTripsConfig(); + } } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { @@ -80,21 +87,30 @@ public class ConnectionManager { if (enableStatusEvents && !status.equals(oldStatus)) { String eventType; + Event stateEvent = null; switch (status) { case Device.STATUS_ONLINE: eventType = Event.TYPE_DEVICE_ONLINE; break; case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; + if (tripsConfig != null) { + stateEvent = updateDeviceState(deviceId); + } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; + if (tripsConfig != null) { + stateEvent = updateDeviceState(deviceId); + } break; } - Event event = new Event(eventType, deviceId); - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().updateEvent(event, null); + Set events = new HashSet<>(); + if (stateEvent != null) { + events.add(stateEvent); } + events.add(new Event(eventType, deviceId)); + Context.getNotificationManager().updateEvents(events, null); } Timeout timeout = timeouts.remove(deviceId); @@ -126,6 +142,29 @@ public class ConnectionManager { updateDevice(device); } + public Event updateDeviceState(long deviceId) { + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + if (deviceState == null || deviceState.getMotionState() == null) { + return null; + } + Event result = null; + Boolean oldMotion = deviceState.getMotionState(); + long currentTime = new Date().getTime(); + boolean newMotion = !oldMotion; + Position potentialPosition = deviceState.getMotionPosition(); + if (potentialPosition != null) { + long potentialTime = potentialPosition.getFixTime().getTime() + + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); + if (potentialTime <= currentTime) { + String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + result = new Event(eventType, potentialPosition.getDeviceId(), potentialPosition.getId()); + deviceState.setMotionState(newMotion); + deviceState.setMotionPosition(null); + } + } + return result; + } + public synchronized void updateDevice(Device device) { for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { if (listeners.containsKey(userId)) { diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 5d123f9b8..3b7e5c617 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -33,6 +33,7 @@ import org.traccar.helper.Log; import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; +import org.traccar.model.DeviceState; import org.traccar.model.DeviceTotalDistance; import org.traccar.model.Group; import org.traccar.model.Position; @@ -52,6 +53,8 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map positions = new ConcurrentHashMap<>(); + private final Map deviceStates = new ConcurrentHashMap<>(); + private boolean fallbackToText; public DeviceManager(DataManager dataManager) { @@ -387,4 +390,13 @@ public class DeviceManager extends BaseObjectManager implements Identity } return result; } + + public DeviceState getDeviceState(long deviceId) { + return deviceStates.get(deviceId); + } + + public void setDeviceState(long deviceId, DeviceState deviceState) { + deviceStates.put(deviceId, deviceState); + } + } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index ed81176a8..9168d0fd8 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -21,11 +21,60 @@ import java.util.Collections; import org.traccar.BaseEventHandler; import org.traccar.Context; 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; public class MotionEventHandler extends BaseEventHandler { + private TripsConfig tripsConfig; + + public MotionEventHandler() { + if (Context.getConfig() != null) { + tripsConfig = ReportUtils.initTripsConfig(); + } + } + + public static Event updateMotionState(DeviceState deviceState, Position position, TripsConfig tripsConfig) { + Event result = null; + Boolean oldMotion = deviceState.getMotionState(); + + long currentTime = position.getFixTime().getTime(); + boolean newMotion = position.getBoolean(Position.KEY_MOTION); + if (newMotion != oldMotion) { + if (deviceState.getMotionPosition() == null) { + deviceState.setMotionPosition(position); + } + } else { + deviceState.setMotionPosition(null); + } + + Position potentialPosition = deviceState.getMotionPosition(); + if (potentialPosition != null) { + long potentialTime = potentialPosition.getFixTime().getTime(); + double distance = ReportUtils.calculateDistance(potentialPosition, position, false); + if (newMotion) { + if (potentialTime + tripsConfig.getMinimalTripDuration() <= currentTime + || distance >= tripsConfig.getMinimalTripDistance()) { + result = new Event(Event.TYPE_DEVICE_MOVING, potentialPosition.getDeviceId(), + potentialPosition.getId()); + deviceState.setMotionState(true); + deviceState.setMotionPosition(null); + } + } else { + if (potentialTime + tripsConfig.getMinimalParkingDuration() <= currentTime) { + result = new Event(Event.TYPE_DEVICE_STOPPED, potentialPosition.getDeviceId(), + potentialPosition.getId()); + deviceState.setMotionState(false); + deviceState.setMotionPosition(null); + } + } + } + return result; + } + @Override protected Collection analyzePosition(Position position) { @@ -37,18 +86,22 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - boolean motion = position.getBoolean(Position.KEY_MOTION); - boolean oldMotion = false; - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - if (lastPosition != null) { - oldMotion = lastPosition.getBoolean(Position.KEY_MOTION); + Event result = null; + + long deviceId = position.getDeviceId(); + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + + if (deviceState == null) { + deviceState = new DeviceState(); + deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); + } else if (deviceState.getMotionState() == null) { + deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); + } else { + result = updateMotionState(deviceState, position, tripsConfig); } - if (motion && !oldMotion) { - return Collections.singleton( - new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId())); - } else if (!motion && oldMotion) { - return Collections.singleton( - new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId())); + Context.getDeviceManager().setDeviceState(deviceId, deviceState); + if (result != null) { + return Collections.singleton(result); } return null; } diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java new file mode 100644 index 000000000..3626b9953 --- /dev/null +++ b/src/org/traccar/model/DeviceState.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.model; + +public class DeviceState { + + private Boolean motionState; + + public void setMotionState(boolean motionState) { + this.motionState = motionState; + } + + public Boolean getMotionState() { + return motionState; + } + + private Position motionPosition; + + public void setMotionPosition(Position motionPosition) { + this.motionPosition = motionPosition; + } + + public Position getMotionPosition() { + return motionPosition; + } + +} diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 540feb6c6..e8db7e3b5 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -157,8 +157,8 @@ public final class ReportUtils { public static TripsConfig initTripsConfig() { return new TripsConfig( - Context.getConfig().getLong("report.trip.minimalTripDuration", 300) * 1000, Context.getConfig().getLong("report.trip.minimalTripDistance", 500), + Context.getConfig().getLong("report.trip.minimalTripDuration", 300) * 1000, Context.getConfig().getLong("report.trip.minimalParkingDuration", 300) * 1000, Context.getConfig().getBoolean("report.trip.greedyParking"), Context.getConfig().getLong("report.trip.minimalNoDataDuration", 3600) * 1000); diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index f05ef54d5..c44f3f4eb 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -2,28 +2,66 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; -import java.util.Collection; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; import org.junit.Test; import org.traccar.BaseTest; +import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; public class MotionEventHandlerTest extends BaseTest { - + + private Date date(String time) throws ParseException { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.parse(time); + } + @Test public void testMotionEventHandler() throws Exception { - - MotionEventHandler motionEventHandler = new MotionEventHandler(); - + TripsConfig tripsConfig = new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0); + Position position = new Position(); + position.setTime(date("2017-01-01 00:00:00")); position.set(Position.KEY_MOTION, true); - position.setValid(true); - Collection events = motionEventHandler.analyzePosition(position); - assertNotNull(events); - Event event = (Event) events.toArray()[0]; + position.set(Position.KEY_TOTAL_DISTANCE, 0); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(false); + deviceState.setMotionPosition(position); + Position nextPosition = new Position(); + + nextPosition.setTime(date("2017-01-01 00:02:00")); + nextPosition.set(Position.KEY_MOTION, true); + nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); + + Event event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + assertNull(event); + + nextPosition.set(Position.KEY_TOTAL_DISTANCE, 600); + event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); + assertTrue(deviceState.getMotionState()); + assertNull(deviceState.getMotionPosition()); + + deviceState.setMotionState(false); + deviceState.setMotionPosition(position); + nextPosition.setTime(date("2017-01-01 00:06:00")); + nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); + event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + assertNotNull(event); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); + assertTrue(deviceState.getMotionState()); + assertNull(deviceState.getMotionPosition()); } } -- cgit v1.2.3 From 3e16121df8402269ae9f69c80ebe6d4eaaff43a6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Aug 2017 21:49:41 +1200 Subject: Add Tramigo test cases --- test/org/traccar/protocol/TramigoProtocolDecoderTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/TramigoProtocolDecoderTest.java b/test/org/traccar/protocol/TramigoProtocolDecoderTest.java index 96f795172..5e1f09543 100644 --- a/test/org/traccar/protocol/TramigoProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TramigoProtocolDecoderTest.java @@ -12,6 +12,18 @@ public class TramigoProtocolDecoderTest extends ProtocolTest { TramigoProtocolDecoder decoder = new TramigoProtocolDecoder(new TramigoProtocol()); + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "8000c426b000a6000101c557037598050d5c8a595472616d69676f3a204d6f76696e672c20302e3132206b6d2045206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333134392c203130302e37333038352c204e572077697468207370656564203130206b6d2f682c2030303a34393a30382041756720392020454f46")); + + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "8000c526b000a6000101f17d03759805115c8a595472616d69676f3a204d6f76696e672c20302e3133206b6d205345206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333132322c203130302e37333037382c204e4520776974682073706565642039206b6d2f682c2030303a34383a35332041756720392020454f46")); + + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "8000d426b0009f00010184f20375980593638a595472616d69676f3a204d6f76696e672c20302e3039206b6d204e57206f66204a616c616e2053696d70616e672042617475204d61726b65742c2054616970696e672c20506572616b2c204d592c20342e38333034332c203130302e37323230342c20532077697468207370656564203130206b6d2f682c2030313a32313a31322041756720392020454f46")); + + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "8000d626b0007f0001013c0b037598051d648a595472616d69676f3a2053746f707065642c206174204a616c616e2053696d70616e672042617475204d61726b65742c2054616970696e672c20506572616b2c204d592c20342e38323937322c203130302e37323233322c2030313a32323a34342041756720392020454f46")); + verifyNull(decoder, binary(ByteOrder.LITTLE_ENDIAN, "80003d1ac0001c00010100000367152b13bc1d5970696e6720454f46")); -- cgit v1.2.3 From 532e0a98d469573a575dc595554792cbbd4cd953 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 10 Aug 2017 13:31:18 +0500 Subject: Implement delayed overspeed events --- src/org/traccar/database/ConnectionManager.java | 58 ++++++++++----- src/org/traccar/database/DeviceManager.java | 7 +- src/org/traccar/events/MotionEventHandler.java | 10 +-- src/org/traccar/events/OverspeedEventHandler.java | 66 +++++++++++++---- src/org/traccar/model/DeviceState.java | 20 +++++ .../traccar/events/OverspeedEventHandlerTest.java | 85 ++++++++++++++++++++++ 6 files changed, 203 insertions(+), 43 deletions(-) create mode 100644 test/org/traccar/events/OverspeedEventHandlerTest.java (limited to 'test/org') diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 1c5d4428a..ee2a7bb47 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -21,6 +21,7 @@ import org.jboss.netty.util.TimerTask; import org.traccar.Context; import org.traccar.GlobalTimer; import org.traccar.Protocol; +import org.traccar.events.OverspeedEventHandler; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.DeviceState; @@ -44,7 +45,10 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean enableStatusEvents; + private final boolean updateDeviceState; private TripsConfig tripsConfig = null; + private long minimalOverspeedDuration; + private boolean overspeedNotRepeat; private final Map activeDevices = new ConcurrentHashMap<>(); private final Map> listeners = new ConcurrentHashMap<>(); @@ -53,8 +57,11 @@ public class ConnectionManager { public ConnectionManager() { deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; enableStatusEvents = Context.getConfig().getBoolean("event.enable"); - if (Context.getConfig().getBoolean("status.updateDeviceState")) { + updateDeviceState = Context.getConfig().getBoolean("status.updateDeviceState"); + if (updateDeviceState) { tripsConfig = ReportUtils.initTripsConfig(); + minimalOverspeedDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; + overspeedNotRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat"); } } @@ -87,28 +94,24 @@ public class ConnectionManager { if (enableStatusEvents && !status.equals(oldStatus)) { String eventType; - Event stateEvent = null; + Set events = new HashSet<>(); switch (status) { case Device.STATUS_ONLINE: eventType = Event.TYPE_DEVICE_ONLINE; break; case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; - if (tripsConfig != null) { - stateEvent = updateDeviceState(deviceId); + if (updateDeviceState) { + events.addAll(updateDeviceState(deviceId)); } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; - if (tripsConfig != null) { - stateEvent = updateDeviceState(deviceId); + if (updateDeviceState) { + events.addAll(updateDeviceState(deviceId)); } break; } - Set events = new HashSet<>(); - if (stateEvent != null) { - events.add(stateEvent); - } events.add(new Event(eventType, deviceId)); Context.getNotificationManager().updateEvents(events, null); } @@ -142,26 +145,41 @@ public class ConnectionManager { updateDevice(device); } - public Event updateDeviceState(long deviceId) { + public Set updateDeviceState(long deviceId) { DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - if (deviceState == null || deviceState.getMotionState() == null) { - return null; - } - Event result = null; - Boolean oldMotion = deviceState.getMotionState(); + Set result = new HashSet<>(); long currentTime = System.currentTimeMillis(); - boolean newMotion = !oldMotion; - Position motionPosition = deviceState.getMotionPosition(); - if (motionPosition != null) { + if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { + boolean newMotion = !deviceState.getMotionState(); + Position motionPosition = deviceState.getMotionPosition(); long motionTime = motionPosition.getFixTime().getTime() + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); if (motionTime <= currentTime) { String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - result = new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId()); + result.add(new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId())); deviceState.setMotionState(newMotion); deviceState.setMotionPosition(null); } } + if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() + && deviceState.getOverspeedPosition() != null) { + double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, + OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false); + if (speedLimit != 0) { + Position overspeedPosition = deviceState.getOverspeedPosition(); + long overspeedTime = overspeedPosition.getFixTime().getTime(); + if (overspeedTime + minimalOverspeedDuration <= currentTime) { + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), + overspeedPosition.getId()); + event.set("speed", overspeedPosition.getSpeed()); + event.set(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, speedLimit); + result.add(event); + deviceState.setOverspeedState(overspeedNotRepeat); + deviceState.setOverspeedPosition(null); + } + } + } + return result; } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 3b7e5c617..a485d6dc6 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -392,7 +392,12 @@ public class DeviceManager extends BaseObjectManager implements Identity } public DeviceState getDeviceState(long deviceId) { - return deviceStates.get(deviceId); + DeviceState deviceState = deviceStates.get(deviceId); + if (deviceState == null) { + deviceState = new DeviceState(); + deviceStates.put(deviceId, deviceState); + } + return deviceState; } public void setDeviceState(long deviceId, DeviceState deviceState) { diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index 228b43c0f..ed21d7b83 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -77,7 +77,8 @@ public class MotionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getById(position.getDeviceId()); + long deviceId = position.getDeviceId(); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return null; } @@ -86,14 +87,9 @@ public class MotionEventHandler extends BaseEventHandler { } Event result = null; - - long deviceId = position.getDeviceId(); DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - if (deviceState == null) { - deviceState = new DeviceState(); - deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); - } else if (deviceState.getMotionState() == null) { + if (deviceState.getMotionState() == null) { deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); } else { result = updateMotionState(deviceState, position, tripsConfig); diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 795892f40..3b91fed4d 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -21,6 +21,7 @@ import java.util.Collections; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; +import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; @@ -29,15 +30,51 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private boolean notRepeat; + private long minimalDuration; public OverspeedEventHandler() { notRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat"); + minimalDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; + } + + public static Event updateOverspeedState(DeviceState deviceState, Position position, double speedLimit, + long minimalOverspeedDuration, boolean notRepeat) { + Event 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); + } + } else if (oldOverspeed && !newOverspeed) { + deviceState.setOverspeedState(false); + deviceState.setOverspeedPosition(null); + } else { + deviceState.setOverspeedPosition(null); + } + Position overspeedPosition = deviceState.getOverspeedPosition(); + if (overspeedPosition != null) { + long overspeedTime = overspeedPosition.getFixTime().getTime(); + if (newOverspeed && overspeedTime + minimalOverspeedDuration <= currentTime) { + result = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), + overspeedPosition.getId()); + result.set("speed", overspeedPosition.getSpeed()); + result.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + deviceState.setOverspeedState(notRepeat); + deviceState.setOverspeedPosition(null); + } + } + return result; } @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getById(position.getDeviceId()); + long deviceId = position.getDeviceId(); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return null; } @@ -45,24 +82,23 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - double speed = position.getSpeed(); - double speedLimit = Context.getDeviceManager() - .lookupAttributeDouble(device.getId(), ATTRIBUTE_SPEED_LIMIT, 0, false); + double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); if (speedLimit == 0) { return null; } - double oldSpeed = 0; - if (notRepeat) { - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - if (lastPosition != null) { - oldSpeed = lastPosition.getSpeed(); - } + + Event result = null; + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + + if (deviceState.getOverspeedState() == null) { + deviceState.setOverspeedState(position.getSpeed() > speedLimit); + } else { + result = updateOverspeedState(deviceState, position, speedLimit, minimalDuration, notRepeat); } - if (speed > speedLimit && oldSpeed <= speedLimit) { - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()); - event.set("speed", speed); - event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); - return Collections.singleton(event); + + Context.getDeviceManager().setDeviceState(deviceId, deviceState); + if (result != null) { + return Collections.singleton(result); } return null; } diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java index 3626b9953..f2d0ff614 100644 --- a/src/org/traccar/model/DeviceState.java +++ b/src/org/traccar/model/DeviceState.java @@ -38,4 +38,24 @@ public class DeviceState { return motionPosition; } + private Boolean overspeedState; + + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + } + + public Boolean getOverspeedState() { + return overspeedState; + } + + private Position overspeedPosition; + + public void setOverspeedPosition(Position overspeedPosition) { + this.overspeedPosition = overspeedPosition; + } + + public Position getOverspeedPosition() { + return overspeedPosition; + } + } diff --git a/test/org/traccar/events/OverspeedEventHandlerTest.java b/test/org/traccar/events/OverspeedEventHandlerTest.java new file mode 100644 index 000000000..25bbb4319 --- /dev/null +++ b/test/org/traccar/events/OverspeedEventHandlerTest.java @@ -0,0 +1,85 @@ +package org.traccar.events; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.junit.Test; +import org.traccar.BaseTest; +import org.traccar.model.DeviceState; +import org.traccar.model.Event; +import org.traccar.model.Position; + +public class OverspeedEventHandlerTest extends BaseTest { + + private Date date(String time) throws ParseException { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.parse(time); + } + + private void testOverspeed(boolean notRepeat) throws Exception { + Position position = new Position(); + position.setTime(date("2017-01-01 00:00:00")); + position.setSpeed(50); + DeviceState deviceState = new DeviceState(); + deviceState.setOverspeedState(false); + + Event event = OverspeedEventHandler.updateOverspeedState(deviceState, position, 40, 15000, notRepeat); + assertNull(event); + assertFalse(deviceState.getOverspeedState()); + assertEquals(position, deviceState.getOverspeedPosition()); + + Position nextPosition = new Position(); + nextPosition.setTime(date("2017-01-01 00:00:10")); + nextPosition.setSpeed(55); + + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNull(event); + + nextPosition.setTime(date("2017-01-01 00:00:20")); + + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); + assertEquals(50, event.getDouble("speed"), 0.1); + assertEquals(40, event.getDouble(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT), 0.1); + + assertEquals(notRepeat, deviceState.getOverspeedState()); + assertNull(deviceState.getOverspeedPosition()); + + nextPosition.setTime(date("2017-01-01 00:00:30")); + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNull(event); + assertEquals(notRepeat, deviceState.getOverspeedState()); + + if (notRepeat) { + assertNull(deviceState.getOverspeedPosition()); + } else { + assertNotNull(deviceState.getOverspeedPosition()); + } + + nextPosition.setTime(date("2017-01-01 00:00:40")); + nextPosition.setSpeed(30); + + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNull(event); + assertFalse(deviceState.getOverspeedState()); + assertNull(deviceState.getOverspeedPosition()); + } + + @Test + public void testOverspeedEventHandler() throws Exception { + testOverspeed(false); + testOverspeed(true); + } + +} -- cgit v1.2.3 From 3562e0d927d539a1e9730c48ed376ee84ebc2b25 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 11 Aug 2017 05:03:26 +1200 Subject: Fix GL300VC decoding issue --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 6 +----- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 63adb1c70..37793a6ff 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -76,7 +76,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(?:d),") // led .number("(?:d)?,") // gps on need .number("(?:d)?,") // gps antenna type - .number("(?:d),").optional() // gps antenna state + .number("(?:d)?,").optional() // gps antenna state .number("d{14},") // last fix time .groupBegin() .number("(d+),") // battery percentage @@ -388,10 +388,6 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { - - org.traccar.helper.PatternUtil.MatchResult matchResult = - org.traccar.helper.PatternUtil.checkPattern(PATTERN_INF.pattern(), sentence); - Parser parser = new Parser(PATTERN_INF, sentence); Position position = initPosition(parser, channel, remoteAddress); if (position == null) { diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 9e2571916..ac58049df 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "+RESP:GTINF,280500,A1000043D20139,GL300VC,41,,31,0,0,,,3.87,0,1,1,,,20170802150751,70,,48.0,,,20170802112145,03AC$")); verifyAttributes(decoder, buffer( -- cgit v1.2.3 From 2e459d8d591ee9d3578a38d981e7c1c13eb3c389 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 11 Aug 2017 09:22:53 +0500 Subject: Move state updates from ConnectionManager to proper event handlers --- src/org/traccar/database/ConnectionManager.java | 40 ++++++---------------- src/org/traccar/events/MotionEventHandler.java | 18 ++++++++++ src/org/traccar/events/OverspeedEventHandler.java | 20 +++++++++++ .../org/traccar/events/MotionEventHandlerTest.java | 21 +++++++++++- .../traccar/events/OverspeedEventHandlerTest.java | 30 ++++++++++++---- 5 files changed, 93 insertions(+), 36 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index ee2a7bb47..b1dd1b726 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -21,6 +21,7 @@ import org.jboss.netty.util.TimerTask; import org.traccar.Context; import org.traccar.GlobalTimer; import org.traccar.Protocol; +import org.traccar.events.MotionEventHandler; import org.traccar.events.OverspeedEventHandler; import org.traccar.helper.Log; import org.traccar.model.Device; @@ -148,36 +149,17 @@ public class ConnectionManager { public Set updateDeviceState(long deviceId) { DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); Set result = new HashSet<>(); - long currentTime = System.currentTimeMillis(); - if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { - boolean newMotion = !deviceState.getMotionState(); - Position motionPosition = deviceState.getMotionPosition(); - long motionTime = motionPosition.getFixTime().getTime() - + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); - if (motionTime <= currentTime) { - String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - result.add(new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId())); - deviceState.setMotionState(newMotion); - deviceState.setMotionPosition(null); - } + + Event event = MotionEventHandler.updateMotionState(deviceState, tripsConfig); + if (event != null) { + result.add(event); } - if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() - && deviceState.getOverspeedPosition() != null) { - double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, - OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false); - if (speedLimit != 0) { - Position overspeedPosition = deviceState.getOverspeedPosition(); - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (overspeedTime + minimalOverspeedDuration <= currentTime) { - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), - overspeedPosition.getId()); - event.set("speed", overspeedPosition.getSpeed()); - event.set(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, speedLimit); - result.add(event); - deviceState.setOverspeedState(overspeedNotRepeat); - deviceState.setOverspeedPosition(null); - } - } + + event = OverspeedEventHandler.updateOverspeedState(deviceState, Context.getDeviceManager(). + lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false), + minimalOverspeedDuration, overspeedNotRepeat); + if (event != null) { + result.add(event); } return result; diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index ed21d7b83..1a8cb0ef8 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -36,6 +36,24 @@ public class MotionEventHandler extends BaseEventHandler { tripsConfig = ReportUtils.initTripsConfig(); } + public static Event updateMotionState(DeviceState deviceState, TripsConfig tripsConfig) { + Event 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) { + String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + result = new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId()); + deviceState.setMotionState(newMotion); + deviceState.setMotionPosition(null); + } + } + return result; + } + public static Event updateMotionState(DeviceState deviceState, Position position, TripsConfig tripsConfig) { Event result = null; Boolean oldMotion = deviceState.getMotionState(); diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 3b91fed4d..f0bf8a032 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -37,6 +37,26 @@ public class OverspeedEventHandler extends BaseEventHandler { minimalDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; } + public static Event updateOverspeedState(DeviceState deviceState, double speedLimit, + long minimalDuration, boolean notRepeat) { + Event 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 = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), + overspeedPosition.getId()); + result.set("speed", overspeedPosition.getSpeed()); + result.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + deviceState.setOverspeedState(notRepeat); + deviceState.setOverspeedPosition(null); + } + } + return result; + } + public static Event updateOverspeedState(DeviceState deviceState, Position position, double speedLimit, long minimalOverspeedDuration, boolean notRepeat) { Event result = null; diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index c44f3f4eb..9df573244 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -27,7 +27,7 @@ public class MotionEventHandlerTest extends BaseTest { } @Test - public void testMotionEventHandler() throws Exception { + public void testMotionWithPosition() throws Exception { TripsConfig tripsConfig = new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0); Position position = new Position(); @@ -64,4 +64,23 @@ public class MotionEventHandlerTest extends BaseTest { assertNull(deviceState.getMotionPosition()); } + @Test + public void testMotionWithStatus() throws Exception { + TripsConfig tripsConfig = new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0); + + Position position = new Position(); + position.setTime(new Date(System.currentTimeMillis() - 360000)); + position.set(Position.KEY_MOTION, true); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(false); + deviceState.setMotionPosition(position); + + Event event = MotionEventHandler.updateMotionState(deviceState, tripsConfig); + + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); + assertTrue(deviceState.getMotionState()); + assertNull(deviceState.getMotionPosition()); + } + } diff --git a/test/org/traccar/events/OverspeedEventHandlerTest.java b/test/org/traccar/events/OverspeedEventHandlerTest.java index 25bbb4319..eae0917c0 100644 --- a/test/org/traccar/events/OverspeedEventHandlerTest.java +++ b/test/org/traccar/events/OverspeedEventHandlerTest.java @@ -2,7 +2,6 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -26,7 +25,7 @@ public class OverspeedEventHandlerTest extends BaseTest { return dateFormat.parse(time); } - private void testOverspeed(boolean notRepeat) throws Exception { + private void testOverspeedWithPosition(boolean notRepeat) throws Exception { Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); position.setSpeed(50); @@ -55,12 +54,12 @@ public class OverspeedEventHandlerTest extends BaseTest { assertEquals(notRepeat, deviceState.getOverspeedState()); assertNull(deviceState.getOverspeedPosition()); - + nextPosition.setTime(date("2017-01-01 00:00:30")); event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); assertNull(event); assertEquals(notRepeat, deviceState.getOverspeedState()); - + if (notRepeat) { assertNull(deviceState.getOverspeedPosition()); } else { @@ -76,10 +75,29 @@ public class OverspeedEventHandlerTest extends BaseTest { assertNull(deviceState.getOverspeedPosition()); } + private void testOverspeedWithStatus(boolean notRepeat) throws Exception { + Position position = new Position(); + position.setTime(new Date(System.currentTimeMillis() - 30000)); + position.setSpeed(50); + DeviceState deviceState = new DeviceState(); + deviceState.setOverspeedState(false); + deviceState.setOverspeedPosition(position); + + Event event = OverspeedEventHandler.updateOverspeedState(deviceState, 40, 15000, notRepeat); + + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); + assertEquals(notRepeat, deviceState.getOverspeedState()); + + } + @Test public void testOverspeedEventHandler() throws Exception { - testOverspeed(false); - testOverspeed(true); + testOverspeedWithPosition(false); + testOverspeedWithPosition(true); + + testOverspeedWithStatus(false); + testOverspeedWithStatus(true); } } -- cgit v1.2.3 From 32a0fee0b092e488662ed29b7b7f1f303ae57e0f Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 11 Aug 2017 15:06:09 +0500 Subject: Make Overspeed and Motion events handlers singleton and move some code to function --- src/org/traccar/BasePipelineFactory.java | 4 +-- src/org/traccar/Context.java | 20 +++++++++++ src/org/traccar/database/ConnectionManager.java | 18 ++-------- src/org/traccar/events/MotionEventHandler.java | 34 +++++++++--------- src/org/traccar/events/OverspeedEventHandler.java | 40 ++++++++++------------ .../org/traccar/events/MotionEventHandlerTest.java | 14 ++++---- .../traccar/events/OverspeedEventHandlerTest.java | 17 +++++---- 7 files changed, 79 insertions(+), 68 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index b368c800d..da8060071 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -165,9 +165,9 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { if (Context.getConfig().getBoolean("event.enable")) { commandResultEventHandler = new CommandResultEventHandler(); - overspeedEventHandler = new OverspeedEventHandler(); + overspeedEventHandler = Context.getOverspeedEventHandler(); fuelDropEventHandler = new FuelDropEventHandler(); - motionEventHandler = new MotionEventHandler(); + motionEventHandler = Context.getMotionEventHandler(); geofenceEventHandler = new GeofenceEventHandler(); alertEventHandler = new AlertEventHandler(); ignitionEventHandler = new IgnitionEventHandler(); diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 306a37e83..4bcc1468b 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -41,6 +41,8 @@ import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.StatisticsManager; import org.traccar.database.UsersManager; +import org.traccar.events.MotionEventHandler; +import org.traccar.events.OverspeedEventHandler; import org.traccar.geocoder.BingMapsGeocoder; import org.traccar.geocoder.FactualGeocoder; import org.traccar.geocoder.GeocodeFarmGeocoder; @@ -65,6 +67,7 @@ import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.notification.EventForwarder; +import org.traccar.reports.ReportUtils; import org.traccar.smpp.SmppClient; import org.traccar.web.WebServer; @@ -229,6 +232,18 @@ public final class Context { return smppClient; } + private static MotionEventHandler motionEventHandler; + + public static MotionEventHandler getMotionEventHandler() { + return motionEventHandler; + } + + private static OverspeedEventHandler overspeedEventHandler; + + public static OverspeedEventHandler getOverspeedEventHandler() { + return overspeedEventHandler; + } + public static void init(String[] arguments) throws Exception { config = new Config(); @@ -350,6 +365,11 @@ public final class Context { velocityEngine = new VelocityEngine(); velocityEngine.init(velocityProperties); + + motionEventHandler = new MotionEventHandler(ReportUtils.initTripsConfig()); + overspeedEventHandler = new OverspeedEventHandler( + Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000, + Context.getConfig().getBoolean("event.overspeed.notRepeat")); } serverManager = new ServerManager(); diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index b1dd1b726..7a0a6d30d 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -21,15 +21,12 @@ import org.jboss.netty.util.TimerTask; import org.traccar.Context; import org.traccar.GlobalTimer; import org.traccar.Protocol; -import org.traccar.events.MotionEventHandler; import org.traccar.events.OverspeedEventHandler; import org.traccar.helper.Log; 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 java.net.SocketAddress; import java.sql.SQLException; @@ -47,9 +44,6 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean enableStatusEvents; private final boolean updateDeviceState; - private TripsConfig tripsConfig = null; - private long minimalOverspeedDuration; - private boolean overspeedNotRepeat; private final Map activeDevices = new ConcurrentHashMap<>(); private final Map> listeners = new ConcurrentHashMap<>(); @@ -59,11 +53,6 @@ public class ConnectionManager { deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; enableStatusEvents = Context.getConfig().getBoolean("event.enable"); updateDeviceState = Context.getConfig().getBoolean("status.updateDeviceState"); - if (updateDeviceState) { - tripsConfig = ReportUtils.initTripsConfig(); - minimalOverspeedDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; - overspeedNotRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat"); - } } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { @@ -150,14 +139,13 @@ public class ConnectionManager { DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); Set result = new HashSet<>(); - Event event = MotionEventHandler.updateMotionState(deviceState, tripsConfig); + Event event = Context.getMotionEventHandler().updateMotionState(deviceState); if (event != null) { result.add(event); } - event = OverspeedEventHandler.updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false), - minimalOverspeedDuration, overspeedNotRepeat); + event = Context.getOverspeedEventHandler().updateOverspeedState(deviceState, Context.getDeviceManager(). + lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false)); if (event != null) { result.add(event); } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index 1a8cb0ef8..b20a11999 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -32,11 +32,20 @@ public class MotionEventHandler extends BaseEventHandler { private TripsConfig tripsConfig; - public MotionEventHandler() { - tripsConfig = ReportUtils.initTripsConfig(); + public MotionEventHandler(TripsConfig tripsConfig) { + this.tripsConfig = tripsConfig; } - public static Event updateMotionState(DeviceState deviceState, TripsConfig tripsConfig) { + private Event newEvent(DeviceState deviceState, boolean newMotion) { + String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + Event event = new Event(eventType, deviceState.getMotionPosition().getDeviceId(), + deviceState.getMotionPosition().getId()); + deviceState.setMotionState(newMotion); + deviceState.setMotionPosition(null); + return event; + } + + public Event updateMotionState(DeviceState deviceState) { Event result = null; if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { boolean newMotion = !deviceState.getMotionState(); @@ -45,16 +54,13 @@ public class MotionEventHandler extends BaseEventHandler { long motionTime = motionPosition.getFixTime().getTime() + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); if (motionTime <= currentTime) { - String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - result = new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId()); - deviceState.setMotionState(newMotion); - deviceState.setMotionPosition(null); + result = newEvent(deviceState, newMotion); } } return result; } - public static Event updateMotionState(DeviceState deviceState, Position position, TripsConfig tripsConfig) { + public Event updateMotionState(DeviceState deviceState, Position position) { Event result = null; Boolean oldMotion = deviceState.getMotionState(); @@ -75,17 +81,11 @@ public class MotionEventHandler extends BaseEventHandler { if (newMotion) { if (motionTime + tripsConfig.getMinimalTripDuration() <= currentTime || distance >= tripsConfig.getMinimalTripDistance()) { - result = new Event(Event.TYPE_DEVICE_MOVING, motionPosition.getDeviceId(), - motionPosition.getId()); - deviceState.setMotionState(true); - deviceState.setMotionPosition(null); + result = newEvent(deviceState, newMotion); } } else { if (motionTime + tripsConfig.getMinimalParkingDuration() <= currentTime) { - result = new Event(Event.TYPE_DEVICE_STOPPED, motionPosition.getDeviceId(), - motionPosition.getId()); - deviceState.setMotionState(false); - deviceState.setMotionPosition(null); + result = newEvent(deviceState, newMotion); } } } @@ -110,7 +110,7 @@ public class MotionEventHandler extends BaseEventHandler { if (deviceState.getMotionState() == null) { deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); } else { - result = updateMotionState(deviceState, position, tripsConfig); + result = updateMotionState(deviceState, position); } Context.getDeviceManager().setDeviceState(deviceId, deviceState); if (result != null) { diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index f0bf8a032..953af6b33 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -32,13 +32,22 @@ public class OverspeedEventHandler extends BaseEventHandler { private boolean notRepeat; private long minimalDuration; - public OverspeedEventHandler() { - notRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat"); - minimalDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; + public OverspeedEventHandler(long minimalDuration, boolean notRepeat) { + this.notRepeat = notRepeat; + this.minimalDuration = minimalDuration; } - public static Event updateOverspeedState(DeviceState deviceState, double speedLimit, - long minimalDuration, boolean notRepeat) { + private Event newEvent(DeviceState deviceState, double speedLimit) { + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, deviceState.getOverspeedPosition().getDeviceId(), + deviceState.getOverspeedPosition().getId()); + event.set("speed", deviceState.getOverspeedPosition().getSpeed()); + event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + deviceState.setOverspeedState(notRepeat); + deviceState.setOverspeedPosition(null); + return event; + } + + public Event updateOverspeedState(DeviceState deviceState, double speedLimit) { Event result = null; if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() && deviceState.getOverspeedPosition() != null && speedLimit != 0) { @@ -46,19 +55,13 @@ public class OverspeedEventHandler extends BaseEventHandler { Position overspeedPosition = deviceState.getOverspeedPosition(); long overspeedTime = overspeedPosition.getFixTime().getTime(); if (overspeedTime + minimalDuration <= currentTime) { - result = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), - overspeedPosition.getId()); - result.set("speed", overspeedPosition.getSpeed()); - result.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); - deviceState.setOverspeedState(notRepeat); - deviceState.setOverspeedPosition(null); + result = newEvent(deviceState, speedLimit); } } return result; } - public static Event updateOverspeedState(DeviceState deviceState, Position position, double speedLimit, - long minimalOverspeedDuration, boolean notRepeat) { + public Event updateOverspeedState(DeviceState deviceState, Position position, double speedLimit) { Event result = null; Boolean oldOverspeed = deviceState.getOverspeedState(); @@ -78,13 +81,8 @@ public class OverspeedEventHandler extends BaseEventHandler { Position overspeedPosition = deviceState.getOverspeedPosition(); if (overspeedPosition != null) { long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (newOverspeed && overspeedTime + minimalOverspeedDuration <= currentTime) { - result = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), - overspeedPosition.getId()); - result.set("speed", overspeedPosition.getSpeed()); - result.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); - deviceState.setOverspeedState(notRepeat); - deviceState.setOverspeedPosition(null); + if (newOverspeed && overspeedTime + minimalDuration <= currentTime) { + result = newEvent(deviceState, speedLimit); } } return result; @@ -113,7 +111,7 @@ public class OverspeedEventHandler extends BaseEventHandler { if (deviceState.getOverspeedState() == null) { deviceState.setOverspeedState(position.getSpeed() > speedLimit); } else { - result = updateOverspeedState(deviceState, position, speedLimit, minimalDuration, notRepeat); + result = updateOverspeedState(deviceState, position, speedLimit); } Context.getDeviceManager().setDeviceState(deviceId, deviceState); diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index 9df573244..6b7b9daee 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -28,7 +28,8 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws Exception { - TripsConfig tripsConfig = new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0); + MotionEventHandler motionEventHandler = new MotionEventHandler( + new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -43,11 +44,11 @@ public class MotionEventHandlerTest extends BaseTest { nextPosition.set(Position.KEY_MOTION, true); nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - Event event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + Event event = motionEventHandler.updateMotionState(deviceState, nextPosition); assertNull(event); nextPosition.set(Position.KEY_TOTAL_DISTANCE, 600); - event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + event = motionEventHandler.updateMotionState(deviceState, nextPosition); assertNotNull(event); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); assertTrue(deviceState.getMotionState()); @@ -57,7 +58,7 @@ public class MotionEventHandlerTest extends BaseTest { deviceState.setMotionPosition(position); nextPosition.setTime(date("2017-01-01 00:06:00")); nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + event = motionEventHandler.updateMotionState(deviceState, nextPosition); assertNotNull(event); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); assertTrue(deviceState.getMotionState()); @@ -66,7 +67,8 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithStatus() throws Exception { - TripsConfig tripsConfig = new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0); + MotionEventHandler motionEventHandler = new MotionEventHandler( + new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 360000)); @@ -75,7 +77,7 @@ public class MotionEventHandlerTest extends BaseTest { deviceState.setMotionState(false); deviceState.setMotionPosition(position); - Event event = MotionEventHandler.updateMotionState(deviceState, tripsConfig); + Event event = motionEventHandler.updateMotionState(deviceState); assertNotNull(event); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); diff --git a/test/org/traccar/events/OverspeedEventHandlerTest.java b/test/org/traccar/events/OverspeedEventHandlerTest.java index eae0917c0..48d7445ff 100644 --- a/test/org/traccar/events/OverspeedEventHandlerTest.java +++ b/test/org/traccar/events/OverspeedEventHandlerTest.java @@ -26,13 +26,15 @@ public class OverspeedEventHandlerTest extends BaseTest { } private void testOverspeedWithPosition(boolean notRepeat) throws Exception { + OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(15000, notRepeat); + Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); position.setSpeed(50); DeviceState deviceState = new DeviceState(); deviceState.setOverspeedState(false); - Event event = OverspeedEventHandler.updateOverspeedState(deviceState, position, 40, 15000, notRepeat); + Event event = overspeedEventHandler.updateOverspeedState(deviceState, position, 40); assertNull(event); assertFalse(deviceState.getOverspeedState()); assertEquals(position, deviceState.getOverspeedPosition()); @@ -41,12 +43,12 @@ public class OverspeedEventHandlerTest extends BaseTest { nextPosition.setTime(date("2017-01-01 00:00:10")); nextPosition.setSpeed(55); - event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); assertNull(event); nextPosition.setTime(date("2017-01-01 00:00:20")); - event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); assertNotNull(event); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(50, event.getDouble("speed"), 0.1); @@ -56,7 +58,7 @@ public class OverspeedEventHandlerTest extends BaseTest { assertNull(deviceState.getOverspeedPosition()); nextPosition.setTime(date("2017-01-01 00:00:30")); - event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); assertNull(event); assertEquals(notRepeat, deviceState.getOverspeedState()); @@ -69,13 +71,15 @@ public class OverspeedEventHandlerTest extends BaseTest { nextPosition.setTime(date("2017-01-01 00:00:40")); nextPosition.setSpeed(30); - event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); assertNull(event); assertFalse(deviceState.getOverspeedState()); assertNull(deviceState.getOverspeedPosition()); } private void testOverspeedWithStatus(boolean notRepeat) throws Exception { + OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(15000, notRepeat); + Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 30000)); position.setSpeed(50); @@ -83,12 +87,11 @@ public class OverspeedEventHandlerTest extends BaseTest { deviceState.setOverspeedState(false); deviceState.setOverspeedPosition(position); - Event event = OverspeedEventHandler.updateOverspeedState(deviceState, 40, 15000, notRepeat); + Event event = overspeedEventHandler.updateOverspeedState(deviceState, 40); assertNotNull(event); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(notRepeat, deviceState.getOverspeedState()); - } @Test -- cgit v1.2.3 From 8313471a752dc08e5e7a270349e9f03417672b08 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 14 Aug 2017 14:43:17 +0500 Subject: Correct motion state by ignition. --- src/org/traccar/Context.java | 3 ++- src/org/traccar/events/MotionEventHandler.java | 8 +++++- src/org/traccar/reports/model/TripsConfig.java | 15 +++++++++-- .../org/traccar/events/MotionEventHandlerTest.java | 30 ++++++++++++++++++++-- test/org/traccar/reports/ReportUtilsTest.java | 12 ++++----- 5 files changed, 56 insertions(+), 12 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index a69b1786d..61000172e 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -256,7 +256,8 @@ public final class Context { config.getLong("report.trip.minimalTripDuration", 300) * 1000, config.getLong("report.trip.minimalParkingDuration", 300) * 1000, config.getBoolean("report.trip.greedyParking"), - config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000); + config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000, + config.getBoolean("report.trip.stopOnIgnitionOff")); } public static void init(String[] arguments) throws Exception { diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index b20a11999..208fd5b42 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -78,13 +78,19 @@ public class MotionEventHandler extends BaseEventHandler { if (motionPosition != null) { long motionTime = motionPosition.getFixTime().getTime(); double distance = ReportUtils.calculateDistance(motionPosition, position, false); + Boolean ignition = null; + if (tripsConfig.getStopOnIgnitionOff() + && 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) { + if (motionTime + tripsConfig.getMinimalParkingDuration() <= currentTime + || ignition != null && !ignition) { result = newEvent(deviceState, newMotion); } } diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java index 7067781d7..039094b89 100644 --- a/src/org/traccar/reports/model/TripsConfig.java +++ b/src/org/traccar/reports/model/TripsConfig.java @@ -21,13 +21,14 @@ public class TripsConfig { public TripsConfig() { } - public TripsConfig(double minimalTripDistance, long minimalTripDuration, - long minimalParkingDuration, boolean greedyParking, long minimalNoDataDuration) { + public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, + boolean greedyParking, long minimalNoDataDuration, boolean stopOnIgnitionOff) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; this.greedyParking = greedyParking; this.minimalNoDataDuration = minimalNoDataDuration; + this.stopOnIgnitionOff = stopOnIgnitionOff; } private double minimalTripDistance; @@ -80,4 +81,14 @@ public class TripsConfig { this.minimalNoDataDuration = minimalNoDataDuration; } + private boolean stopOnIgnitionOff; + + public boolean getStopOnIgnitionOff() { + return stopOnIgnitionOff; + } + + public void setStopOnIgnitionOff(boolean stopOnIgnitionOff) { + this.stopOnIgnitionOff = stopOnIgnitionOff; + } + } diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index 6b7b9daee..826f4c4e5 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -1,6 +1,7 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -29,7 +30,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); + new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0, false)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -68,7 +69,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithStatus() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); + new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0, false)); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 360000)); @@ -85,4 +86,29 @@ public class MotionEventHandlerTest extends BaseTest { assertNull(deviceState.getMotionPosition()); } + @Test + public void testStopWithPositionIgnition() throws Exception { + MotionEventHandler motionEventHandler = new MotionEventHandler( + new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0, true)); + + Position position = new Position(); + position.setTime(date("2017-01-01 00:00:00")); + position.set(Position.KEY_MOTION, false); + position.set(Position.KEY_IGNITION, true); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(true); + deviceState.setMotionPosition(position); + + Position nextPosition = new Position(); + nextPosition.setTime(date("2017-01-01 00:02:00")); + nextPosition.set(Position.KEY_MOTION, false); + nextPosition.set(Position.KEY_IGNITION, false); + + Event event = motionEventHandler.updateMotionState(deviceState, nextPosition); + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_STOPPED, event.getType()); + assertFalse(deviceState.getMotionState()); + assertNull(deviceState.getMotionPosition()); + } + } diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index adcdf5875..8fc1e6e53 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -79,7 +79,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:06:00.000", 0, 3000), position("2016-01-01 00:07:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, false, 900000, false); Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, true); @@ -119,7 +119,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000, false); Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); @@ -145,7 +145,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000, false); Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); @@ -184,7 +184,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 0, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000, false); Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); @@ -210,7 +210,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000, false); Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); @@ -232,7 +232,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, false, 900000, false); Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, true); -- cgit v1.2.3 From 8012240ac5662d8b0a2ec7907ad3f04e86b17627 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 15 Aug 2017 07:39:46 +1200 Subject: Add VT200 trip message support --- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 58 +++++++++++++++++++--- .../traccar/protocol/Vt200ProtocolDecoderTest.java | 7 ++- 2 files changed, 57 insertions(+), 8 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index 111c29313..6be70c3c1 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -27,6 +27,8 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; +import java.util.Arrays; +import java.util.Date; public class Vt200ProtocolDecoder extends BaseProtocolDecoder { @@ -40,6 +42,13 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes * 0.0001 / 60; } + protected Date decodeDate(ChannelBuffer buf) { + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)) + .setTime(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); + return dateBuilder.getDate(); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -66,12 +75,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // data type buf.readUnsignedShort(); // trip id - DateBuilder dateBuilder = new DateBuilder(); - dateBuilder.setDateReverse( - BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); - dateBuilder.setTime( - BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); + position.setTime(decodeDate(buf)); position.setLatitude(decodeCoordinate(BcdUtil.readInteger(buf, 8))); position.setLongitude(decodeCoordinate(BcdUtil.readInteger(buf, 9))); @@ -97,6 +101,48 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == 0x3088) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + buf.readUnsignedShort(); // trip id + buf.skipBytes(8); // imei + buf.skipBytes(8); // imsi + + position.set("tripStart", decodeDate(buf).getTime()); + position.set("tripEnd", decodeDate(buf).getTime()); + position.set("drivingTime", buf.readUnsignedShort()); + + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); + + position.set("maxSpeed", UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + position.set("maxRpm", buf.readUnsignedShort()); + position.set("maxTemp", buf.readUnsignedByte() - 40); + position.set("hardAccelerationCount", buf.readUnsignedByte()); + position.set("hardBreakingCount", buf.readUnsignedByte()); + + for (String speedType : Arrays.asList("over", "high", "normal", "low")) { + position.set(speedType + "SpeedTime", buf.readUnsignedShort()); + position.set(speedType + "SpeedDistance", buf.readUnsignedInt()); + position.set(speedType + "SpeedFuel", buf.readUnsignedInt()); + } + + position.set("idleTime", buf.readUnsignedShort()); + position.set("idleFuel", buf.readUnsignedInt()); + + position.set("hardCorneringCount", buf.readUnsignedByte()); + position.set("overspeedCount", buf.readUnsignedByte()); + position.set("overheatCount", buf.readUnsignedShort()); + position.set("laneChangeCount", buf.readUnsignedByte()); + position.set("emergencyRefueling", buf.readUnsignedByte()); + + return position; + } return null; diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index 37d9c46d9..42ed4a652 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "286310373094563082002701033d010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); + verifyAttributes(decoder, binary( + "2863103730945630880062033d862631037309456f222014604362936f010817140954010817144135076b00002a3800003b7d6127cc91040000000000000000000000005a0000088e000001ce02630000263b000009b401ff00000cb40000069c02af000018190200000102019729")); + verifyPosition(decoder, binary( "286310373094562086002101033d010817143328441790420114817637207d090a00000847002001207f00d6f229")); @@ -25,7 +28,7 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "28631037309456108800002e29")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "2863103730945630880062033c862631037309456f222014604362936f01081713365601081713571904c800001b2c000034f66827f0840000000000000000000000000047000006e7000001b9022a000023ff000007f2018a00000a10000003f300cd00000d8d0300000302002729")); verifyNull(decoder, binary( @@ -40,7 +43,7 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "286310373094563089001200032f2107171740144417075001147188872c29")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "2863103730945630880062032f862631037309456f222014604362936f21071717373221071717401400a100000cd700000004020d3c8e0000000000000000000000000000000000000000000000000000000000000000000a000000040000000e009700000cc9000000000000e929")); verifyPosition(decoder, binary( -- cgit v1.2.3 From f1ee1017d62ec0d1b6b1ca56c297537870f1d32b Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 14 Aug 2017 15:34:48 +0500 Subject: Reimplement trips detector using MotionEventHandler --- src/org/traccar/reports/ReportUtils.java | 147 ++++++++++++-------------- src/org/traccar/reports/Stops.java | 9 +- src/org/traccar/reports/Trips.java | 9 +- test/org/traccar/reports/ReportUtilsTest.java | 75 ++++++------- 4 files changed, 109 insertions(+), 131 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 8c39bb9dc..91dc2e019 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -26,9 +26,11 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.events.MotionEventHandler; +import org.traccar.model.DeviceState; import org.traccar.model.Driver; +import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; @@ -237,8 +239,11 @@ public final class ReportUtils { private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig, double speedThreshold) { - if (tripsConfig.getMinimalNoDataDuration() > 0 && index < positions.size() - 1 + if (tripsConfig.getMinimalNoDataDuration() > 0 && (index < positions.size() - 1 && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration()) + || index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() >= tripsConfig.getMinimalNoDataDuration()) { return false; } @@ -250,100 +255,80 @@ public final class ReportUtils { } } - public static Collection detectTripsAndStops(TripsConfig tripsConfig, boolean ignoreOdometer, - double speedThreshold, Collection positionCollection, boolean trips) { - - Collection result = new ArrayList<>(); + public static Collection detectTrips(Collection positionCollection, TripsConfig tripsConfig, + boolean ignoreOdometer, double speedThreshold) { + Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); if (positions != null && !positions.isEmpty()) { - int previousStartParkingIndex = 0; + MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); + int startTripIndex = deviceState.getMotionState() ? 0 : -1; int startParkingIndex = -1; - int previousEndParkingIndex = 0; - int endParkingIndex = 0; - - boolean isMoving = false; - boolean isLast = false; - boolean skipped = false; - boolean tripFiltered = false; - for (int i = 0; i < positions.size(); i++) { - isMoving = isMoving(positions, i, tripsConfig, speedThreshold); - isLast = i == positions.size() - 1; - - if ((isMoving || isLast) && startParkingIndex != -1) { - if (!skipped || previousEndParkingIndex == 0) { - previousEndParkingIndex = endParkingIndex; - } - endParkingIndex = i; + positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); + Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); + if (startTripIndex == -1 && !deviceState.getMotionState() && deviceState.getMotionPosition() != null) { + startTripIndex = i; + startParkingIndex = -1; } - if (!isMoving && startParkingIndex == -1) { - if (tripsConfig.getGreedyParking()) { - long tripDuration = positions.get(i).getFixTime().getTime() - - positions.get(endParkingIndex).getFixTime().getTime(); - double tripDistance = ReportUtils.calculateDistance(positions.get(endParkingIndex), - positions.get(i), false); - tripFiltered = tripDuration < tripsConfig.getMinimalTripDuration() - && tripDistance < tripsConfig.getMinimalTripDistance(); - if (tripFiltered) { - startParkingIndex = previousStartParkingIndex; - endParkingIndex = previousEndParkingIndex; - tripFiltered = false; - } else { - previousStartParkingIndex = i; - startParkingIndex = i; - } - } else { - long tripDuration = positions.get(i).getFixTime().getTime() - - positions.get(previousEndParkingIndex).getFixTime().getTime(); - double tripDistance = ReportUtils.calculateDistance(positions.get(previousEndParkingIndex), - positions.get(i), false); - tripFiltered = tripDuration < tripsConfig.getMinimalTripDuration() - && tripDistance < tripsConfig.getMinimalTripDistance(); + if (deviceState.getMotionState()) { + if (startParkingIndex == -1) { startParkingIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startParkingIndex = -1; } } - if (startParkingIndex != -1 && (endParkingIndex > startParkingIndex || isLast)) { - long parkingDuration = positions.get(endParkingIndex).getFixTime().getTime() - - positions.get(startParkingIndex).getFixTime().getTime(); - if ((parkingDuration >= tripsConfig.getMinimalParkingDuration() || isLast) - && previousEndParkingIndex < startParkingIndex) { - if (!tripFiltered) { - if (trips) { - result.add(calculateTrip( - positions, previousEndParkingIndex, startParkingIndex, ignoreOdometer)); - } else { - if (result.isEmpty() && previousEndParkingIndex > previousStartParkingIndex) { - long previousParkingDuration = positions.get(previousEndParkingIndex) - .getFixTime().getTime() - positions.get(previousStartParkingIndex) - .getFixTime().getTime(); - if (previousParkingDuration >= tripsConfig.getMinimalParkingDuration()) { - result.add(calculateStop(positions, previousStartParkingIndex, - previousEndParkingIndex)); - } - } - result.add(calculateStop(positions, startParkingIndex, isLast ? i : endParkingIndex)); - } - } - previousEndParkingIndex = endParkingIndex; - skipped = false; - } else { - skipped = true; + if (startTripIndex != -1 && startParkingIndex != -1 && event != null && !deviceState.getMotionState()) { + result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); + startTripIndex = -1; + } + } + if (startTripIndex != -1 && startParkingIndex != -1) { + result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); + } + } + return result; + } + + public static Collection detectStops(Collection positionCollection, TripsConfig tripsConfig, + boolean ignoreOdometer, double speedThreshold) { + Collection result = new ArrayList<>(); + + ArrayList positions = new ArrayList<>(positionCollection); + if (positions != null && !positions.isEmpty()) { + MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); + int startTripIndex = -1; + int startParkingIndex = deviceState.getMotionState() ? -1 : 0; + for (int i = 0; i < positions.size(); i++) { + boolean isMoving = isMoving(positions, i, tripsConfig, speedThreshold); + positions.get(i).set(Position.KEY_MOTION, isMoving); + Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); + if (startParkingIndex == -1 && deviceState.getMotionState() + && deviceState.getMotionPosition() != null) { + startParkingIndex = i; + startTripIndex = -1; + } + if (!deviceState.getMotionState()) { + if (startTripIndex == -1) { + startTripIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startTripIndex = -1; } + } + if (startParkingIndex != -1 && startTripIndex != -1 && event != null && deviceState.getMotionState()) { + result.add(calculateStop(positions, startParkingIndex, startTripIndex)); startParkingIndex = -1; } } - if (result.isEmpty() && !trips) { - int end = isMoving && !tripsConfig.getGreedyParking() - ? Math.max(endParkingIndex, previousEndParkingIndex) : positions.size() - 1; - long parkingDuration = positions.get(end).getFixTime().getTime() - - positions.get(previousStartParkingIndex).getFixTime().getTime(); - if (parkingDuration >= tripsConfig.getMinimalParkingDuration()) { - result.add(calculateStop(positions, previousStartParkingIndex, end)); - } + if (startParkingIndex != -1) { + result.add(calculateStop(positions, startParkingIndex, + startTripIndex != -1 ? startTripIndex : positions.size() - 1)); } } - return result; } } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 3f7f674b5..68fdef334 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -30,7 +30,6 @@ import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.StopReport; @@ -45,11 +44,11 @@ public final class Stops { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectTripsAndStops( - Context.getTripsConfig(), ignoreOdometer, speedThreshold, - Context.getDataManager().getPositions(deviceId, from, to), false); + Collection result = ReportUtils.detectStops( + Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, speedThreshold); - return (Collection) result; + return result; } public static Collection getObjects( diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index a4dcf00f1..bb39cf493 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -29,7 +29,6 @@ import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.TripReport; @@ -44,11 +43,11 @@ public final class Trips { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectTripsAndStops( - Context.getTripsConfig(), ignoreOdometer, speedThreshold, - Context.getDataManager().getPositions(deviceId, from, to), true); + Collection result = ReportUtils.detectTrips( + Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, speedThreshold); - return (Collection) result; + return result; } public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index adcdf5875..1b552baa3 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -11,13 +11,13 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.Iterator; import java.util.TimeZone; import org.junit.Assert; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; @@ -81,12 +81,12 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, true); + Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(trips); + assertFalse(trips.isEmpty()); - TripReport itemTrip = (TripReport) result.iterator().next(); + TripReport itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); @@ -95,12 +95,20 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(stops); + assertFalse(stops.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + Iterator iterator = stops.iterator(); + + StopReport itemStop = iterator.next(); + + assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); + assertEquals(120000, itemStop.getDuration()); + + itemStop = iterator.next(); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:07:00.000"), itemStop.getEndTime()); @@ -121,12 +129,12 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); @@ -147,32 +155,19 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getEndTime()); assertEquals(240000, itemStop.getDuration()); - tripsConfig.setGreedyParking(true); - - result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); - - assertNotNull(result); - assertFalse(result.isEmpty()); - - itemStop = (StopReport) result.iterator().next(); - - assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); - assertEquals(300000, itemStop.getDuration()); - } - + @Test public void testDetectStopsStartedFromTrip() throws ParseException { @@ -186,16 +181,16 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = result.iterator().next(); - assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); - assertEquals(300000, itemStop.getDuration()); + assertEquals(180000, itemStop.getDuration()); } @@ -212,7 +207,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); assertNotNull(result); assertTrue(result.isEmpty()); @@ -234,12 +229,12 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, false, 900000); - Collection result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, true); + Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(trips); + assertFalse(trips.isEmpty()); - TripReport itemTrip = (TripReport) result.iterator().next(); + TripReport itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemTrip.getEndTime()); @@ -248,12 +243,12 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - result = ReportUtils.detectTripsAndStops(tripsConfig, false, 0.01, data, false); + Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); - assertNotNull(result); - assertFalse(result.isEmpty()); + assertNotNull(stops); + assertFalse(stops.isEmpty()); - StopReport itemStop = (StopReport) result.iterator().next(); + StopReport itemStop = stops.iterator().next(); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:23:00.000"), itemStop.getEndTime()); -- cgit v1.2.3 From 60dea5494b10f52433166a8785edc12860679bc3 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 15 Aug 2017 15:15:49 +0500 Subject: Remove greadyParking --- src/org/traccar/Context.java | 1 - src/org/traccar/reports/model/TripsConfig.java | 13 +------------ test/org/traccar/events/MotionEventHandlerTest.java | 4 ++-- test/org/traccar/reports/ReportUtilsTest.java | 12 ++++++------ 4 files changed, 9 insertions(+), 21 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index a69b1786d..0d2a05b7a 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -255,7 +255,6 @@ public final class Context { config.getLong("report.trip.minimalTripDistance", 500), config.getLong("report.trip.minimalTripDuration", 300) * 1000, config.getLong("report.trip.minimalParkingDuration", 300) * 1000, - config.getBoolean("report.trip.greedyParking"), config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000); } diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java index 7067781d7..4898c1389 100644 --- a/src/org/traccar/reports/model/TripsConfig.java +++ b/src/org/traccar/reports/model/TripsConfig.java @@ -22,11 +22,10 @@ public class TripsConfig { } public TripsConfig(double minimalTripDistance, long minimalTripDuration, - long minimalParkingDuration, boolean greedyParking, long minimalNoDataDuration) { + long minimalParkingDuration, long minimalNoDataDuration) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; - this.greedyParking = greedyParking; this.minimalNoDataDuration = minimalNoDataDuration; } @@ -60,16 +59,6 @@ public class TripsConfig { this.minimalParkingDuration = minimalParkingDuration; } - private boolean greedyParking; - - public boolean getGreedyParking() { - return greedyParking; - } - - public void setGreedyParking(boolean greedyParking) { - this.greedyParking = greedyParking; - } - private long minimalNoDataDuration; public long getMinimalNoDataDuration() { diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index 6b7b9daee..0543d86fe 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -29,7 +29,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -68,7 +68,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithStatus() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0)); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 360000)); diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index 1b552baa3..14d8d87e0 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -79,7 +79,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:06:00.000", 0, 3000), position("2016-01-01 00:07:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000); Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); @@ -127,7 +127,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -153,7 +153,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -179,7 +179,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 0, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -205,7 +205,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000); Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); @@ -227,7 +227,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, false, 900000); + TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000); Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); -- cgit v1.2.3 From 7820541530ea9891c001cbd8c53cc6340380a077 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 16 Aug 2017 07:10:33 +1200 Subject: Support new Telic format --- src/org/traccar/protocol/TelicProtocolDecoder.java | 4 ++-- test/org/traccar/ProtocolTest.java | 4 ++++ test/org/traccar/protocol/TelicFrameDecoderTest.java | 14 +++++++------- test/org/traccar/protocol/TelicProtocolDecoderTest.java | 6 ++++++ 4 files changed, 19 insertions(+), 9 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index 62b756ab5..a875009a1 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -34,8 +34,8 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("dddd") - .number("(d{6})") // device id - .number("(d+),") // type + .number("(d{6}|d{15})") // device id + .number("(dd),") // type .number("d{12},") // event time .number("d+,") .number("(dd)(dd)(dd)") // date (ddmmyy) diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index daa495a17..a2c7e4f21 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -82,6 +82,10 @@ public class ProtocolTest extends BaseTest { Assert.assertNotNull(decoder.decode(null, null, object)); } + protected void verifyNull(Object object) throws Exception { + Assert.assertNull(object); + } + protected void verifyNull(BaseProtocolDecoder decoder, Object object) throws Exception { Assert.assertNull(decoder.decode(null, null, object)); } diff --git a/test/org/traccar/protocol/TelicFrameDecoderTest.java b/test/org/traccar/protocol/TelicFrameDecoderTest.java index a091891df..711014c46 100644 --- a/test/org/traccar/protocol/TelicFrameDecoderTest.java +++ b/test/org/traccar/protocol/TelicFrameDecoderTest.java @@ -14,30 +14,30 @@ public class TelicFrameDecoderTest extends ProtocolTest { TelicFrameDecoder decoder = new TelicFrameDecoder(); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "303032363230333339337c3232367c31307c303032303034303130"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363230333339337c3232367c31307c30303230303430313000"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "3030333032303333393332352c3139303331373038333035322c302c3138303331373130333132372c3235393932342c3434353133332c332c302c302c392c2c2c39332c31323231303134312c2c303031302c30302c34302c3234302c302c30343036"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "630000003030333032303333393332352c3139303331373038333035322c302c3138303331373130333132372c3235393932342c3434353133332c332c302c302c392c2c2c39332c31323231303134312c2c303031302c30302c34302c3234302c302c3034303600"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "303032363239363231385343434530315f534343457c3232367c31307c30323637"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363239363231385343434530315f534343457c3232367c31307c3032363700"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "30303434323936323138544c4f43303236372c30302c3031313030393030303239363231382c3139303331373038333033362c3235353137382c3434353037322c332c302c38322c2c2c2c3136382c31343734313239362c2c30302c30302c302c323137"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "6400000030303434323936323138544c4f43303236372c30302c3031313030393030303239363231382c3139303331373038333033362c3235353137382c3434353037322c332c302c38322c2c2c2c3136382c31343734313239362c2c30302c30302c302c32313700"))); - Assert.assertNull( + verifyNull( decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "00303032363937393238317c3233327c30337c30303230303430313000"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "303032363937393238317c3233327c30337c303032303034303130"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363937393238317c3233327c30337c30303230303430313000"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "3030323039373932383139392c3231303231363038313930302c302c3231303231363038313835392c3031333839333338352c34363635383639352c332c302c302c382c2c2c3534312c36313239382c2c303030302c30302c302c3139362c302c30343037"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "650000003030323039373932383139392c3231303231363038313930302c302c3231303231363038313835392c3031333839333338352c34363635383639352c332c302c302c382c2c2c3534312c36313239382c2c303030302c30302c302c3139362c302c3034303700"))); diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index 85d6f70ac..84b6a797b 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class TelicProtocolDecoderTest extends ProtocolTest { TelicProtocolDecoder decoder = new TelicProtocolDecoder(new TelicProtocol()); + verifyNull(decoder, text( + "0026355565071347499|206|01|001002008")); + + verifyPosition(decoder, text( + "002135556507134749999,010817171138,0,010817171138,004560973,50667173,3,0,0,11,1,1,100,958071,20601,000000,00,4142,0000,0000,0208,10395,0")); + verifyPosition(decoder, text( "442045993198,290317131935,0,290317131935,269158,465748,3,26,183,,,,184,85316567,226,01,00,68,218")); -- cgit v1.2.3 From 668d0c65609cc510ad9da3be4fc7aafaa3ca427d Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 16 Aug 2017 11:04:41 +0500 Subject: Combine trips and stops detectors and some optimization --- src/org/traccar/events/MotionEventHandler.java | 5 +- src/org/traccar/reports/ReportUtils.java | 114 +++++++++++-------------- src/org/traccar/reports/Stops.java | 4 +- src/org/traccar/reports/Trips.java | 4 +- test/org/traccar/reports/ReportUtilsTest.java | 16 ++-- 5 files changed, 68 insertions(+), 75 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index 8c2d4c56c..b96898fc1 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -61,11 +61,14 @@ public class MotionEventHandler extends BaseEventHandler { } public Event updateMotionState(DeviceState deviceState, Position position) { + return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + } + + public Event updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { Event result = null; Boolean oldMotion = deviceState.getMotionState(); long currentTime = position.getFixTime().getTime(); - boolean newMotion = position.getBoolean(Position.KEY_MOTION); if (newMotion != oldMotion) { if (deviceState.getMotionPosition() == null) { deviceState.setMotionPosition(position); diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 75f300b1d..cd13b28e6 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -31,6 +31,7 @@ import org.traccar.model.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; @@ -239,13 +240,16 @@ public final class ReportUtils { private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig, double speedThreshold) { - if (tripsConfig.getMinimalNoDataDuration() > 0 && (index < positions.size() - 1 - && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration()) - || index > 0 - && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration()) { - return false; + if (tripsConfig.getMinimalNoDataDuration() > 0) { + boolean beforeGap = index < positions.size() - 1 + && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + boolean afterGap = index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + if (beforeGap || afterGap) { + return false; + } } if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { @@ -255,76 +259,62 @@ public final class ReportUtils { } } - public static Collection detectTrips(Collection positionCollection, TripsConfig tripsConfig, - boolean ignoreOdometer, double speedThreshold) { - Collection result = new ArrayList<>(); + public static Collection detectTripsAndStops(Collection positionCollection, + TripsConfig tripsConfig, boolean ignoreOdometer, double speedThreshold, Class reportClass) { + Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); if (positions != null && !positions.isEmpty()) { + boolean trips = reportClass.equals(TripReport.class); MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); - int startTripIndex = deviceState.getMotionState() ? 0 : -1; - int startParkingIndex = -1; + int startTripIndex = trips && deviceState.getMotionState() ? 0 : -1; + int startParkingIndex = !trips && !deviceState.getMotionState() ? 0 : -1; for (int i = 0; i < positions.size(); i++) { - positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); - Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); - if (startTripIndex == -1 && !deviceState.getMotionState() && deviceState.getMotionPosition() != null) { - startTripIndex = i; - startParkingIndex = -1; - } - if (deviceState.getMotionState()) { - if (startParkingIndex == -1) { - startParkingIndex = i; - } else if (deviceState.getMotionPosition() == null) { + Event event = motionHandler.updateMotionState(deviceState, positions.get(i), + isMoving(positions, i, tripsConfig, speedThreshold)); + if (deviceState.getMotionPosition() != null) { + if (trips && startTripIndex == -1 && !deviceState.getMotionState()) { + startTripIndex = i; startParkingIndex = -1; + } else if (!trips && startParkingIndex == -1 && deviceState.getMotionState()) { + startParkingIndex = i; + startTripIndex = -1; } } - if (startTripIndex != -1 && startParkingIndex != -1 && event != null && !deviceState.getMotionState()) { - result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); - startTripIndex = -1; - } - } - if (startTripIndex != -1 && startParkingIndex != -1) { - result.add(calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); - } - } - return result; - } - - public static Collection detectStops(Collection positionCollection, TripsConfig tripsConfig, - boolean ignoreOdometer, double speedThreshold) { - Collection result = new ArrayList<>(); - - ArrayList positions = new ArrayList<>(positionCollection); - if (positions != null && !positions.isEmpty()) { - MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); - int startTripIndex = -1; - int startParkingIndex = deviceState.getMotionState() ? -1 : 0; - for (int i = 0; i < positions.size(); i++) { - positions.get(i).set(Position.KEY_MOTION, isMoving(positions, i, tripsConfig, speedThreshold)); - Event event = motionHandler.updateMotionState(deviceState, positions.get(i)); - if (startParkingIndex == -1 && deviceState.getMotionState() - && deviceState.getMotionPosition() != null) { - startParkingIndex = i; - startTripIndex = -1; + if (trips) { + if (deviceState.getMotionState()) { + if (startParkingIndex == -1) { + startParkingIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startParkingIndex = -1; + } + } + } else { + if (!deviceState.getMotionState()) { + if (startTripIndex == -1) { + startTripIndex = i; + } else if (deviceState.getMotionPosition() == null) { + startTripIndex = -1; + } + } } - if (!deviceState.getMotionState()) { - if (startTripIndex == -1) { - startTripIndex = i; - } else if (deviceState.getMotionPosition() == null) { + if (startTripIndex != -1 && startParkingIndex != -1 && event != null) { + if (trips && !deviceState.getMotionState()) { + result.add((T) calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); startTripIndex = -1; + } else if (!trips && deviceState.getMotionState()) { + result.add((T) calculateStop(positions, startParkingIndex, startTripIndex)); + startParkingIndex = -1; } } - if (startParkingIndex != -1 && startTripIndex != -1 && event != null && deviceState.getMotionState()) { - result.add(calculateStop(positions, startParkingIndex, startTripIndex)); - startParkingIndex = -1; - } } - if (startParkingIndex != -1) { - result.add(calculateStop(positions, startParkingIndex, + if (trips && startTripIndex != -1 && startParkingIndex != -1) { + result.add((T) calculateTrip(positions, startTripIndex, startParkingIndex, ignoreOdometer)); + } + if (!trips && startParkingIndex != -1) { + result.add((T) calculateStop(positions, startParkingIndex, startTripIndex != -1 ? startTripIndex : positions.size() - 1)); } } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 68fdef334..1e72cc927 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -44,9 +44,9 @@ public final class Stops { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectStops( + Collection result = ReportUtils.detectTripsAndStops( Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, speedThreshold); + Context.getTripsConfig(), ignoreOdometer, speedThreshold, StopReport.class); return result; } diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index bb39cf493..1ee62e87c 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -43,9 +43,9 @@ public final class Trips { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); - Collection result = ReportUtils.detectTrips( + Collection result = ReportUtils.detectTripsAndStops( Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, speedThreshold); + Context.getTripsConfig(), ignoreOdometer, speedThreshold, TripReport.class); return result; } diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index c74109550..c82853161 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -81,7 +81,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false); - Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -95,7 +95,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -129,7 +129,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -155,7 +155,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -181,7 +181,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -207,7 +207,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); - Collection result = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -229,7 +229,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false); - Collection trips = ReportUtils.detectTrips(data, tripsConfig, false, 0.01); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -243,7 +243,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectStops(data, tripsConfig, false, 0.01); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 1324c00d0ece6e20545fb75f7775a2c6cee2a391 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 17 Aug 2017 10:10:05 +0500 Subject: Pass Map to notifications --- src/org/traccar/BaseEventHandler.java | 8 +++--- src/org/traccar/database/ConnectionManager.java | 21 ++++++++-------- src/org/traccar/database/NotificationManager.java | 18 ++++++-------- src/org/traccar/events/AlertEventHandler.java | 6 ++--- .../traccar/events/CommandResultEventHandler.java | 6 ++--- src/org/traccar/events/DriverEventHandler.java | 6 ++--- src/org/traccar/events/FuelDropEventHandler.java | 6 ++--- src/org/traccar/events/GeofenceEventHandler.java | 11 ++++---- src/org/traccar/events/IgnitionEventHandler.java | 14 +++++------ .../traccar/events/MaintenanceEventHandler.java | 6 ++--- src/org/traccar/events/MotionEventHandler.java | 29 ++++++++++------------ src/org/traccar/events/OverspeedEventHandler.java | 27 +++++++++----------- src/org/traccar/reports/ReportUtils.java | 3 ++- test/org/traccar/events/AlertEventHandlerTest.java | 6 ++--- .../events/CommandResultEventHandlerTest.java | 6 ++--- .../traccar/events/IgnitionEventHandlerTest.java | 4 +-- .../org/traccar/events/MotionEventHandlerTest.java | 23 ++++++++++------- .../traccar/events/OverspeedEventHandlerTest.java | 27 +++++++++++--------- 18 files changed, 114 insertions(+), 113 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/BaseEventHandler.java b/src/org/traccar/BaseEventHandler.java index 588406bf4..b6f7e2085 100644 --- a/src/org/traccar/BaseEventHandler.java +++ b/src/org/traccar/BaseEventHandler.java @@ -15,7 +15,7 @@ */ package org.traccar; -import java.util.Collection; +import java.util.Map; import org.traccar.model.Event; import org.traccar.model.Position; @@ -25,13 +25,13 @@ public abstract class BaseEventHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Collection events = analyzePosition(position); + Map events = analyzePosition(position); if (events != null && Context.getNotificationManager() != null) { - Context.getNotificationManager().updateEvents(events, position); + Context.getNotificationManager().updateEvents(events); } return position; } - protected abstract Collection analyzePosition(Position position); + protected abstract Map analyzePosition(Position position); } diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 7a0a6d30d..de11db21b 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -31,6 +31,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.sql.SQLException; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -84,7 +85,7 @@ public class ConnectionManager { if (enableStatusEvents && !status.equals(oldStatus)) { String eventType; - Set events = new HashSet<>(); + Map events = new HashMap<>(); switch (status) { case Device.STATUS_ONLINE: eventType = Event.TYPE_DEVICE_ONLINE; @@ -92,18 +93,18 @@ public class ConnectionManager { case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; if (updateDeviceState) { - events.addAll(updateDeviceState(deviceId)); + events.putAll(updateDeviceState(deviceId)); } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; if (updateDeviceState) { - events.addAll(updateDeviceState(deviceId)); + events.putAll(updateDeviceState(deviceId)); } break; } - events.add(new Event(eventType, deviceId)); - Context.getNotificationManager().updateEvents(events, null); + events.put(new Event(eventType, deviceId), null); + Context.getNotificationManager().updateEvents(events); } Timeout timeout = timeouts.remove(deviceId); @@ -135,19 +136,19 @@ public class ConnectionManager { updateDevice(device); } - public Set updateDeviceState(long deviceId) { + public Map updateDeviceState(long deviceId) { DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - Set result = new HashSet<>(); + Map result = new HashMap<>(); - Event event = Context.getMotionEventHandler().updateMotionState(deviceState); + Map event = Context.getMotionEventHandler().updateMotionState(deviceState); if (event != null) { - result.add(event); + result.putAll(event); } event = Context.getOverspeedEventHandler().updateOverspeedState(deviceState, Context.getDeviceManager(). lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false)); if (event != null) { - result.add(event); + result.putAll(event); } return result; diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java index 8eea287de..98cae3499 100644 --- a/src/org/traccar/database/NotificationManager.java +++ b/src/org/traccar/database/NotificationManager.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -48,13 +49,8 @@ public class NotificationManager { } public void updateEvent(Event event, Position position) { - Position relatedPosition = position; try { dataManager.addObject(event); - if (event.getPositionId() != 0 && (relatedPosition == null - || event.getPositionId() != relatedPosition.getId())) { - relatedPosition = dataManager.getObject(Position.class, event.getPositionId()); - } } catch (SQLException error) { Log.warning(error); } @@ -69,22 +65,22 @@ public class NotificationManager { Context.getConnectionManager().updateEvent(userId, event); } if (notification.getMail()) { - NotificationMail.sendMailAsync(userId, event, relatedPosition); + NotificationMail.sendMailAsync(userId, event, position); } if (notification.getSms()) { - NotificationSms.sendSmsAsync(userId, event, relatedPosition); + NotificationSms.sendSmsAsync(userId, event, position); } } } } if (Context.getEventForwarder() != null) { - Context.getEventForwarder().forwardEvent(event, relatedPosition); + Context.getEventForwarder().forwardEvent(event, position); } } - public void updateEvents(Collection events, Position position) { - for (Event event : events) { - updateEvent(event, position); + public void updateEvents(Map events) { + for (Entry event : events.entrySet()) { + updateEvent(event.getKey(), event.getValue()); } } diff --git a/src/org/traccar/events/AlertEventHandler.java b/src/org/traccar/events/AlertEventHandler.java index 7d0bd669b..003ccb662 100644 --- a/src/org/traccar/events/AlertEventHandler.java +++ b/src/org/traccar/events/AlertEventHandler.java @@ -15,8 +15,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.model.Event; @@ -25,12 +25,12 @@ import org.traccar.model.Position; public class AlertEventHandler extends BaseEventHandler { @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { Object alarm = position.getAttributes().get(Position.KEY_ALARM); if (alarm != null) { Event event = new Event(Event.TYPE_ALARM, position.getDeviceId(), position.getId()); event.set(Position.KEY_ALARM, (String) alarm); - return Collections.singleton(event); + return Collections.singletonMap(event, position); } return null; } diff --git a/src/org/traccar/events/CommandResultEventHandler.java b/src/org/traccar/events/CommandResultEventHandler.java index 077c389c9..775aa903f 100644 --- a/src/org/traccar/events/CommandResultEventHandler.java +++ b/src/org/traccar/events/CommandResultEventHandler.java @@ -15,8 +15,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.model.Event; @@ -25,12 +25,12 @@ import org.traccar.model.Position; public class CommandResultEventHandler extends BaseEventHandler { @Override - protected Collection analyzePosition(Position position) { + protected Map 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.singleton(event); + return Collections.singletonMap(event, position); } return null; } diff --git a/src/org/traccar/events/DriverEventHandler.java b/src/org/traccar/events/DriverEventHandler.java index eb5f2a301..39b8eb9c0 100644 --- a/src/org/traccar/events/DriverEventHandler.java +++ b/src/org/traccar/events/DriverEventHandler.java @@ -16,8 +16,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.Context; @@ -27,7 +27,7 @@ import org.traccar.model.Position; public class DriverEventHandler extends BaseEventHandler { @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { if (!Context.getIdentityManager().isLatestPosition(position)) { return null; } @@ -41,7 +41,7 @@ public class DriverEventHandler extends BaseEventHandler { 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.singleton(event); + return Collections.singletonMap(event, position); } } return null; diff --git a/src/org/traccar/events/FuelDropEventHandler.java b/src/org/traccar/events/FuelDropEventHandler.java index 4e09bd4fa..4fc512162 100644 --- a/src/org/traccar/events/FuelDropEventHandler.java +++ b/src/org/traccar/events/FuelDropEventHandler.java @@ -21,15 +21,15 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; -import java.util.Collection; import java.util.Collections; +import java.util.Map; public class FuelDropEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_FUEL_DROP_THRESHOLD = "fuelDropThreshold"; @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { @@ -52,7 +52,7 @@ public class FuelDropEventHandler extends BaseEventHandler { 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.singleton(event); + return Collections.singletonMap(event, position); } } } diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java index 79e5d0f8e..31d82a81e 100644 --- a/src/org/traccar/events/GeofenceEventHandler.java +++ b/src/org/traccar/events/GeofenceEventHandler.java @@ -16,8 +16,9 @@ package org.traccar.events; import java.util.ArrayList; -import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.Context; @@ -36,7 +37,7 @@ public class GeofenceEventHandler extends BaseEventHandler { } @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; @@ -56,14 +57,14 @@ public class GeofenceEventHandler extends BaseEventHandler { device.setGeofenceIds(currentGeofences); - Collection events = new ArrayList<>(); + Map events = new HashMap<>(); for (long geofenceId : newGeofences) { long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); Calendar calendar = calendarId != 0 ? Context.getCalendarManager().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.add(event); + events.put(event, position); } } for (long geofenceId : oldGeofences) { @@ -72,7 +73,7 @@ public class GeofenceEventHandler extends BaseEventHandler { if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId()); event.setGeofenceId(geofenceId); - events.add(event); + events.put(event, position); } } return events; diff --git a/src/org/traccar/events/IgnitionEventHandler.java b/src/org/traccar/events/IgnitionEventHandler.java index 5519135bf..cc53b216c 100644 --- a/src/org/traccar/events/IgnitionEventHandler.java +++ b/src/org/traccar/events/IgnitionEventHandler.java @@ -16,8 +16,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.Context; @@ -28,13 +28,13 @@ import org.traccar.model.Position; public class IgnitionEventHandler extends BaseEventHandler { @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } - Collection result = null; + Map result = null; if (position.getAttributes().containsKey(Position.KEY_IGNITION)) { boolean ignition = position.getBoolean(Position.KEY_IGNITION); @@ -44,11 +44,11 @@ public class IgnitionEventHandler extends BaseEventHandler { boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); if (ignition && !oldIgnition) { - result = Collections.singleton( - new Event(Event.TYPE_IGNITION_ON, position.getDeviceId(), position.getId())); + result = Collections.singletonMap( + new Event(Event.TYPE_IGNITION_ON, position.getDeviceId(), position.getId()), position); } else if (!ignition && oldIgnition) { - result = Collections.singleton( - new Event(Event.TYPE_IGNITION_OFF, position.getDeviceId(), position.getId())); + result = Collections.singletonMap( + new Event(Event.TYPE_IGNITION_OFF, position.getDeviceId(), position.getId()), position); } } } diff --git a/src/org/traccar/events/MaintenanceEventHandler.java b/src/org/traccar/events/MaintenanceEventHandler.java index ffeefc8c5..86abf7c17 100644 --- a/src/org/traccar/events/MaintenanceEventHandler.java +++ b/src/org/traccar/events/MaintenanceEventHandler.java @@ -16,8 +16,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.Context; @@ -31,7 +31,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_MAINTENANCE_INTERVAL = "maintenance.interval"; @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; @@ -60,7 +60,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { if ((long) (oldTotalDistance / maintenanceInterval) < (long) (newTotalDistance / maintenanceInterval)) { Event event = new Event(Event.TYPE_MAINTENANCE, position.getDeviceId(), position.getId()); event.set(Position.KEY_TOTAL_DISTANCE, newTotalDistance); - return Collections.singleton(event); + return Collections.singletonMap(event, position); } return null; diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index b96898fc1..ae64c10ea 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -16,8 +16,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.Context; @@ -36,17 +36,17 @@ public class MotionEventHandler extends BaseEventHandler { this.tripsConfig = tripsConfig; } - private Event newEvent(DeviceState deviceState, boolean newMotion) { + private Map newEvent(DeviceState deviceState, boolean newMotion) { String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - Event event = new Event(eventType, deviceState.getMotionPosition().getDeviceId(), - deviceState.getMotionPosition().getId()); + Position position = deviceState.getMotionPosition(); + Event event = new Event(eventType, position.getDeviceId(), position.getId()); deviceState.setMotionState(newMotion); deviceState.setMotionPosition(null); - return event; + return Collections.singletonMap(event, position); } - public Event updateMotionState(DeviceState deviceState) { - Event result = null; + public Map updateMotionState(DeviceState deviceState) { + Map result = null; if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { boolean newMotion = !deviceState.getMotionState(); Position motionPosition = deviceState.getMotionPosition(); @@ -60,12 +60,12 @@ public class MotionEventHandler extends BaseEventHandler { return result; } - public Event updateMotionState(DeviceState deviceState, Position position) { + public Map updateMotionState(DeviceState deviceState, Position position) { return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); } - public Event updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { - Event result = null; + public Map updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { + Map result = null; Boolean oldMotion = deviceState.getMotionState(); long currentTime = position.getFixTime().getTime(); @@ -102,7 +102,7 @@ public class MotionEventHandler extends BaseEventHandler { } @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { long deviceId = position.getDeviceId(); Device device = Context.getIdentityManager().getById(deviceId); @@ -113,7 +113,7 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - Event result = null; + Map result = null; DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); if (deviceState.getMotionState() == null) { @@ -122,10 +122,7 @@ public class MotionEventHandler extends BaseEventHandler { result = updateMotionState(deviceState, position); } Context.getDeviceManager().setDeviceState(deviceId, deviceState); - if (result != null) { - return Collections.singleton(result); - } - return null; + return result; } } diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 953af6b33..cb658415c 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -15,8 +15,8 @@ */ package org.traccar.events; -import java.util.Collection; import java.util.Collections; +import java.util.Map; import org.traccar.BaseEventHandler; import org.traccar.Context; @@ -37,18 +37,18 @@ public class OverspeedEventHandler extends BaseEventHandler { this.minimalDuration = minimalDuration; } - private Event newEvent(DeviceState deviceState, double speedLimit) { - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, deviceState.getOverspeedPosition().getDeviceId(), - deviceState.getOverspeedPosition().getId()); + private Map newEvent(DeviceState deviceState, double speedLimit) { + Position position = deviceState.getOverspeedPosition(); + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()); event.set("speed", deviceState.getOverspeedPosition().getSpeed()); event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); deviceState.setOverspeedState(notRepeat); deviceState.setOverspeedPosition(null); - return event; + return Collections.singletonMap(event, position); } - public Event updateOverspeedState(DeviceState deviceState, double speedLimit) { - Event result = null; + public Map updateOverspeedState(DeviceState deviceState, double speedLimit) { + Map result = null; if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() && deviceState.getOverspeedPosition() != null && speedLimit != 0) { long currentTime = System.currentTimeMillis(); @@ -61,8 +61,8 @@ public class OverspeedEventHandler extends BaseEventHandler { return result; } - public Event updateOverspeedState(DeviceState deviceState, Position position, double speedLimit) { - Event result = null; + public Map updateOverspeedState(DeviceState deviceState, Position position, double speedLimit) { + Map result = null; Boolean oldOverspeed = deviceState.getOverspeedState(); @@ -89,7 +89,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } @Override - protected Collection analyzePosition(Position position) { + protected Map analyzePosition(Position position) { long deviceId = position.getDeviceId(); Device device = Context.getIdentityManager().getById(deviceId); @@ -105,7 +105,7 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - Event result = null; + Map result = null; DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); if (deviceState.getOverspeedState() == null) { @@ -115,10 +115,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } Context.getDeviceManager().setDeviceState(deviceId, deviceState); - if (result != null) { - return Collections.singleton(result); - } - return null; + return result; } } diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 8a398e4c2..46aea0757 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -46,6 +46,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.TimeZone; public final class ReportUtils { @@ -281,7 +282,7 @@ public final class ReportUtils { int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { - Event event = motionHandler.updateMotionState(deviceState, positions.get(i), + Map event = motionHandler.updateMotionState(deviceState, positions.get(i), isMoving(positions, i, tripsConfig, speedThreshold)); if (deviceState.getMotionPosition() != null && startEventIndex == -1 && trips != deviceState.getMotionState()) { diff --git a/test/org/traccar/events/AlertEventHandlerTest.java b/test/org/traccar/events/AlertEventHandlerTest.java index 77128f066..4e11398e1 100644 --- a/test/org/traccar/events/AlertEventHandlerTest.java +++ b/test/org/traccar/events/AlertEventHandlerTest.java @@ -3,7 +3,7 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.util.Collection; +import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; @@ -19,9 +19,9 @@ public class AlertEventHandlerTest extends BaseTest { Position position = new Position(); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - Collection events = alertEventHandler.analyzePosition(position); + Map events = alertEventHandler.analyzePosition(position); assertNotNull(events); - Event event = (Event) events.toArray()[0]; + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_ALARM, event.getType()); } diff --git a/test/org/traccar/events/CommandResultEventHandlerTest.java b/test/org/traccar/events/CommandResultEventHandlerTest.java index f028e86ee..602108d1a 100644 --- a/test/org/traccar/events/CommandResultEventHandlerTest.java +++ b/test/org/traccar/events/CommandResultEventHandlerTest.java @@ -3,7 +3,7 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.util.Collection; +import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; @@ -19,9 +19,9 @@ public class CommandResultEventHandlerTest extends BaseTest { Position position = new Position(); position.set(Position.KEY_RESULT, "Test Result"); - Collection events = commandResultEventHandler.analyzePosition(position); + Map events = commandResultEventHandler.analyzePosition(position); assertNotNull(events); - Event event = (Event) events.toArray()[0]; + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_COMMAND_RESULT, event.getType()); } diff --git a/test/org/traccar/events/IgnitionEventHandlerTest.java b/test/org/traccar/events/IgnitionEventHandlerTest.java index d6c348c77..7c4ac21b9 100644 --- a/test/org/traccar/events/IgnitionEventHandlerTest.java +++ b/test/org/traccar/events/IgnitionEventHandlerTest.java @@ -2,7 +2,7 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; -import java.util.Collection; +import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; @@ -19,7 +19,7 @@ public class IgnitionEventHandlerTest extends BaseTest { Position position = new Position(); position.set(Position.KEY_IGNITION, true); position.setValid(true); - Collection events = ignitionEventHandler.analyzePosition(position); + Map events = ignitionEventHandler.analyzePosition(position); assertEquals(events, null); } diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index 902be8b87..b88328e58 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -10,6 +10,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Map; import java.util.TimeZone; import org.junit.Test; @@ -45,12 +46,13 @@ public class MotionEventHandlerTest extends BaseTest { nextPosition.set(Position.KEY_MOTION, true); nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - Event event = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNull(event); + Map events = motionEventHandler.updateMotionState(deviceState, nextPosition); + assertNull(events); nextPosition.set(Position.KEY_TOTAL_DISTANCE, 600); - event = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(event); + events = motionEventHandler.updateMotionState(deviceState, nextPosition); + assertNotNull(events); + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); assertTrue(deviceState.getMotionState()); assertNull(deviceState.getMotionPosition()); @@ -59,8 +61,9 @@ public class MotionEventHandlerTest extends BaseTest { deviceState.setMotionPosition(position); nextPosition.setTime(date("2017-01-01 00:06:00")); nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - event = motionEventHandler.updateMotionState(deviceState, nextPosition); + events = motionEventHandler.updateMotionState(deviceState, nextPosition); assertNotNull(event); + event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); assertTrue(deviceState.getMotionState()); assertNull(deviceState.getMotionPosition()); @@ -78,9 +81,10 @@ public class MotionEventHandlerTest extends BaseTest { deviceState.setMotionState(false); deviceState.setMotionPosition(position); - Event event = motionEventHandler.updateMotionState(deviceState); + Map events = motionEventHandler.updateMotionState(deviceState); - assertNotNull(event); + assertNotNull(events); + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); assertTrue(deviceState.getMotionState()); assertNull(deviceState.getMotionPosition()); @@ -104,8 +108,9 @@ public class MotionEventHandlerTest extends BaseTest { nextPosition.set(Position.KEY_MOTION, false); nextPosition.set(Position.KEY_IGNITION, false); - Event event = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(event); + Map events = motionEventHandler.updateMotionState(deviceState, nextPosition); + assertNotNull(events); + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_STOPPED, event.getType()); assertFalse(deviceState.getMotionState()); assertNull(deviceState.getMotionPosition()); diff --git a/test/org/traccar/events/OverspeedEventHandlerTest.java b/test/org/traccar/events/OverspeedEventHandlerTest.java index 48d7445ff..d38367cd9 100644 --- a/test/org/traccar/events/OverspeedEventHandlerTest.java +++ b/test/org/traccar/events/OverspeedEventHandlerTest.java @@ -9,6 +9,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Map; import java.util.TimeZone; import org.junit.Test; @@ -34,8 +35,8 @@ public class OverspeedEventHandlerTest extends BaseTest { DeviceState deviceState = new DeviceState(); deviceState.setOverspeedState(false); - Event event = overspeedEventHandler.updateOverspeedState(deviceState, position, 40); - assertNull(event); + Map events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40); + assertNull(events); assertFalse(deviceState.getOverspeedState()); assertEquals(position, deviceState.getOverspeedPosition()); @@ -43,13 +44,14 @@ public class OverspeedEventHandlerTest extends BaseTest { nextPosition.setTime(date("2017-01-01 00:00:10")); nextPosition.setSpeed(55); - event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); - assertNull(event); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + assertNull(events); nextPosition.setTime(date("2017-01-01 00:00:20")); - event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); - assertNotNull(event); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + assertNotNull(events); + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(50, event.getDouble("speed"), 0.1); assertEquals(40, event.getDouble(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT), 0.1); @@ -58,8 +60,8 @@ public class OverspeedEventHandlerTest extends BaseTest { assertNull(deviceState.getOverspeedPosition()); nextPosition.setTime(date("2017-01-01 00:00:30")); - event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); - assertNull(event); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + assertNull(events); assertEquals(notRepeat, deviceState.getOverspeedState()); if (notRepeat) { @@ -71,8 +73,8 @@ public class OverspeedEventHandlerTest extends BaseTest { nextPosition.setTime(date("2017-01-01 00:00:40")); nextPosition.setSpeed(30); - event = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); - assertNull(event); + events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40); + assertNull(events); assertFalse(deviceState.getOverspeedState()); assertNull(deviceState.getOverspeedPosition()); } @@ -87,9 +89,10 @@ public class OverspeedEventHandlerTest extends BaseTest { deviceState.setOverspeedState(false); deviceState.setOverspeedPosition(position); - Event event = overspeedEventHandler.updateOverspeedState(deviceState, 40); + Map events = overspeedEventHandler.updateOverspeedState(deviceState, 40); - assertNotNull(event); + assertNotNull(events); + Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(notRepeat, deviceState.getOverspeedState()); } -- cgit v1.2.3 From ad18dad83638ac2b003596eb1b6226bb9c407abc Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 17 Aug 2017 16:37:29 +0500 Subject: Fix trip detector --- src/org/traccar/reports/ReportUtils.java | 20 ++-- test/org/traccar/reports/ReportUtilsTest.java | 127 +++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 11 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 46aea0757..74cdaf9b5 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -284,17 +284,21 @@ public final class ReportUtils { for (int i = 0; i < positions.size(); i++) { Map event = motionHandler.updateMotionState(deviceState, positions.get(i), isMoving(positions, i, tripsConfig, speedThreshold)); - if (deviceState.getMotionPosition() != null && startEventIndex == -1 - && trips != deviceState.getMotionState()) { + if (startEventIndex == -1 + && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null + || trips == deviceState.getMotionState() && event != null)) { startEventIndex = i; startNoEventIndex = -1; + } else if (trips != deviceState.getMotionState() && startEventIndex != -1 + && deviceState.getMotionPosition() == null && event == null) { + startEventIndex = -1; } - if (trips == deviceState.getMotionState()) { - if (startNoEventIndex == -1) { - startNoEventIndex = i; - } else if (deviceState.getMotionPosition() == null) { - startNoEventIndex = -1; - } + if (startNoEventIndex == -1 + && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null + || trips != deviceState.getMotionState() && event != null)) { + startNoEventIndex = i; + } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { + startNoEventIndex = -1; } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index c82853161..261291255 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Iterator; +import java.util.List; import java.util.TimeZone; import org.junit.Assert; @@ -69,7 +70,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testDetectTripsSimple() throws ParseException { - Collection data = Arrays.asList( + List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), position("2016-01-01 00:01:00.000", 0, 0), position("2016-01-01 00:02:00.000", 10, 0), @@ -116,6 +117,126 @@ public class ReportUtilsTest extends BaseTest { } + @Test + public void testDetectTripsSimpleWithIgnition() throws ParseException { + + List data = Arrays.asList( + position("2016-01-01 00:00:00.000", 0, 0), + position("2016-01-01 00:01:00.000", 0, 0), + position("2016-01-01 00:02:00.000", 10, 0), + position("2016-01-01 00:03:00.000", 10, 1000), + position("2016-01-01 00:04:00.000", 10, 2000), + position("2016-01-01 00:05:00.000", 0, 3000), + position("2016-01-01 00:06:00.000", 0, 3000), + position("2016-01-01 00:07:00.000", 0, 3000)); + + data.get(5).set(Position.KEY_IGNITION, false); + + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true); + + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + + assertNotNull(trips); + assertFalse(trips.isEmpty()); + + TripReport itemTrip = trips.iterator().next(); + + assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); + assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); + assertEquals(180000, itemTrip.getDuration()); + assertEquals(10, itemTrip.getAverageSpeed(), 0.01); + assertEquals(10, itemTrip.getMaxSpeed(), 0.01); + assertEquals(3000, itemTrip.getDistance(), 0.01); + + trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + + assertNotNull(trips); + assertFalse(trips.isEmpty()); + + itemTrip = trips.iterator().next(); + + assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); + assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); + assertEquals(180000, itemTrip.getDuration()); + assertEquals(10, itemTrip.getAverageSpeed(), 0.01); + assertEquals(10, itemTrip.getMaxSpeed(), 0.01); + assertEquals(3000, itemTrip.getDistance(), 0.01); + + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + + assertNotNull(stops); + assertFalse(stops.isEmpty()); + + Iterator iterator = stops.iterator(); + + StopReport itemStop = iterator.next(); + + assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); + assertEquals(120000, itemStop.getDuration()); + + itemStop = iterator.next(); + + assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:07:00.000"), itemStop.getEndTime()); + assertEquals(120000, itemStop.getDuration()); + + } + + @Test + public void testDetectTripsWithFluctuation() throws ParseException { + + List data = Arrays.asList( + position("2016-01-01 00:00:00.000", 0, 0), + position("2016-01-01 00:01:00.000", 0, 0), + position("2016-01-01 00:02:00.000", 10, 0), + position("2016-01-01 00:03:00.000", 10, 1000), + position("2016-01-01 00:04:00.000", 10, 2000), + position("2016-01-01 00:05:00.000", 10, 3000), + position("2016-01-01 00:06:00.000", 10, 4000), + position("2016-01-01 00:07:00.000", 0, 5000), + position("2016-01-01 00:08:00.000", 10, 6000), + position("2016-01-01 00:09:00.000", 0, 7000), + position("2016-01-01 00:10:00.000", 0, 7000), + position("2016-01-01 00:11:00.000", 0, 7000)); + + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false); + + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + + assertNotNull(trips); + assertFalse(trips.isEmpty()); + + TripReport itemTrip = trips.iterator().next(); + + assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); + assertEquals(date("2016-01-01 00:09:00.000"), itemTrip.getEndTime()); + assertEquals(420000, itemTrip.getDuration()); + assertEquals(8.57, itemTrip.getAverageSpeed(), 0.01); + assertEquals(10, itemTrip.getMaxSpeed(), 0.01); + assertEquals(7000, itemTrip.getDistance(), 0.01); + + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + + assertNotNull(stops); + assertFalse(stops.isEmpty()); + + Iterator iterator = stops.iterator(); + + StopReport itemStop = iterator.next(); + + assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); + assertEquals(120000, itemStop.getDuration()); + + itemStop = iterator.next(); + + assertEquals(date("2016-01-01 00:09:00.000"), itemStop.getStartTime()); + assertEquals(date("2016-01-01 00:11:00.000"), itemStop.getEndTime()); + assertEquals(120000, itemStop.getDuration()); + + } + @Test public void testDetectStopsOnly() throws ParseException { @@ -251,8 +372,8 @@ public class ReportUtilsTest extends BaseTest { StopReport itemStop = stops.iterator().next(); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getStartTime()); - assertEquals(date("2016-01-01 00:23:00.000"), itemStop.getEndTime()); - assertEquals(1140000, itemStop.getDuration()); + assertEquals(date("2016-01-01 00:24:00.000"), itemStop.getEndTime()); + assertEquals(1200000, itemStop.getDuration()); } } -- cgit v1.2.3 From 4a14edeea2b98062d1d61fe5eee5e1dfaf664916 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 18 Aug 2017 05:42:43 +1200 Subject: Implement eSky ES610 protocol --- setup/default.xml | 1 + src/org/traccar/protocol/EskyFrameDecoder.java | 39 +++++++++ src/org/traccar/protocol/EskyProtocol.java | 46 +++++++++++ src/org/traccar/protocol/EskyProtocolDecoder.java | 92 ++++++++++++++++++++++ .../org/traccar/protocol/EskyFrameDecoderTest.java | 24 ++++++ .../traccar/protocol/EskyProtocolDecoderTest.java | 18 +++++ 6 files changed, 220 insertions(+) create mode 100644 src/org/traccar/protocol/EskyFrameDecoder.java create mode 100644 src/org/traccar/protocol/EskyProtocol.java create mode 100644 src/org/traccar/protocol/EskyProtocolDecoder.java create mode 100644 test/org/traccar/protocol/EskyFrameDecoderTest.java create mode 100644 test/org/traccar/protocol/EskyProtocolDecoderTest.java (limited to 'test/org') diff --git a/setup/default.xml b/setup/default.xml index edb3dd47d..0047949eb 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -236,5 +236,6 @@ 5144 5145 5146 + 5147 diff --git a/src/org/traccar/protocol/EskyFrameDecoder.java b/src/org/traccar/protocol/EskyFrameDecoder.java new file mode 100644 index 000000000..3175698fd --- /dev/null +++ b/src/org/traccar/protocol/EskyFrameDecoder.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +public class EskyFrameDecoder extends FrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + + buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 'E')); + + int endIndex = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 'E'); + if (endIndex > 0) { + return buf.readBytes(endIndex - buf.readerIndex()); + } else { + return buf.readBytes(buf.readableBytes()); // assume full frame + } + } + +} diff --git a/src/org/traccar/protocol/EskyProtocol.java b/src/org/traccar/protocol/EskyProtocol.java new file mode 100644 index 000000000..4c1d11f7d --- /dev/null +++ b/src/org/traccar/protocol/EskyProtocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class EskyProtocol extends BaseProtocol { + + public EskyProtocol() { + super("esky"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new EskyFrameDecoder()); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new EskyProtocolDecoder(EskyProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java new file mode 100644 index 000000000..c12753881 --- /dev/null +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -0,0 +1,92 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class EskyProtocolDecoder extends BaseProtocolDecoder { + + public EskyProtocolDecoder(EskyProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("EO;") // header + .number("d+;") // index + .number("(d+);") // imei + .text("R;") // data type + .number("(d+)").text("+") // satellites + .number("(dd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").text("+") // time + .number("(d+.d+)").text("+") // latitude + .number("(d+.d+)").text("+") // longitude + .number("(d+.d+)").text("+") // speed + .number("(d+)").text("+") // course + .text("0x").number("(d+)").text("+") // input + .number("(d+)").text("+") // message type + .number("(d+)").text("+") // odometer + .number("(d+)") // voltage + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + org.traccar.helper.PatternUtil.MatchResult matchResult = + org.traccar.helper.PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromMps(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextInt()); + position.set(Position.KEY_POWER, parser.nextInt()); + + return position; + } + +} diff --git a/test/org/traccar/protocol/EskyFrameDecoderTest.java b/test/org/traccar/protocol/EskyFrameDecoderTest.java new file mode 100644 index 000000000..34a984bb2 --- /dev/null +++ b/test/org/traccar/protocol/EskyFrameDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class EskyFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + EskyFrameDecoder decoder = new EskyFrameDecoder(); + + verifyFrame( + binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"), + decoder.decode(null, null, binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"))); + + verifyFrame( + binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"), + decoder.decode(null, null, binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"))); + + } + +} diff --git a/test/org/traccar/protocol/EskyProtocolDecoderTest.java b/test/org/traccar/protocol/EskyProtocolDecoderTest.java new file mode 100644 index 000000000..52dff971f --- /dev/null +++ b/test/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class EskyProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + EskyProtocolDecoder decoder = new EskyProtocolDecoder(new EskyProtocol()); + + verifyPosition(decoder, text( + "EO;0;864906029196626;R;0+170808155352+0.00000+0.00000+0.00+0+0x1+0+0+0+1233")); + + } + +} -- cgit v1.2.3 From e90e38d8c5db452adc5ab704a6f9dd84db16ce20 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 12:01:27 +1200 Subject: Advanced TK103 attributes --- src/org/traccar/model/Position.java | 1 + src/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- src/org/traccar/protocol/Tk103ProtocolDecoder.java | 44 ++++++++++++++++++---- src/org/traccar/protocol/TytanProtocolDecoder.java | 2 +- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 3 ++ 5 files changed, 42 insertions(+), 10 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 66a6f91ce..c188124af 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -75,6 +75,7 @@ public class Position extends Message { public static final String KEY_OPERATOR = "operator"; public static final String KEY_COMMAND = "command"; public static final String KEY_BLOCKED = "blocked"; + public static final String KEY_DOOR = "door"; public static final String KEY_DTCS = "dtcs"; public static final String KEY_OBD_SPEED = "obdSpeed"; // knots diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 186867b9d..4cf4a79eb 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -531,7 +531,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x05) { int flags = buf.readUnsignedByte(); - position.set("door", BitUtil.check(flags, 0)); + position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); return position; diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index 0106e5bf3..14278085b 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -50,7 +50,14 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d)(?:d*,)?") // speed .number("(dd)(dd)(dd),?") // time (hhmmss) .number("(d+.?d{1,2}),?") // course - .number("(?:([01]{8})|(x{8}))?,?") // state + .groupBegin() + .number("([01])") // charge + .number("([01])") // ignition + .number("(x)") // io + .number("(x)") // io + .number("(x)") // io + .number("(xxx),?") // fuel + .groupEnd("?") .number("(?:L(x+))?") // odometer .any() .number("([+-]ddd.d)?") // temperature @@ -260,15 +267,36 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble(0)); - String status = parser.next(); - if (status != null) { - position.set(Position.KEY_STATUS, status); // binary status + if (parser.hasNext(6)) { + position.set(Position.KEY_CHARGE, parser.nextInt() == 0); + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - int value = Integer.parseInt(new StringBuilder(status).reverse().toString(), 2); - position.set(Position.KEY_CHARGE, !BitUtil.check(value, 0)); - position.set(Position.KEY_IGNITION, BitUtil.check(value, 1)); + int mask1 = parser.nextHexInt(); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask1, 0)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(mask1, 2)); + if (BitUtil.check(mask1, 3)) { + position.set(Position.KEY_BLOCKED, true); + } + + int mask2 = parser.nextHexInt(); + for (int i = 0; i < 3; i++) { + if (BitUtil.check(mask2, i)) { + position.set("hs" + (3 - i), true); + } + } + if (BitUtil.check(mask2, 3)) { + position.set(Position.KEY_DOOR, true); + } + + int mask3 = parser.nextHexInt(); + for (int i = 1; i <= 3; i++) { + if (BitUtil.check(mask3, i)) { + position.set("hs" + (3 - i + 1), true); + } + } + + position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); } - position.set(Position.KEY_STATUS, parser.next()); // hex status if (parser.hasNext()) { position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); diff --git a/src/org/traccar/protocol/TytanProtocolDecoder.java b/src/org/traccar/protocol/TytanProtocolDecoder.java index 030fbce78..0ae669784 100644 --- a/src/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/org/traccar/protocol/TytanProtocolDecoder.java @@ -111,7 +111,7 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); break; case 150: - position.set("door", buf.readUnsignedByte()); + position.set(Position.KEY_DOOR, buf.readUnsignedByte()); break; default: buf.skipBytes(length); diff --git a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java index f2ee8ffe5..a69ff8856 100644 --- a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { Tk103ProtocolDecoder decoder = new Tk103ProtocolDecoder(new Tk103Protocol()); + verifyPosition(decoder, text( + "(007611121184BR00170816A2401.5217N07447.0788E000.0221352232.340000004FL0030F14F)")); + verifyNull(decoder, text( "(027044702512BP00027044702512HSO01A4)")); -- cgit v1.2.3 From d7725b0fb8ecde4d883a07d8bc4e77974c56eada Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 12:55:25 +1200 Subject: Add Suntech temperature support --- .../traccar/protocol/SuntechProtocolDecoder.java | 50 +++++++++++++++++++++- .../protocol/SuntechProtocolDecoderTest.java | 23 ++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 42e81f60c..93c53d2cf 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -32,18 +32,34 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { private int protocolType; private boolean hbm; + private boolean includeAdc; + private boolean includeTemp; public SuntechProtocolDecoder(SuntechProtocol protocol) { super(protocol); protocolType = Context.getConfig().getInteger(getProtocolName() + ".protocolType"); hbm = Context.getConfig().getBoolean(getProtocolName() + ".hbm"); + includeAdc = Context.getConfig().getBoolean(getProtocolName() + ".includeAdc"); + includeTemp = Context.getConfig().getBoolean(getProtocolName() + ".includeTemp"); } public void setProtocolType(int protocolType) { this.protocolType = protocolType; } + public void setHbm(boolean hbm) { + this.hbm = hbm; + } + + public void setIncludeAdc(boolean includeAdc) { + this.includeAdc = includeAdc; + } + + public void setIncludeTemp(boolean includeTemp) { + this.includeTemp = includeTemp; + } + private Position decode9( Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { int index = 1; @@ -87,7 +103,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setValid(values[index++].equals("1")); if (protocolType == 1) { - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index])); + position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++])); } return position; @@ -155,7 +171,37 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (index < values.length) { - position.set(Position.KEY_BATTERY, Double.parseDouble(values[index])); + position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++])); + } + + if (index < values.length) { + if (values[index++].equals("0")) { + position.set(Position.KEY_ARCHIVE, true); + } + } + + if (includeAdc) { + position.set(Position.PREFIX_ADC + 1, Double.parseDouble(values[index++])); + position.set(Position.PREFIX_ADC + 2, Double.parseDouble(values[index++])); + position.set(Position.PREFIX_ADC + 3, Double.parseDouble(values[index++])); + } + + if (values.length - index >= 2) { + String driverUniqueId = values[index++]; + if (values[index++].equals("1") && !driverUniqueId.isEmpty()) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, driverUniqueId); + } + } + + if (includeTemp) { + for (int i = 1; i <= 3; i++) { + String temperature = values[index++]; + String value = temperature.substring(temperature.indexOf(':') + 1); + if (!value.isEmpty()) { + position.set(Position.PREFIX_TEMP + i, Double.parseDouble(value)); + } + } + } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index a9b13b3e6..bb0710340 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -5,11 +5,34 @@ import org.traccar.ProtocolTest; public class SuntechProtocolDecoderTest extends ProtocolTest { + @Test + public void testDecodeTemperature() throws Exception { + + SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + + decoder.setHbm(true); + decoder.setIncludeAdc(true); + decoder.setIncludeTemp(true); + + /*verifyPosition(decoder, text( + "ST300STT;205170303;12;561;20170816;09:10:34;173f53;+19.082370;-098.214287;006.776;000.00;0;0;52982186;12.75;100000;2;6328;155747;4.2;1;0.00;0;0.00;0.00;00000000000000;0;28F2B7600600005D:+5.2;:;:"));*/ + + verifyPosition(decoder, text( + "ST300STT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); + + verifyPosition(decoder, text( + "ST300EVT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;2;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); + + } + @Test public void testDecode() throws Exception { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "ST300STT;205170303;12;561;20170816;09:10:34;173f53;+19.082370;-098.214287;006.776;000.00;0;0;52982186;12.75;100000;2;6328;155747;4.2;1;0.00;0;0.00;0.00;00000000000000;0;28F2B7600600005D:+5.2;:;:")); + verifyPosition(decoder, text( "ST910;Location;205576803;500;20170319;12:18:17;-22.846014;-046.322176;000.000;000.00;0;3.8;0;1;9159")); -- cgit v1.2.3 From dd5f81b6ccaca626d07f7524abf44d8cb95b4faf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 13:01:46 +1200 Subject: Add Suntech ST500 support --- src/org/traccar/protocol/SuntechProtocolDecoder.java | 10 ++++++---- test/org/traccar/protocol/SuntechProtocolDecoderTest.java | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 93c53d2cf..ec764774d 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -109,7 +109,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decode23( + private Position decode235( Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException { int index = 0; @@ -132,7 +132,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(deviceSession.getDeviceId()); - if (protocol.equals("ST300")) { + if (protocol.equals("ST300") || protocol.equals("ST500")) { index += 1; // model } @@ -142,7 +142,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); position.setTime(dateFormat.parse(values[index++] + values[index++])); - index += 1; // cell + if (!protocol.equals("ST500")) { + index += 1; // cell + } position.setLatitude(Double.parseDouble(values[index++])); position.setLongitude(Double.parseDouble(values[index++])); @@ -220,7 +222,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (protocol.equals("ST910")) { return decode9(channel, remoteAddress, values); } else { - return decode23(channel, remoteAddress, protocol, values); + return decode235(channel, remoteAddress, protocol, values); } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index bb0710340..d46ca3d34 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -30,6 +30,9 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "ST500STT;205450135;07;843;20170816;23:24:45;+19.338432;-099.179817;000.283;000.00;6;1;141121;12.89;0;0;1;4659;002.795;0;001.891;611;4.0")); + verifyPosition(decoder, text( "ST300STT;205170303;12;561;20170816;09:10:34;173f53;+19.082370;-098.214287;006.776;000.00;0;0;52982186;12.75;100000;2;6328;155747;4.2;1;0.00;0;0.00;0.00;00000000000000;0;28F2B7600600005D:+5.2;:;:")); -- cgit v1.2.3 From 128f4be3a22ec1ea9a296be05f67ce20fbdd99d0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 18:06:49 +1200 Subject: Implement another GT06 LBS message --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 23 ++++++++++++++-------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 4cf4a79eb..d8da7e6de 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -69,6 +69,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_1 = 0x16; public static final int MSG_GPS_LBS_STATUS_2 = 0x26; public static final int MSG_GPS_LBS_STATUS_3 = 0x27; + public static final int MSG_LBS_MULTIPLE = 0x28; public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_PHONE = 0x17; public static final int MSG_LBS_EXTEND = 0x18; @@ -406,7 +407,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.setProtocol(getProtocolName()); - if (type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { + if (type == MSG_LBS_MULTIPLE || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { DateBuilder dateBuilder = new DateBuilder(timeZone) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -418,17 +419,23 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mnc = buf.readUnsignedByte(); Network network = new Network(); for (int i = 0; i < 7; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); + int lac = buf.readUnsignedShort(); + int cid = buf.readUnsignedMedium(); + int rssi = -buf.readUnsignedByte(); + if (lac > 0) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); + } } buf.readUnsignedByte(); // time leads - int wifiCount = buf.readUnsignedByte(); - for (int i = 0; i < wifiCount; i++) { - String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + if (type != MSG_LBS_MULTIPLE) { + int wifiCount = buf.readUnsignedByte(); + for (int i = 0; i < wifiCount; i++) { + String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + } } position.setNetwork(network); diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 3c767c908..e449a26d4 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "78783b281108111002050136041bcf0000bf09000000000000000000000000000000000000000000000000000000000000000000000000ff00020007d3280d0a")); + verifyNotNull(decoder, binary( "7878412c11030b011c1f013604cb8a00b17754cb8a00bef357cb8a00b73f5fcb8900b0e25fcb8900b6655fcb8a00b74960cb8a00b178620701001801eb40393800bbbde10d0a")); -- cgit v1.2.3 From aa6c631a0184405b5e67ed6183acbf4c4a6b9536 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 20 Aug 2017 09:34:24 +1200 Subject: Add Watch test case --- test/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/WatchProtocolDecoderTest.java b/test/org/traccar/protocol/WatchProtocolDecoderTest.java index 23e1e35fb..ef77857a3 100644 --- a/test/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { WatchProtocolDecoder decoder = new WatchProtocolDecoder(new WatchProtocol()); + verifyPosition(decoder, buffer( + "[SG*9051007430*006C*UD,150817,132115,V,28.435142,N,81.354333,W,2.2038,000,99,00,70,100,0,50,00000000,1,1,310,260,1091,30082,139,,00]")); + verifyPosition(decoder, buffer( "[3G*6005412902*011F*WT,170517,133811,V,18.512200,N,73.7750283,E,0.00,0.0,0.0,0,92,82,4262,0,00000010,2,1,404,22,10125,8301,141,10125,13921,122,5,Skynet,28:c6:8e:be:87:c0,-60,Intel Wi-Fi,4c:60:de:32:3d:38,-70,Nirvanic-2,40:e3:d6:4a:d9:c2,-73,A4-Guest,40:e3:d6:4a:d9:c4,-73,A4Idatix,40:e3:d6:4a:d9:c3,-73,13.8]")); -- cgit v1.2.3 From 9fb1f19aab9e4535c1c208fdd3dc0e986940b160 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Aug 2017 01:15:46 +1200 Subject: Prevent PatternUtil in production --- src/org/traccar/helper/PatternUtil.java | 7 ++++++- src/org/traccar/protocol/EskyProtocolDecoder.java | 3 --- test/org/traccar/helper/PatternUtilTest.java | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/helper/PatternUtil.java b/src/org/traccar/helper/PatternUtil.java index 12536eaef..1bbb166a6 100644 --- a/src/org/traccar/helper/PatternUtil.java +++ b/src/org/traccar/helper/PatternUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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,6 +15,7 @@ */ package org.traccar.helper; +import java.lang.management.ManagementFactory; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -49,6 +50,10 @@ public final class PatternUtil { public static MatchResult checkPattern(String pattern, String input) { + if (!ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("-agentlib:jdwp")) { + throw new RuntimeException("PatternUtil usage detected"); + } + MatchResult result = new MatchResult(); for (int i = 0; i < pattern.length(); i++) { diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java index c12753881..0d3dcafb2 100644 --- a/src/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -55,9 +55,6 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - org.traccar.helper.PatternUtil.MatchResult matchResult = - org.traccar.helper.PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); - Parser parser = new Parser(PATTERN, (String) msg); if (!parser.matches()) { return null; diff --git a/test/org/traccar/helper/PatternUtilTest.java b/test/org/traccar/helper/PatternUtilTest.java index b6b05e88c..77660078a 100644 --- a/test/org/traccar/helper/PatternUtilTest.java +++ b/test/org/traccar/helper/PatternUtilTest.java @@ -1,11 +1,13 @@ package org.traccar.helper; +import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertEquals; public class PatternUtilTest { - + + @Ignore @Test public void testCheckPattern() { -- cgit v1.2.3 From 7b486504294329c6ac9f6395e3c6b7ca7000acd7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Aug 2017 05:43:54 +1200 Subject: Support Chainway CW801 and CW701 --- src/org/traccar/protocol/CarscopProtocolDecoder.java | 8 ++++++-- test/org/traccar/protocol/CarscopProtocolDecoderTest.java | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/CarscopProtocolDecoder.java b/src/org/traccar/protocol/CarscopProtocolDecoder.java index ac3df1cd7..2a081bcdd 100644 --- a/src/org/traccar/protocol/CarscopProtocolDecoder.java +++ b/src/org/traccar/protocol/CarscopProtocolDecoder.java @@ -44,8 +44,10 @@ public class CarscopProtocolDecoder extends BaseProtocolDecoder { .number("(ddd.d)") // speed .number("(dd)(dd)(dd)") // date (yymmdd) .number("(ddd.dd)") // course + .groupBegin() .number("(d{8})") // state .number("L(d{6})") // odometer + .groupEnd("?") .compile(); @Override @@ -88,8 +90,10 @@ public class CarscopProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble(0)); - position.set(Position.KEY_STATUS, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); + if (parser.hasNext(2)) { + position.set(Position.KEY_STATUS, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextInt(0)); + } return position; } diff --git a/test/org/traccar/protocol/CarscopProtocolDecoderTest.java b/test/org/traccar/protocol/CarscopProtocolDecoderTest.java index 2d6ea208f..7b6f2f28d 100644 --- a/test/org/traccar/protocol/CarscopProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CarscopProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class CarscopProtocolDecoderTest extends ProtocolTest { CarscopProtocolDecoder decoder = new CarscopProtocolDecoder(new CarscopProtocol()); verifyNull(decoder, text( + "*170821223045UB00HSO")); + + verifyPosition(decoder, text( + "*170821223121UB05ORANGE000731512061825V0000.0000N00000.0000E000.0040331309.62")); + + verifyPosition(decoder, text( "*170724163029UB05ORANGE000000010061825V0000.0000N00000.0000E000.0040331309.62")); verifyNull(decoder, text( -- cgit v1.2.3 From ebd193d4d5a98f7b53cc229f1c7287d05465b13e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 23 Aug 2017 00:51:38 +1200 Subject: Handle eSky negative coords --- src/org/traccar/protocol/EskyProtocolDecoder.java | 4 ++-- test/org/traccar/protocol/EskyFrameDecoderTest.java | 4 ++++ test/org/traccar/protocol/EskyProtocolDecoderTest.java | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java index 0d3dcafb2..d524224af 100644 --- a/src/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -40,8 +40,8 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder { .number("(d+)").text("+") // satellites .number("(dd)(dd)(dd)") // date .number("(dd)(dd)(dd)").text("+") // time - .number("(d+.d+)").text("+") // latitude - .number("(d+.d+)").text("+") // longitude + .number("(-?d+.d+)").text("+") // latitude + .number("(-?d+.d+)").text("+") // longitude .number("(d+.d+)").text("+") // speed .number("(d+)").text("+") // course .text("0x").number("(d+)").text("+") // input diff --git a/test/org/traccar/protocol/EskyFrameDecoderTest.java b/test/org/traccar/protocol/EskyFrameDecoderTest.java index 34a984bb2..e8902e8be 100644 --- a/test/org/traccar/protocol/EskyFrameDecoderTest.java +++ b/test/org/traccar/protocol/EskyFrameDecoderTest.java @@ -11,6 +11,10 @@ public class EskyFrameDecoderTest extends ProtocolTest { EskyFrameDecoder decoder = new EskyFrameDecoder(); + verifyFrame( + binary("454c3b313b3836343930363032393139363632363b3137303832323134333432363b"), + decoder.decode(null, null, binary("454c3b313b3836343930363032393139363632363b3137303832323134333432363b"))); + verifyFrame( binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"), decoder.decode(null, null, binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"))); diff --git a/test/org/traccar/protocol/EskyProtocolDecoderTest.java b/test/org/traccar/protocol/EskyProtocolDecoderTest.java index 52dff971f..0617ba8a9 100644 --- a/test/org/traccar/protocol/EskyProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class EskyProtocolDecoderTest extends ProtocolTest { EskyProtocolDecoder decoder = new EskyProtocolDecoder(new EskyProtocol()); + verifyNull(decoder, text( + "EL;1;864906029196626;170822143426;")); + + verifyPosition(decoder, text( + "EO;0;864906029196626;R;7+170822143646+-26.10806+27.94600+0.40+0+0x1+0+102540+0+1242")); + verifyPosition(decoder, text( "EO;0;864906029196626;R;0+170808155352+0.00000+0.00000+0.00+0+0x1+0+0+0+1233")); -- cgit v1.2.3 From 819bca366f89f237f19e52b7a916895ed1761fb9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 26 Aug 2017 09:41:37 +1200 Subject: Decode negative temperature --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 37793a6ff..3bee39cc4 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -614,7 +614,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { for (int i = 1; i <= deviceCount; i++) { index++; // id index++; // type - position.set(Position.PREFIX_TEMP + i, Short.parseShort(data[index++], 16) * 0.0625); + position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index++], 16) * 0.0625); } } } diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index ac58049df..6796f48ee 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyPositions(decoder, buffer( + "+RESP:GTERI,060502,861074023620928,,00000002,27822,10,1,1,0.0,84,2870.9,-78.531796,-0.277329,20170825045344,,,,,,0.0,01138:30:24,,,83,220104,2,1,28FF2776A2150308,1,FFAD,0,20170825045348,A88C$")); + verifyAttributes(decoder, buffer( "+RESP:GTINF,280500,A1000043D20139,GL300VC,41,,31,0,0,,,3.87,0,1,1,,,20170802150751,70,,48.0,,,20170802112145,03AC$")); -- cgit v1.2.3 From 1756cad4ad66f1b5e932c51a8c0891e27d705ec6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 28 Aug 2017 02:58:43 +1200 Subject: Save Watch movement alert as motion --- src/org/traccar/protocol/WatchProtocolDecoder.java | 8 +++++--- test/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index 57f5d7e78..adab65245 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -76,8 +76,6 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_ENTER; } else if (BitUtil.check(status, 3)) { return Position.ALARM_OVERSPEED; - } else if (BitUtil.check(status, 4)) { - return Position.ALARM_MOVEMENT; } else if (BitUtil.check(status, 16)) { return Position.ALARM_SOS; } else if (BitUtil.check(status, 17)) { @@ -209,7 +207,11 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { position.set("steps", parser.nextInt(0)); - position.set(Position.KEY_ALARM, decodeAlarm(parser.nextHexInt(0))); + int status = parser.nextHexInt(0); + position.set(Position.KEY_ALARM, decodeAlarm(status)); + if (BitUtil.check(status, 4)) { + position.set(Position.KEY_MOTION, true); + } decodeTail(position, parser.next()); diff --git a/test/org/traccar/protocol/WatchProtocolDecoderTest.java b/test/org/traccar/protocol/WatchProtocolDecoderTest.java index ef77857a3..c960ccc25 100644 --- a/test/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { WatchProtocolDecoder decoder = new WatchProtocolDecoder(new WatchProtocol()); + verifyPosition(decoder, buffer( + "[3G*8308373902*0080*AL,230817,095346,A,47.083950,N,15.4821850,E,7.60,273.8,0.0,4,15,44,0,0,00200010,2,255,232,1,7605,42530,118,7605,58036,119,0,65.8]")); + verifyPosition(decoder, buffer( "[SG*9051007430*006C*UD,150817,132115,V,28.435142,N,81.354333,W,2.2038,000,99,00,70,100,0,50,00000000,1,1,310,260,1091,30082,139,,00]")); -- cgit v1.2.3 From eb96d365786785c6b2d8743c3a57f09bd3021f5f Mon Sep 17 00:00:00 2001 From: Anshul Jain Date: Mon, 28 Aug 2017 16:13:25 +0530 Subject: Updated test cases. --- test/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index e449a26d4..4042c3bf0 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -161,6 +161,13 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780d1f000000000000000200b196a20d0a")); + verifyPosition(decoder, binary( + "78781f12110819110216d402f250340828924055d4c801944600d300c09501429c830d0a")); + + verifyPosition(decoder, binary( + "78782516110819110208d402f264dc08289a4058d4c70901944600d300c0954606040600014057e90d0a")); + + } } -- cgit v1.2.3 From 8d489fd4290bd93b394f0066983611f25e2e103b Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 28 Aug 2017 16:59:18 +0500 Subject: - Do not filter alarms - Fix division --- src/org/traccar/FilterHandler.java | 12 +++++++++++- test/org/traccar/FilterHandlerTest.java | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 1f5fffc86..ff53c9e25 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -30,6 +30,7 @@ public class FilterHandler extends BaseDataHandler { private int filterDistance; private int filterMaxSpeed; private long filterLimit; + private boolean allowAlarms; public void setFilterInvalid(boolean filterInvalid) { this.filterInvalid = filterInvalid; @@ -67,6 +68,10 @@ public class FilterHandler extends BaseDataHandler { this.filterLimit = filterLimit; } + public void setAllowAlarms(boolean allowAlarms) { + this.allowAlarms = allowAlarms; + } + public FilterHandler() { Config config = Context.getConfig(); if (config != null) { @@ -79,6 +84,7 @@ public class FilterHandler extends BaseDataHandler { filterDistance = config.getInteger("filter.distance"); filterMaxSpeed = config.getInteger("filter.maxSpeed"); filterLimit = config.getLong("filter.limit") * 1000; + allowAlarms = config.getBoolean("filter.allowAlarms"); } } @@ -127,7 +133,7 @@ public class FilterHandler extends BaseDataHandler { if (filterMaxSpeed != 0 && last != null) { double distance = position.getDouble(Position.KEY_DISTANCE); long time = position.getFixTime().getTime() - last.getFixTime().getTime(); - return UnitsConverter.knotsFromMps(distance / (time / 1000)) > filterMaxSpeed; + return UnitsConverter.knotsFromMps(distance / (time / 1000.0)) > filterMaxSpeed; } return false; } @@ -146,6 +152,10 @@ public class FilterHandler extends BaseDataHandler { private boolean filter(Position position) { + if (allowAlarms && position.getAttributes().containsKey(Position.KEY_ALARM)) { + return false; + } + StringBuilder filterType = new StringBuilder(); Position last = null; diff --git a/test/org/traccar/FilterHandlerTest.java b/test/org/traccar/FilterHandlerTest.java index 02023096e..86b84f91f 100644 --- a/test/org/traccar/FilterHandlerTest.java +++ b/test/org/traccar/FilterHandlerTest.java @@ -75,6 +75,10 @@ public class FilterHandlerTest extends BaseTest { assertNull(filtingHandler.decode(null, null, position)); assertNotNull(passingHandler.decode(null, null, position)); + + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + filtingHandler.setAllowAlarms(true); + assertNotNull(filtingHandler.decode(null, null, position)); } } -- cgit v1.2.3 From 57d2621cdf5e318a236b036a9435358121a4adf5 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 29 Aug 2017 08:44:12 +0500 Subject: - Rename parameter - Move Limit to the begining --- src/org/traccar/FilterHandler.java | 30 ++++++++++++++---------------- test/org/traccar/FilterHandlerTest.java | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index ff53c9e25..91fbac68f 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -30,7 +30,7 @@ public class FilterHandler extends BaseDataHandler { private int filterDistance; private int filterMaxSpeed; private long filterLimit; - private boolean allowAlarms; + private boolean keepAlarms; public void setFilterInvalid(boolean filterInvalid) { this.filterInvalid = filterInvalid; @@ -68,8 +68,8 @@ public class FilterHandler extends BaseDataHandler { this.filterLimit = filterLimit; } - public void setAllowAlarms(boolean allowAlarms) { - this.allowAlarms = allowAlarms; + public void setKeepAlarms(boolean keepAlarms) { + this.keepAlarms = keepAlarms; } public FilterHandler() { @@ -84,7 +84,7 @@ public class FilterHandler extends BaseDataHandler { filterDistance = config.getInteger("filter.distance"); filterMaxSpeed = config.getInteger("filter.maxSpeed"); filterLimit = config.getLong("filter.limit") * 1000; - allowAlarms = config.getBoolean("filter.allowAlarms"); + keepAlarms = config.getBoolean("filter.keepAlarms"); } } @@ -132,27 +132,22 @@ public class FilterHandler extends BaseDataHandler { private boolean filterMaxSpeed(Position position, Position last) { if (filterMaxSpeed != 0 && last != null) { double distance = position.getDouble(Position.KEY_DISTANCE); - long time = position.getFixTime().getTime() - last.getFixTime().getTime(); - return UnitsConverter.knotsFromMps(distance / (time / 1000.0)) > filterMaxSpeed; + double time = position.getFixTime().getTime() - last.getFixTime().getTime(); + return UnitsConverter.knotsFromMps(distance / (time / 1000)) > filterMaxSpeed; } return false; } private boolean filterLimit(Position position, Position last) { - if (filterLimit != 0) { - if (last != null) { - return (position.getFixTime().getTime() - last.getFixTime().getTime()) > filterLimit; - } else { - return false; - } - } else { - return false; + if (filterLimit != 0 && last != null) { + return (position.getFixTime().getTime() - last.getFixTime().getTime()) > filterLimit; } + return false; } private boolean filter(Position position) { - if (allowAlarms && position.getAttributes().containsKey(Position.KEY_ALARM)) { + if (keepAlarms && position.getAttributes().containsKey(Position.KEY_ALARM)) { return false; } @@ -163,6 +158,9 @@ public class FilterHandler extends BaseDataHandler { last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); } + if (filterLimit(position, last)) { + filterType.append("Limit "); + } if (filterInvalid(position)) { filterType.append("Invalid "); } @@ -188,7 +186,7 @@ public class FilterHandler extends BaseDataHandler { filterType.append("MaxSpeed "); } - if (filterType.length() > 0 && !filterLimit(position, last)) { + if (filterType.length() > 0) { StringBuilder message = new StringBuilder(); message.append("Position filtered by "); diff --git a/test/org/traccar/FilterHandlerTest.java b/test/org/traccar/FilterHandlerTest.java index 86b84f91f..a2019f81f 100644 --- a/test/org/traccar/FilterHandlerTest.java +++ b/test/org/traccar/FilterHandlerTest.java @@ -77,7 +77,7 @@ public class FilterHandlerTest extends BaseTest { assertNotNull(passingHandler.decode(null, null, position)); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - filtingHandler.setAllowAlarms(true); + filtingHandler.setKeepAlarms(true); assertNotNull(filtingHandler.decode(null, null, position)); } -- cgit v1.2.3 From e1925a35ce309a3cf99c47c8cea599cd53d22b5c Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 29 Aug 2017 10:10:15 +0500 Subject: Rename variables and parameters to skip filtering --- src/org/traccar/FilterHandler.java | 22 +++++++++++----------- test/org/traccar/FilterHandlerTest.java | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 08be43f65..f63fd17dd 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -29,8 +29,8 @@ public class FilterHandler extends BaseDataHandler { private boolean filterStatic; private int filterDistance; private int filterMaxSpeed; - private long filterLimit; - private boolean keepAlarms; + private long skipLimit; + private boolean skipAlarms; public void setFilterInvalid(boolean filterInvalid) { this.filterInvalid = filterInvalid; @@ -64,12 +64,12 @@ public class FilterHandler extends BaseDataHandler { this.filterMaxSpeed = filterMaxSpeed; } - public void setFilterLimit(long filterLimit) { - this.filterLimit = filterLimit; + public void setSkipLimit(long skipLimit) { + this.skipLimit = skipLimit; } - public void setKeepAlarms(boolean keepAlarms) { - this.keepAlarms = keepAlarms; + public void setSkipAlarms(boolean skipAlarms) { + this.skipAlarms = skipAlarms; } public FilterHandler() { @@ -83,8 +83,8 @@ public class FilterHandler extends BaseDataHandler { filterStatic = config.getBoolean("filter.static"); filterDistance = config.getInteger("filter.distance"); filterMaxSpeed = config.getInteger("filter.maxSpeed"); - filterLimit = config.getLong("filter.limit") * 1000; - keepAlarms = config.getBoolean("filter.keepAlarms"); + skipLimit = config.getLong("filter.skipLimit") * 1000; + skipAlarms = config.getBoolean("filter.skipAlarms"); } } @@ -139,14 +139,14 @@ public class FilterHandler extends BaseDataHandler { } private boolean skipLimit(Position position, Position last) { - if (filterLimit != 0 && last != null) { - return (position.getFixTime().getTime() - last.getFixTime().getTime()) > filterLimit; + if (skipLimit != 0 && last != null) { + return (position.getFixTime().getTime() - last.getFixTime().getTime()) > skipLimit; } return false; } private boolean skipAlarms(Position position) { - return keepAlarms && position.getAttributes().containsKey(Position.KEY_ALARM); + return skipAlarms && position.getAttributes().containsKey(Position.KEY_ALARM); } private boolean filter(Position position) { diff --git a/test/org/traccar/FilterHandlerTest.java b/test/org/traccar/FilterHandlerTest.java index a2019f81f..e91566635 100644 --- a/test/org/traccar/FilterHandlerTest.java +++ b/test/org/traccar/FilterHandlerTest.java @@ -27,7 +27,7 @@ public class FilterHandlerTest extends BaseTest { filtingHandler.setFilterStatic(true); filtingHandler.setFilterDistance(10); filtingHandler.setFilterMaxSpeed(500); - filtingHandler.setFilterLimit(10); + filtingHandler.setSkipLimit(10); } @After @@ -77,7 +77,7 @@ public class FilterHandlerTest extends BaseTest { assertNotNull(passingHandler.decode(null, null, position)); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - filtingHandler.setKeepAlarms(true); + filtingHandler.setSkipAlarms(true); assertNotNull(filtingHandler.decode(null, null, position)); } -- cgit v1.2.3 From df43d91b34f9b03aee9fb4cf1be582fb2fc7a688 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 30 Aug 2017 02:12:51 +1200 Subject: Add GV500 OBD test case --- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 6796f48ee..cb515a73e 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyPosition(decoder, buffer( + "+RESP:GTOBD,360701,864251020253807,LSGTC58UX7Y067312,GV500,0,70FFFF,LSGTC58UX7Y067312,1,12309,983A8140,0,0,33,nan,,0,0,0,,10,0,,0,4.4,0,83.7,36.235142,49.967324,20170829112348,0255,0001,2760,9017,00,690.1,20170829112400,3456$")); + verifyPositions(decoder, buffer( "+RESP:GTERI,060502,861074023620928,,00000002,27822,10,1,1,0.0,84,2870.9,-78.531796,-0.277329,20170825045344,,,,,,0.0,01138:30:24,,,83,220104,2,1,28FF2776A2150308,1,FFAD,0,20170825045348,A88C$")); -- cgit v1.2.3 From 1c807549e315d04054b4803518d2624591976324 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Sep 2017 14:09:17 +1200 Subject: Implement Watch custom command --- src/org/traccar/protocol/WatchProtocol.java | 1 + src/org/traccar/protocol/WatchProtocolEncoder.java | 2 ++ test/org/traccar/protocol/WatchProtocolEncoderTest.java | 7 +++++++ 3 files changed, 10 insertions(+) (limited to 'test/org') diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java index 42a640b85..2be2dc9ae 100644 --- a/src/org/traccar/protocol/WatchProtocol.java +++ b/src/org/traccar/protocol/WatchProtocol.java @@ -29,6 +29,7 @@ public class WatchProtocol extends BaseProtocol { public WatchProtocol() { super("watch"); setSupportedDataCommands( + Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_SOS_NUMBER, diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index c5d8fad86..6fcd109c2 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -97,6 +97,8 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin protected Object encodeCommand(Command command) { switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, command.getString(Command.KEY_DATA)); case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "RG"); case Command.TYPE_SOS_NUMBER: diff --git a/test/org/traccar/protocol/WatchProtocolEncoderTest.java b/test/org/traccar/protocol/WatchProtocolEncoderTest.java index a7c360d7f..7184d278e 100644 --- a/test/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -32,6 +32,12 @@ public class WatchProtocolEncoderTest extends ProtocolTest { command.set(Command.KEY_DATA, "3333"); Assert.assertEquals("[CS*123456789012345*0005*TK,33]", encoder.encodeCommand(command)); + command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_CUSTOM); + command.set(Command.KEY_DATA, "WORK,6-9,11-13,13-15,17-19"); + Assert.assertEquals("[CS*123456789012345*001a*WORK,6-9,11-13,13-15,17-19]", encoder.encodeCommand(command)); + command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); @@ -46,6 +52,7 @@ public class WatchProtocolEncoderTest extends ProtocolTest { command.set(Command.KEY_TIMEZONE, -11 * 60 * 60 - 30 * 60); Assert.assertEquals("[CS*123456789012345*0009*LZ,,-11.5]", encoder.encodeCommand(command)); + } } -- cgit v1.2.3 From d0ed5e6964a5e44793b8c72106f09e4ce147f47d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Sep 2017 05:19:40 +1200 Subject: Support CK300 device protocol --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 18 ++++++++++++++++-- .../traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index e05182022..988fd71c8 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -80,7 +80,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("d{14},") // last fix time .groupBegin() .number("(d+),") // battery percentage - .expression("[01]?,") // flash type + .number("[d.]*,") // flash type / power .number("(-?[d.]+)?,,,") // temperature .or() .expression("(?:[01])?,").optional() // pin15 mode @@ -394,7 +394,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return null; } - position.set(Position.KEY_STATUS, parser.next()); + String status = parser.next(); + + if (status.charAt(0) == '2') { + position.set(Position.KEY_IGNITION, true); + } else if (status.charAt(0) == '4') { + position.set(Position.KEY_IGNITION, false); + } + + if (status.charAt(1) == '1') { + position.set(Position.KEY_MOTION, false); + } else if (status.charAt(1) == '2') { + position.set(Position.KEY_MOTION, true); + } + + position.set(Position.KEY_STATUS, status); position.set(Position.KEY_RSSI, parser.nextInt()); diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index cb515a73e..812973fb8 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, buffer( + "+RESP:GTINF,210102,354524044950583,,42,89011702272048900184,11,99,0,,,4.08,0,1,1,0,0,20170831170831,87,0.00,,,,20170831171010,0064$")); + verifyPosition(decoder, buffer( "+RESP:GTOBD,360701,864251020253807,LSGTC58UX7Y067312,GV500,0,70FFFF,LSGTC58UX7Y067312,1,12309,983A8140,0,0,33,nan,,0,0,0,,10,0,,0,4.4,0,83.7,36.235142,49.967324,20170829112348,0255,0001,2760,9017,00,690.1,20170829112400,3456$")); -- cgit v1.2.3 From 99fd421c76c8e7491095a91630516f6d2db27034 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Sep 2017 07:24:06 +1200 Subject: Implement GenX protocol --- setup/default.xml | 1 + src/org/traccar/protocol/GenxProtocol.java | 45 +++++++++++++ src/org/traccar/protocol/GenxProtocolDecoder.java | 75 ++++++++++++++++++++++ .../traccar/protocol/GenxProtocolDecoderTest.java | 21 ++++++ 4 files changed, 142 insertions(+) create mode 100644 src/org/traccar/protocol/GenxProtocol.java create mode 100644 src/org/traccar/protocol/GenxProtocolDecoder.java create mode 100644 test/org/traccar/protocol/GenxProtocolDecoderTest.java (limited to 'test/org') diff --git a/setup/default.xml b/setup/default.xml index fea747c01..d96ceeb6d 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -237,5 +237,6 @@ 5145 5146 5147 + 5148 diff --git a/src/org/traccar/protocol/GenxProtocol.java b/src/org/traccar/protocol/GenxProtocol.java new file mode 100644 index 000000000..deb89e4ae --- /dev/null +++ b/src/org/traccar/protocol/GenxProtocol.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class GenxProtocol extends BaseProtocol { + + public GenxProtocol() { + super("genx"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new GenxProtocolDecoder(GenxProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java new file mode 100644 index 000000000..6d16db9ad --- /dev/null +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -0,0 +1,75 @@ +/* + * Copyright 2017 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.protocol; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; +import org.traccar.DeviceSession; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.text.SimpleDateFormat; + +public class GenxProtocolDecoder extends BaseProtocolDecoder { + + private int[] reportColumns; + + public GenxProtocolDecoder(GenxProtocol protocol) { + super(protocol); + String[] columns = Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4").split(","); + reportColumns = new int[columns.length]; + for (int i = 0; i < columns.length; i++) { + reportColumns[i] = Integer.parseInt(columns[i]); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String[] values = ((String) msg).split(","); + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setValid(true); + + for (int i = 0; i < Math.min(values.length, reportColumns.length); i++) { + switch (reportColumns[i]) { + case 1: + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + break; + case 2: + position.setTime(new SimpleDateFormat("MM/dd/yy HH:mm:ss").parse(values[i])); + break; + case 3: + position.setLatitude(Double.parseDouble(values[i])); + break; + case 4: + position.setLongitude(Double.parseDouble(values[i])); + break; + default: + break; + } + } + + return position; + } + +} diff --git a/test/org/traccar/protocol/GenxProtocolDecoderTest.java b/test/org/traccar/protocol/GenxProtocolDecoderTest.java new file mode 100644 index 000000000..5e99b8fb8 --- /dev/null +++ b/test/org/traccar/protocol/GenxProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class GenxProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + GenxProtocolDecoder decoder = new GenxProtocolDecoder(new GenxProtocol()); + + verifyPosition(decoder, text( + "000036004130,08/31/2017 17:24:13,45.47275,-73.65491,5,19,117,1.14,147,ON,1462,0,6,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U")); + + verifyPosition(decoder, text( + "000036004130,08/31/2017 17:24:37,45.47257,-73.65506,3,0,117,1.14,124,ON,1489,0,5,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U")); + + } + +} -- cgit v1.2.3 From 87392d9fbb0289b5486496b6e6b97db1ea84e2b7 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 4 Sep 2017 18:01:43 +0500 Subject: Accept timezone id instead of offset in commands --- .../traccar/protocol/CityeasyProtocolEncoder.java | 8 +++++--- src/org/traccar/protocol/Jt600ProtocolEncoder.java | 6 ++++-- .../traccar/protocol/MeiligaoProtocolEncoder.java | 5 +++-- .../traccar/protocol/MiniFinderProtocolEncoder.java | 6 ++++-- src/org/traccar/protocol/Pt502ProtocolEncoder.java | 20 ++++++++++++++++++-- src/org/traccar/protocol/WatchProtocolEncoder.java | 6 ++++-- .../protocol/CityeasyProtocolEncoderTest.java | 4 ++-- .../traccar/protocol/Jt600ProtocolEncoderTest.java | 2 +- .../protocol/MeiligaoProtocolEncoderTest.java | 4 ++-- .../protocol/MiniFinderProtocolEncoderTest.java | 6 +++--- .../traccar/protocol/Pt502ProtocolEncoderTest.java | 2 +- .../traccar/protocol/WatchProtocolEncoderTest.java | 8 ++++---- 12 files changed, 51 insertions(+), 26 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/org/traccar/protocol/CityeasyProtocolEncoder.java index c800131d6..387926e03 100644 --- a/src/org/traccar/protocol/CityeasyProtocolEncoder.java +++ b/src/org/traccar/protocol/CityeasyProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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,6 +15,8 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; @@ -56,13 +58,13 @@ public class CityeasyProtocolEncoder extends BaseProtocolEncoder { content.writeShort(0); return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_INTERVAL, content); case Command.TYPE_SET_TIMEZONE: - int timezone = command.getInteger(Command.KEY_TIMEZONE); + int timezone = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; if (timezone < 0) { content.writeByte(1); } else { content.writeByte(0); } - content.writeShort(Math.abs(timezone) / 60); + content.writeShort(Math.abs(timezone)); return encodeContent(CityeasyProtocolDecoder.MSG_TIMEZONE, content); default: Log.warning(new UnsupportedOperationException(command.getType())); diff --git a/src/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/org/traccar/protocol/Jt600ProtocolEncoder.java index 0bf389460..377f104a3 100644 --- a/src/org/traccar/protocol/Jt600ProtocolEncoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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,6 +15,8 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -29,7 +31,7 @@ public class Jt600ProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_ENGINE_RESUME: return "(S07,1)"; case Command.TYPE_SET_TIMEZONE: - int offset = command.getInteger(Command.KEY_TIMEZONE) / 60; + int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; return "(S09,1," + offset + ")"; case Command.TYPE_REBOOT_DEVICE: return "(S17)"; diff --git a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java index 268bae392..2e0a1e84c 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -24,6 +24,7 @@ import org.traccar.model.Command; import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; +import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @@ -78,7 +79,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { content.writeShort(command.getInteger(Command.KEY_RADIUS)); return encodeContent(command.getDeviceId(), MSG_MOVEMENT_ALARM, content); case Command.TYPE_SET_TIMEZONE: - int offset = command.getInteger(Command.KEY_TIMEZONE) / 60; + int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; content.writeBytes(String.valueOf(offset).getBytes(StandardCharsets.US_ASCII)); return encodeContent(command.getDeviceId(), MSG_TIME_ZONE, content); case Command.TYPE_REBOOT_DEVICE: diff --git a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java index e5c43e29a..7cf19d352 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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,6 +15,8 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -27,7 +29,7 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements if (key.equals(Command.KEY_ENABLE)) { return (Boolean) value ? "1" : "0"; } else if (key.equals(Command.KEY_TIMEZONE)) { - return String.format("%+03d", ((Number) value).longValue() / 3600); + return String.format("%+03d", TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000); } else if (key.equals(Command.KEY_INDEX)) { switch (((Number) value).intValue()) { case 0: diff --git a/src/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/org/traccar/protocol/Pt502ProtocolEncoder.java index 5f7665e50..d5e219bd2 100644 --- a/src/org/traccar/protocol/Pt502ProtocolEncoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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,11 +15,27 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -public class Pt502ProtocolEncoder extends StringProtocolEncoder { +public class Pt502ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { + + @Override + public String formatValue(String key, Object value) { + if (key.equals(Command.KEY_TIMEZONE)) { + return String.valueOf(TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000); + } + + return null; + } + + @Override + protected String formatCommand(Command command, String format, String... keys) { + return super.formatCommand(command, format, this, keys); + } @Override protected Object encodeCommand(Command command) { diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index 6fcd109c2..e585a91c1 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -26,13 +26,14 @@ import java.text.DecimalFormatSymbols; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.TimeZone; public class WatchProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { @Override public String formatValue(String key, Object value) { if (key.equals(Command.KEY_TIMEZONE)) { - double offset = ((Number) value).longValue() / 3600.0; + double offset = TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000.0; DecimalFormat fmt = new DecimalFormat("+#.##;-#.##", DecimalFormatSymbols.getInstance(Locale.US)); return fmt.format(offset); } @@ -41,6 +42,7 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin } + @Override protected String formatCommand(Command command, String format, String... keys) { String content = super.formatCommand(command, format, this, keys); return String.format("[CS*%s*%04x*%s]", diff --git a/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java b/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java index 96b3c2b74..7c03b7d5b 100644 --- a/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java +++ b/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java @@ -10,11 +10,11 @@ public class CityeasyProtocolEncoderTest extends ProtocolTest { public void testEncode() throws Exception { CityeasyProtocolEncoder encoder = new CityeasyProtocolEncoder(); - + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 6 * 3600); + command.set(Command.KEY_TIMEZONE, "GMT+6"); verifyCommand(encoder, command, binary("5353001100080001680000000B60820D0A")); diff --git a/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java b/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java index 80802dc35..100d7492a 100644 --- a/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java @@ -25,7 +25,7 @@ public class Jt600ProtocolEncoderTest extends ProtocolTest { @Test public void testSetTimezone() throws Exception { command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 240 * 60); + command.set(Command.KEY_TIMEZONE, "GMT+4"); assertEquals("(S09,1,240)", encoder.encodeCommand(command)); } diff --git a/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index f9d77f8a6..ee4a869f9 100644 --- a/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java +++ b/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java @@ -10,7 +10,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { public void testEncode() throws Exception { MeiligaoProtocolEncoder encoder = new MeiligaoProtocolEncoder(); - + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_SINGLE); @@ -23,7 +23,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { verifyCommand(encoder, command, binary("40400013123456789012344102000a2f4f0d0a")); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 480 * 60); + command.set(Command.KEY_TIMEZONE, "GMT+8"); verifyCommand(encoder, command, binary("4040001412345678901234413234383030ad0d0a")); diff --git a/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java b/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java index 99b250ebc..360ea0008 100644 --- a/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java +++ b/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java @@ -11,12 +11,12 @@ public class MiniFinderProtocolEncoderTest extends ProtocolTest { public void testEncode() throws Exception { MiniFinderProtocolEncoder encoder = new MiniFinderProtocolEncoder(); - + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 3600); - + command.set(Command.KEY_TIMEZONE, "GMT+1"); + Assert.assertEquals("123456L+01", encoder.encodeCommand(command)); command = new Command(); diff --git a/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java index ab6446010..62406d3f2 100644 --- a/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java +++ b/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java @@ -30,7 +30,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 8); + command.set(Command.KEY_TIMEZONE, "GMT+8"); Assert.assertEquals("#TMZ8\r\n", encoder.encodeCommand(command)); diff --git a/test/org/traccar/protocol/WatchProtocolEncoderTest.java b/test/org/traccar/protocol/WatchProtocolEncoderTest.java index 7184d278e..cffe373cf 100644 --- a/test/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -41,16 +41,16 @@ public class WatchProtocolEncoderTest extends ProtocolTest { command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 60 * 60); + command.set(Command.KEY_TIMEZONE, "Europe/Amsterdam"); Assert.assertEquals("[CS*123456789012345*0006*LZ,,+1]", encoder.encodeCommand(command)); - command.set(Command.KEY_TIMEZONE, 90 * 60); + command.set(Command.KEY_TIMEZONE, "GMT+01:30"); Assert.assertEquals("[CS*123456789012345*0008*LZ,,+1.5]", encoder.encodeCommand(command)); - command.set(Command.KEY_TIMEZONE, -60 * 60); + command.set(Command.KEY_TIMEZONE, "Atlantic/Azores"); Assert.assertEquals("[CS*123456789012345*0006*LZ,,-1]", encoder.encodeCommand(command)); - command.set(Command.KEY_TIMEZONE, -11 * 60 * 60 - 30 * 60); + command.set(Command.KEY_TIMEZONE, "GMT-11:30"); Assert.assertEquals("[CS*123456789012345*0009*LZ,,-11.5]", encoder.encodeCommand(command)); } -- cgit v1.2.3 From 36c62f0f2ca21ccd5040f8529f446b1b697dba69 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Sep 2017 09:40:28 +1200 Subject: Fix EV07 login decoding --- src/org/traccar/protocol/MiniFinderProtocolDecoder.java | 6 +++++- test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java index 8bfb4fb36..05994b697 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -133,7 +133,11 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; if (sentence.startsWith("!1,")) { - getDeviceSession(channel, remoteAddress, sentence.substring(3, sentence.length())); + int index = sentence.indexOf(',', 3); + if (index < 0) { + index = sentence.length(); + } + getDeviceSession(channel, remoteAddress, sentence.substring(3, index)); return null; } diff --git a/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index fd16df779..b9003a25d 100644 --- a/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { MiniFinderProtocolDecoder decoder = new MiniFinderProtocolDecoder(new MiniFinderProtocol()); + verifyNull(decoder, text( + "!1,867273023933661,V07S.5701.1621,100")); + verifyNull(decoder, text( "!1,123456789012345")); -- cgit v1.2.3 From 9ebd2a934a5ca3a61863f839733bff321ba30296 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 7 Sep 2017 11:33:22 +0500 Subject: Handle correct and incorrect attribute types --- src/org/traccar/database/DeviceManager.java | 45 ++++++++-------------- src/org/traccar/model/ExtendedModel.java | 2 +- src/org/traccar/notification/NotificationMail.java | 2 +- .../traccar/notification/PropertiesProvider.java | 10 +++++ .../traccar/protocol/OsmAndProtocolDecoder.java | 12 +++++- test/org/traccar/ProtocolTest.java | 4 ++ .../protocol/OsmAndProtocolDecoderTest.java | 3 ++ 7 files changed, 45 insertions(+), 33 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index a485d6dc6..9bc221aa3 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -262,59 +262,44 @@ public class DeviceManager extends BaseObjectManager implements Identity public boolean lookupAttributeBoolean( long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Boolean.parseBoolean(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Boolean.parseBoolean(result.toString()) : defaultValue; } public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result; - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? result.toString() : defaultValue; } public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Integer.parseInt(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Integer.parseInt(result.toString()) : defaultValue; } public long lookupAttributeLong( long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Long.parseLong(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Long.parseLong(result.toString()) : defaultValue; } public double lookupAttributeDouble( long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Double.parseDouble(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Double.parseDouble(result.toString()) : defaultValue; } - private String lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { - String result = null; + private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { + Object result = null; Device device = getById(deviceId); if (device != null) { - result = device.getString(attributeName); + result = device.getAttributes().get(attributeName); if (result == null && lookupGroupsAttribute) { long groupId = device.getGroupId(); while (groupId != 0) { Group group = Context.getGroupsManager().getById(groupId); if (group != null) { - result = group.getString(attributeName); + result = group.getAttributes().get(attributeName); if (result != null) { break; } @@ -329,7 +314,7 @@ public class DeviceManager extends BaseObjectManager implements Identity result = Context.getConfig().getString(attributeName); } else { Server server = Context.getPermissionsManager().getServer(); - result = server.getString(attributeName); + result = server.getAttributes().get(attributeName); } } } diff --git a/src/org/traccar/model/ExtendedModel.java b/src/org/traccar/model/ExtendedModel.java index a4bf00e70..2ce503eea 100644 --- a/src/org/traccar/model/ExtendedModel.java +++ b/src/org/traccar/model/ExtendedModel.java @@ -100,7 +100,7 @@ public class ExtendedModel extends BaseModel { public boolean getBoolean(String key) { if (attributes.containsKey(key)) { - return Boolean.parseBoolean(attributes.get(key).toString()); + return (Boolean) attributes.get(key); } else { return false; } diff --git a/src/org/traccar/notification/NotificationMail.java b/src/org/traccar/notification/NotificationMail.java index d7f3bf64c..fc70a6115 100644 --- a/src/org/traccar/notification/NotificationMail.java +++ b/src/org/traccar/notification/NotificationMail.java @@ -43,7 +43,7 @@ public final class NotificationMail { if (host != null) { properties.put("mail.transport.protocol", provider.getString("mail.transport.protocol", "smtp")); properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", provider.getString("mail.smtp.port", "25")); + properties.put("mail.smtp.port", String.valueOf(provider.getInteger("mail.smtp.port", 25))); String starttlsEnable = provider.getString("mail.smtp.starttls.enable"); if (starttlsEnable != null) { diff --git a/src/org/traccar/notification/PropertiesProvider.java b/src/org/traccar/notification/PropertiesProvider.java index 2fea901af..1a4104d2b 100644 --- a/src/org/traccar/notification/PropertiesProvider.java +++ b/src/org/traccar/notification/PropertiesProvider.java @@ -48,4 +48,14 @@ public class PropertiesProvider { return value; } + public int getInteger(String key, int defaultValue) { + if (config != null) { + return config.getInteger(key, defaultValue); + } else if (extendedModel.getAttributes().containsKey(key)) { + return Integer.parseInt(extendedModel.getAttributes().get(key).toString()); + } else { + return defaultValue; + } + } + } diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index c06582a15..15a71c88b 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -135,7 +135,17 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { try { position.set(entry.getKey(), Double.parseDouble(value)); } catch (NumberFormatException e) { - position.set(entry.getKey(), value); + switch (value) { + case "true": + position.set(entry.getKey(), true); + break; + case "false": + position.set(entry.getKey(), false); + break; + default: + position.set(entry.getKey(), value); + break; + } } break; } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index a2c7e4f21..7bff41acd 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -241,6 +241,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_CHARGE) instanceof Boolean); } + if (attributes.containsKey(Position.KEY_IGNITION)) { + Assert.assertTrue(attributes.get(Position.KEY_IGNITION) instanceof Boolean); + } + if (attributes.containsKey(Position.KEY_MOTION)) { Assert.assertTrue(attributes.get(Position.KEY_MOTION) instanceof Boolean); } diff --git a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java index 2d0ef0adf..af860f371 100644 --- a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java +++ b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java @@ -37,6 +37,9 @@ public class OsmAndProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, request( "/?id=123456×tamp=1377177267&location=60.0,30.0")); + verifyPosition(decoder, request( + "/?id=123456789012345×tamp=1504763810&lat=40.7232948571&lon=-74.0061408571&bearing=7.19889788244&speed=40&ignition=true&rpm=933&fuel=24")); + } } -- cgit v1.2.3 From 5e481bfc1596de062093c5bc01cf168ed906aafc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 03:13:09 +1200 Subject: Support H02 V3 message type --- src/org/traccar/protocol/H02ProtocolDecoder.java | 62 ++++++++++++++++++++++ .../traccar/protocol/H02ProtocolDecoderTest.java | 11 ++-- 2 files changed, 69 insertions(+), 4 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index aa3d47650..091d97cdd 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -222,6 +222,24 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_V3 = new PatternBuilder() + .text("*") + .expression("..,") // manufacturer + .number("(d+),") // imei + .text("V3,") + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(ddd)") // mcc + .number("(d+),") // mnc + .number("(d+),") // count + .expression("(.*),") // cell info + .number("(x{4}),") // battery + .number("d+,") // reboot info + .text("X,") + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(x{8})") // status + .text("#").optional() + .compile(); + private Position decodeText(String sentence, Channel channel, SocketAddress remoteAddress) { Parser parser = new Parser(PATTERN, sentence); @@ -366,6 +384,48 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeV3(String sentence, Channel channel, SocketAddress remoteAddress) { + + Parser parser = new Parser(PATTERN_V3, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + + int mcc = parser.nextInt(); + int mnc = parser.nextInt(); + + int count = parser.nextInt(); + Network network = new Network(); + String[] values = parser.next().split(","); + for (int i = 0; i < count; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, Integer.parseInt(values[i * 4]), Integer.parseInt(values[i * 4 + 1]))); + } + position.setNetwork(network); + + position.set(Position.KEY_BATTERY, parser.nextHexInt()); + + dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + + getLastLocation(position, dateBuilder.getDate()); + + processStatus(position, parser.nextLong(16, 0)); + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -385,6 +445,8 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { return decodeLbs(sentence, channel, remoteAddress); case "LINK": return decodeLink(sentence, channel, remoteAddress); + case "V3": + return decodeV3(sentence, channel, remoteAddress); default: return decodeText(sentence, channel, remoteAddress); } diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 48f4d987e..a14d57c3c 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyAttributes(decoder, buffer( + "*HQ,353111080001055,V3,044855,28403,01,001450,011473,158,-62,0292,0,X,030817,FFFFFBFF#")); + verifyPosition(decoder, binary( "2442091341332059572807175137358006000183640e000000fffffbfdff001f080000000000ea1e0000000021")); @@ -20,10 +23,10 @@ public class H02ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "*HQ,1700086468,LINK,180902,15,0,84,0,0,240517,FFFFFBFF#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020882405,V3,095426,74001,01,010278,045142,128,-92,02DE,0,X,090517,FFFFFBFF#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020882405,V3,095426,74001,04,010278,045142,128,-92,010278,026311,125,,010278,026582,125,,010278,028322,119,,02DD,0,X,090517,FFFFFBFF#")); verifyPosition(decoder, buffer( @@ -50,7 +53,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "*HQ,4109179024,NBR,103732,722,310,0,6,8106,32010,23,8101,22007,25,8106,12010,23,8106,22105,22,8101,22012,16,8106,42010,5,100217,FFFFFBFF,5#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020930796,V3,002339,62160,06,024852,035421,148,0,024852,035425,143,,022251,036482,137,,024852,000335,133,,024852,031751,133,,024852,035423,133,,02A1,0,X,010104,EFE7FBFF#")); verifyPosition(decoder, buffer( @@ -80,7 +83,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "*HQ,1600068860,LINK,112137,20,8,67,0,0,081116,FFFFFBFF#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020533263,V3,121536,65501,04,000152,014001,156,-64,000161,010642,138,,000152,014003,129,,000152,013973,126,,02E4,0,X,071116,FFFFFBFF#")); verifyPosition(decoder, buffer( -- cgit v1.2.3 From 3aebd92cc3781b417ded6260d1300434b1418e7e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 04:45:40 +1200 Subject: Handle GOOME status message --- src/org/traccar/protocol/EelinkProtocolDecoder.java | 4 +++- test/org/traccar/protocol/EelinkProtocolDecoderTest.java | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 11d111e54..2526282b1 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -160,7 +160,9 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { if (statusType == 0x01 || statusType == 0x02 || statusType == 0x03) { buf.readUnsignedInt(); // device time - decodeStatus(position, buf.readUnsignedShort()); + if (buf.readableBytes() >= 2) { + decodeStatus(position, buf.readUnsignedShort()); + } } } diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index 46c85d89a..d62357fe3 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,12 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "676705002102b459ae7388fcd360d7034332b1000000028f000a4f64002eb101010159ae7388")); + + verifyPosition(decoder, binary( + "676702001c02b259ae7387fcd360d6034332b2000000028f000a4f64002eb10101")); + verifyPosition(decoder, binary( "6767050022001F59643640000000000000000000000001CC0000249500142000015964A6C0006E")); -- cgit v1.2.3 From 179373c6b3d619922a5daf98220ffe831f56fba2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 05:44:29 +1200 Subject: Improve TRV decoder logic --- src/org/traccar/model/ExtendedModel.java | 4 +- src/org/traccar/protocol/TrvProtocolDecoder.java | 68 +++++++++++++++------- .../traccar/protocol/TrvProtocolDecoderTest.java | 9 +++ 3 files changed, 59 insertions(+), 22 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/ExtendedModel.java b/src/org/traccar/model/ExtendedModel.java index 2ce503eea..8353d0e66 100644 --- a/src/org/traccar/model/ExtendedModel.java +++ b/src/org/traccar/model/ExtendedModel.java @@ -31,7 +31,9 @@ public class ExtendedModel extends BaseModel { } public void set(String key, Boolean value) { - attributes.put(key, value); + if (value != null) { + attributes.put(key, value); + } } public void set(String key, Byte value) { diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java index 1783bce73..918748f7b 100644 --- a/src/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/org/traccar/protocol/TrvProtocolDecoder.java @@ -53,8 +53,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)") // satellites .number("(ddd)") // battery .number("(d)") // acc - .number("dd") // arm status - .number("dd,") // working mode + .number("(dd)") // arm status + .number("(dd),") // working mode .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -71,9 +71,41 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode + .groupBegin() + .number("(ddd)") // interval + .number("d") // vibration alarm + .number("ddd") // vibration sensitivity + .number("d") // automatic arm + .number("dddd") // automatic arm time + .number("(d)") // blocked + .number("(d)") // power status + .number("(d)") // movement status + .groupEnd("?") .any() .compile(); + private Boolean decodeOptionalValue(Parser parser, int activeValue) { + int value = parser.nextInt(); + if (value != 0) { + return value == activeValue; + } + return null; + } + + private void decodeCommon(Position position, Parser parser) { + + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_BATTERY, parser.nextInt()); + position.set(Position.KEY_IGNITION, decodeOptionalValue(parser, 1)); + position.set(Position.KEY_ARMED, decodeOptionalValue(parser, 1)); + + int mode = parser.nextInt(); + if (mode != 0) { + position.set("mode", mode); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -118,13 +150,13 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - position.set(Position.KEY_IGNITION, parser.nextInt(0) != 0); + decodeCommon(position, parser); - position.set("arm", parser.nextInt(0)); - position.set("mode", parser.nextInt(0)); + if (parser.hasNext(3)) { + position.set(Position.KEY_BLOCKED, decodeOptionalValue(parser, 2)); + position.set(Position.KEY_CHARGE, decodeOptionalValue(parser, 1)); + position.set(Position.KEY_MOTION, decodeOptionalValue(parser, 1)); + } return position; @@ -140,31 +172,25 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setValid(parser.next().equals("A")); position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + dateBuilder.setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); - position.setCourse(parser.nextDouble(0)); + position.setCourse(parser.nextDouble()); - int rssi = parser.nextInt(0); - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - - int acc = parser.nextInt(0); - if (acc != 0) { - position.set(Position.KEY_IGNITION, acc == 1); - } + decodeCommon(position, parser); position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), rssi))); + parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()))); return position; + } return null; diff --git a/test/org/traccar/protocol/TrvProtocolDecoderTest.java b/test/org/traccar/protocol/TrvProtocolDecoderTest.java index 319455b9f..a4c0d3343 100644 --- a/test/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -10,6 +10,15 @@ public class TrvProtocolDecoderTest extends ProtocolTest { TrvProtocolDecoder decoder = new TrvProtocolDecoder(new TrvProtocol()); + verifyNull(decoder, text( + "TRVAP00352121088015548")); + + verifyPosition(decoder, text( + "TRVAP01170905A5227.1382N00541.4256E001.7095844000.0008100610020100,204,8,3230,13007")); + + verifyAttributes(decoder, text( + "TRVCP01,07800010010000602001206001120124")); + verifyNull(decoder, text( "IWAP00353456789012345")); -- cgit v1.2.3 From e84d1addacd76c05416c31b9e10b6a1618e41c9d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 07:30:17 +1200 Subject: Improve H02 protocol decoder --- src/org/traccar/protocol/H02ProtocolDecoder.java | 43 +++++++++++++++------- .../traccar/protocol/H02ProtocolDecoderTest.java | 13 +++++-- 2 files changed, 39 insertions(+), 17 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index 091d97cdd..69e53ec27 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -150,9 +150,20 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .text("*") .expression("..,") // manufacturer .number("(d+),") // imei - .expression("[^,]+,") + .groupBegin() + .text("VP1,") + .expression("[ABV],") + .or() + .groupBegin() + .text("V1,") + .or() + .text("V4,") .any() + .or() + .text("V19,") + .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) + .groupEnd() .expression("([AV])?,") // validity .groupBegin() .number("-(d+)-(d+.d+),") // latitude @@ -169,25 +180,28 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .number("(d+.?d*),") // speed .number("(d+.?d*)?,") // course .number("(?:(dd)(dd)(dd))?") // date (ddmmyy) - .any() - .number(",(x{8})") // status + .groupBegin() + .expression(",[^,]*,") + .expression("[^,]*,") + .expression("[^,]*") // sim info + .groupEnd("?") + .groupBegin() + .number(",(x{8})") .groupBegin() .number(",(d+),") // odometer .number("(-?d+),") // temperature .number("(d+.d+),") // fuel .number("(-?d+),") // altitude .number("(x+),") // lac - .number("(x+)#") // cid + .number("(x+)") // cid .or() - .number(",(d+),") - .number("(d+),") - .number("(d+),") - .number("(d+)#") + .text(",") + .expression("(.*)") // data .or() - .expression(",.*") + .groupEnd() .or() - .text("#") .groupEnd() + .text("#") .compile(); private static final Pattern PATTERN_NBR = new PatternBuilder() @@ -289,7 +303,9 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setTime(new Date()); } - processStatus(position, parser.nextLong(16, 0)); + if (parser.hasNext()) { + processStatus(position, parser.nextLong(16, 0)); + } if (parser.hasNext(6)) { position.set(Position.KEY_ODOMETER, parser.nextInt(0)); @@ -302,8 +318,9 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(4)) { - for (int i = 1; i <= 4; i++) { - position.set(Position.PREFIX_IO + i, parser.nextInt(0)); + String[] values = parser.next().split(","); + for (int i = 0; i < values.length; i++) { + position.set(Position.PREFIX_IO + (i + 1), values[i].trim()); } } diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index a14d57c3c..0b90a4767 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,15 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyPosition(decoder, buffer( + "*HQ,4209951296,V19,214452,A,5201.0178,N,01830.5029,E,000.00,000,200417,,195.63.13.195,89480610500392633029,BFFFFBFF#")); + + verifyNull(decoder, buffer( + "*hq,356327080425330,VP1,A,2702.7215,S,15251.9309,E,0.62,0.0000,050917#")); + + verifyNull(decoder, buffer( + "*HQ,356327080425330,XT,1,100#")); + verifyAttributes(decoder, buffer( "*HQ,353111080001055,V3,044855,28403,01,001450,011473,158,-62,0292,0,X,030817,FFFFFBFF#")); @@ -215,10 +224,6 @@ public class H02ProtocolDecoderTest extends ProtocolTest { "*HQ,2705171109,V1,213324,A,5002.5849,N,01433.7822,E,0.00,000,140613,FFFFFFFF#"), Position.KEY_STATUS, 0xFFFFFFFFL); - verifyAttribute(decoder, buffer( - "*HQ,4109179024,V19,181519,V,3853.2587,S,06205.9175,W,000.00,000,090217,,5492932630888,8954315265044716555?,FFFFFBFF#"), - Position.KEY_STATUS, 0xFFFFFBFFL); - verifyAttribute(decoder, binary( "2441091144271222470112142233983006114026520E000000FFFFFBFFFF0014060000000001CC00262B0F170A"), Position.KEY_STATUS, 0xFFFFFBFFL); -- cgit v1.2.3 From 640770638943146f5c2e7dcfb0c05b84fc9b3cff Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 8 Sep 2017 11:08:38 +0500 Subject: Implement skipping filtering by list of attributes --- src/org/traccar/FilterHandler.java | 23 ++++++++---- test/org/traccar/BaseTest.java | 8 ++--- test/org/traccar/FilterHandlerTest.java | 64 +++++++++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 13 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index f63fd17dd..4cd3eb0eb 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -30,7 +30,7 @@ public class FilterHandler extends BaseDataHandler { private int filterDistance; private int filterMaxSpeed; private long skipLimit; - private boolean skipAlarms; + private boolean skipAttributes; public void setFilterInvalid(boolean filterInvalid) { this.filterInvalid = filterInvalid; @@ -68,8 +68,8 @@ public class FilterHandler extends BaseDataHandler { this.skipLimit = skipLimit; } - public void setSkipAlarms(boolean skipAlarms) { - this.skipAlarms = skipAlarms; + public void setSkipAttributes(boolean skipAttributes) { + this.skipAttributes = skipAttributes; } public FilterHandler() { @@ -84,7 +84,7 @@ public class FilterHandler extends BaseDataHandler { filterDistance = config.getInteger("filter.distance"); filterMaxSpeed = config.getInteger("filter.maxSpeed"); skipLimit = config.getLong("filter.skipLimit") * 1000; - skipAlarms = config.getBoolean("filter.skipAlarms"); + skipAttributes = config.getBoolean("filter.skipAttributes.enable"); } } @@ -145,8 +145,17 @@ public class FilterHandler extends BaseDataHandler { return false; } - private boolean skipAlarms(Position position) { - return skipAlarms && position.getAttributes().containsKey(Position.KEY_ALARM); + private boolean skipAttributes(Position position) { + if (skipAttributes) { + String attributesString = Context.getIdentityManager().lookupAttributeString( + position.getDeviceId(), "filter.skipAttributes", "", true); + for (String attribute : attributesString.split("[ ,]")) { + if (position.getAttributes().containsKey(attribute)) { + return true; + } + } + } + return false; } private boolean filter(Position position) { @@ -158,7 +167,7 @@ public class FilterHandler extends BaseDataHandler { last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); } - if (skipLimit(position, last) || skipAlarms(position)) { + if (skipLimit(position, last) || skipAttributes(position)) { return false; } diff --git a/test/org/traccar/BaseTest.java b/test/org/traccar/BaseTest.java index 37956f11d..4b9ee5451 100644 --- a/test/org/traccar/BaseTest.java +++ b/test/org/traccar/BaseTest.java @@ -40,25 +40,25 @@ public class BaseTest { @Override public boolean lookupAttributeBoolean( long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { - return false; + return defaultValue; } @Override public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { - return null; + return defaultValue; } @Override public int lookupAttributeInteger( long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { - return 0; + return defaultValue; } @Override public long lookupAttributeLong( long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { - return 0; + return defaultValue; } }); diff --git a/test/org/traccar/FilterHandlerTest.java b/test/org/traccar/FilterHandlerTest.java index e91566635..7ebab3af5 100644 --- a/test/org/traccar/FilterHandlerTest.java +++ b/test/org/traccar/FilterHandlerTest.java @@ -3,6 +3,8 @@ package org.traccar; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; import java.util.Date; @@ -10,7 +12,65 @@ import java.util.Date; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -public class FilterHandlerTest extends BaseTest { +public class FilterHandlerTest { + + static { + Context.init(new IdentityManager() { + + private Device createDevice() { + Device device = new Device(); + device.setId(1); + device.setName("test"); + device.setUniqueId("123456789012345"); + return device; + } + + @Override + public Device getById(long id) { + return createDevice(); + } + + @Override + public Device getByUniqueId(String uniqueId) { + return createDevice(); + } + + @Override + public Position getLastPosition(long deviceId) { + return null; + } + + @Override + public boolean isLatestPosition(Position position) { + return true; + } + + @Override + public boolean lookupAttributeBoolean( + long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { + return defaultValue; + } + + @Override + public String lookupAttributeString( + long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { + return "alarm,result"; + } + + @Override + public int lookupAttributeInteger( + long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { + return defaultValue; + } + + @Override + public long lookupAttributeLong( + long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { + return defaultValue; + } + + }); + } private FilterHandler filtingHandler; private FilterHandler passingHandler; @@ -77,7 +137,7 @@ public class FilterHandlerTest extends BaseTest { assertNotNull(passingHandler.decode(null, null, position)); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - filtingHandler.setSkipAlarms(true); + filtingHandler.setSkipAttributes(true); assertNotNull(filtingHandler.decode(null, null, position)); } -- cgit v1.2.3 From 12586966b63f58e5a008b17f8689110fcd3f5809 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 23:56:00 +1200 Subject: Fix H02 simple message decoding --- src/org/traccar/protocol/H02ProtocolDecoder.java | 3 +-- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index c31f9edbb..aea8f0b3b 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -152,7 +152,6 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // imei .groupBegin() .text("VP1,") - .expression("[ABV],") .or() .groupBegin() .text("V1,") @@ -164,7 +163,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) .groupEnd() - .expression("([AV])?,") // validity + .expression("([ABV])?,") // validity .groupBegin() .number("-(d+)-(d+.d+),") // latitude .or() diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 0b90a4767..103746e5e 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,10 +11,13 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyPosition(decoder, buffer( + "*hq,356327080425330,VP1,A,2702.7245,S,15251.9311,E,0.48,0.0000,080917#")); + verifyPosition(decoder, buffer( "*HQ,4209951296,V19,214452,A,5201.0178,N,01830.5029,E,000.00,000,200417,,195.63.13.195,89480610500392633029,BFFFFBFF#")); - verifyNull(decoder, buffer( + verifyPosition(decoder, buffer( "*hq,356327080425330,VP1,A,2702.7215,S,15251.9309,E,0.62,0.0000,050917#")); verifyNull(decoder, buffer( -- cgit v1.2.3 From 61ebffb15c72a0c73dfb82de7c62bce537019d9e Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sat, 9 Sep 2017 23:33:37 +0300 Subject: Add ADM test cases --- .../traccar/protocol/AdmProtocolEncoderTest.java | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/org/traccar/protocol/AdmProtocolEncoderTest.java (limited to 'test/org') diff --git a/test/org/traccar/protocol/AdmProtocolEncoderTest.java b/test/org/traccar/protocol/AdmProtocolEncoderTest.java new file mode 100644 index 000000000..3a72036bf --- /dev/null +++ b/test/org/traccar/protocol/AdmProtocolEncoderTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com) + * + * 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.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class AdmProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + AdmProtocolEncoder encoder = new AdmProtocolEncoder(); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_GET_DEVICE_STATUS); + verifyCommand(encoder, command, binary("5354415455530D0A")); + + command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_CUSTOM); + command.set(Command.KEY_DATA, "INPUT 0"); + verifyCommand(encoder, command, binary("494E50555420300D0A")); + } + +} -- cgit v1.2.3 From 07e4e89be6e658239125a8b99e05ce4d132e1d9e Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sun, 10 Sep 2017 01:51:31 +0300 Subject: Inherit AdmProtocolEncoder from StringProtocolEncoder --- src/org/traccar/protocol/AdmProtocol.java | 4 +++- src/org/traccar/protocol/AdmProtocolEncoder.java | 19 ++++--------------- test/org/traccar/protocol/AdmProtocolEncoderTest.java | 5 +++-- 3 files changed, 10 insertions(+), 18 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/AdmProtocol.java b/src/org/traccar/protocol/AdmProtocol.java index db2adfeaa..4d2cbe7b3 100644 --- a/src/org/traccar/protocol/AdmProtocol.java +++ b/src/org/traccar/protocol/AdmProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -40,6 +41,7 @@ public class AdmProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 1, -3, 0)); + pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new AdmProtocolEncoder()); pipeline.addLast("objectDecoder", new AdmProtocolDecoder(AdmProtocol.this)); } diff --git a/src/org/traccar/protocol/AdmProtocolEncoder.java b/src/org/traccar/protocol/AdmProtocolEncoder.java index 1cdfbf0b0..8cbd8618d 100644 --- a/src/org/traccar/protocol/AdmProtocolEncoder.java +++ b/src/org/traccar/protocol/AdmProtocolEncoder.java @@ -16,32 +16,21 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.traccar.BaseProtocolEncoder; +import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -import java.nio.charset.StandardCharsets; - -public class AdmProtocolEncoder extends BaseProtocolEncoder { - - private ChannelBuffer encodeContent(String data) { - ChannelBuffer buf = ChannelBuffers.copiedBuffer(data, StandardCharsets.UTF_8); - buf.writeByte(0x0D); - buf.writeByte(0x0A); - return buf; - } +public class AdmProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { switch (command.getType()) { case Command.TYPE_GET_DEVICE_STATUS: - return encodeContent("STATUS"); + return formatCommand(command, "STATUS\r\n"); case Command.TYPE_CUSTOM: - return encodeContent(command.getString(Command.KEY_DATA)); + return formatCommand(command, "{%s}\r\n", Command.KEY_DATA); default: Log.warning(new UnsupportedOperationException(command.getType())); diff --git a/test/org/traccar/protocol/AdmProtocolEncoderTest.java b/test/org/traccar/protocol/AdmProtocolEncoderTest.java index 3a72036bf..6d2452e26 100644 --- a/test/org/traccar/protocol/AdmProtocolEncoderTest.java +++ b/test/org/traccar/protocol/AdmProtocolEncoderTest.java @@ -16,6 +16,7 @@ */ package org.traccar.protocol; +import org.junit.Assert; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; @@ -30,13 +31,13 @@ public class AdmProtocolEncoderTest extends ProtocolTest { Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_GET_DEVICE_STATUS); - verifyCommand(encoder, command, binary("5354415455530D0A")); + Assert.assertEquals("STATUS\r\n", encoder.encodeCommand(command)); command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_CUSTOM); command.set(Command.KEY_DATA, "INPUT 0"); - verifyCommand(encoder, command, binary("494E50555420300D0A")); + Assert.assertEquals("INPUT 0\r\n", encoder.encodeCommand(command)); } } -- cgit v1.2.3 From 871b9a9c611388394dcbc2eb5ed0e5e30a5411c2 Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sun, 10 Sep 2017 12:08:44 +0300 Subject: Add test case for command response --- test/org/traccar/protocol/AdmProtocolDecoderTest.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/AdmProtocolDecoderTest.java b/test/org/traccar/protocol/AdmProtocolDecoderTest.java index 4299001c3..9a7f91d26 100644 --- a/test/org/traccar/protocol/AdmProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AdmProtocolDecoderTest.java @@ -30,6 +30,8 @@ public class AdmProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, binary(ByteOrder.LITTLE_ENDIAN, "01002200333508202000000000000000007F0D9F030000000000E39A1056E24A8210")); + verifyNotNull(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "01008449443d3120536f66743d30783531204750533d313036382054696d653d30383a35393a32302031302e30392e31372056616c3d30204c61743d36312e36373738204c6f6e3d35302e3832343520563d3020536174436e743d342b3720537461743d30783030313020496e5f616c61726d3d30783030000000000000000000000000")); } } -- cgit v1.2.3 From 753779ee7c3e08693ccb349fb51fee9f8fa8858c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Sep 2017 21:47:23 +1200 Subject: Add CalAmp test case --- test/org/traccar/protocol/CalAmpProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java b/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java index bf0fcf41c..ecbef341d 100644 --- a/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class CalAmpProtocolDecoderTest extends ProtocolTest { CalAmpProtocolDecoder decoder = new CalAmpProtocolDecoder(new CalAmpProtocol()); + verifyPosition(decoder, binary( + "83051633033459010101028afd59ae7c1459ae7c140b06bbce2c01520e0000d916000001b900450900005affa50f091f00260d040000000f24000001b90000000000003714")); + verifyPosition(decoder, binary( "83092701131797081078220107010200dc583d4d3f583d4d3f19c70502cd1d512d00005f180000008500ec0800101eff980f090100313102000000000000000000")); -- cgit v1.2.3 From b7210be4600bca6731700702c4f135ff9e263a89 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Sep 2017 01:14:58 +1200 Subject: Add H02 no GPS test case --- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 103746e5e..59882a91f 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyNull(decoder, buffer( + "*HQ,353505510948929,V1,,V,,N,,E,0.00,0,,FFFFF7FF,f0,a,11a0,c0c6#")); + verifyPosition(decoder, buffer( "*hq,356327080425330,VP1,A,2702.7245,S,15251.9311,E,0.48,0.0000,080917#")); -- cgit v1.2.3 From 195e7b5b45c08fa4fad4f9c8797f8807ded1dbea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Sep 2017 23:13:03 +1200 Subject: Support universal Suntech format --- .../traccar/protocol/SuntechProtocolDecoder.java | 116 ++++++++++++++++++--- .../protocol/SuntechProtocolDecoderTest.java | 6 ++ 2 files changed, 108 insertions(+), 14 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 39804159f..3b350ba64 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -19,6 +19,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -70,19 +71,19 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return null; } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + if (deviceSession == null) { + return null; + } + Position position = new Position(); position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); if (type.equals("Emergency") || type.equals("Alert")) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - if (!type.equals("Alert") || protocolType == 0) { position.set(Position.KEY_VERSION_FW, values[index++]); } @@ -137,15 +138,15 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.set(Position.KEY_TYPE, type); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); if (protocol.equals("ST300") || protocol.equals("ST500")) { index += 1; // model @@ -242,18 +243,105 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeUniversal( + Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { + int index = 0; + + String type = values[index++]; + + if (!type.equals("STT")) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); + + int mask = Integer.parseInt(values[index++], 16); + + if (BitUtil.check(mask, 1)) { + index += 1; // model + } + + if (BitUtil.check(mask, 2)) { + position.set(Position.KEY_VERSION_FW, values[index++]); + } + + if (BitUtil.check(mask, 3) && values[index++].equals("0")) { + position.set(Position.KEY_ARCHIVE, true); + } + + if (BitUtil.check(mask, 4) && BitUtil.check(mask, 5)) { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(values[index++] + values[index++])); + } + + if (BitUtil.check(mask, 6)) { + index += 1; // cell + } + + if (BitUtil.check(mask, 7)) { + index += 1; // mcc + } + + if (BitUtil.check(mask, 8)) { + index += 1; // mnc + } + + if (BitUtil.check(mask, 9)) { + index += 1; // lac + } + + if (BitUtil.check(mask, 10)) { + position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); + } + + if (BitUtil.check(mask, 11)) { + position.setLatitude(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 12)) { + position.setLongitude(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 13)) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + } + + if (BitUtil.check(mask, 14)) { + position.setCourse(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 15)) { + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + } + + if (BitUtil.check(mask, 16)) { + position.setValid(values[index++].equals("1")); + } + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String[] values = ((String) msg).split(";"); - String protocol = values[0].substring(0, 5); - - if (protocol.equals("ST910")) { + if (values[0].length() < 5) { + return decodeUniversal(channel, remoteAddress, values); + } else if (values[0].equals("ST910")) { return decode9(channel, remoteAddress, values); } else { - return decode235(channel, remoteAddress, protocol, values); + return decode235(channel, remoteAddress, values[0].substring(0, 5), values); } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index d46ca3d34..45230a339 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -30,6 +30,12 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "STT;100850000;3FFFFF;26;010;1;20161117;08:37:39;0000004F;450;0;0014;20;+37.479323;+126.887827;62.03;65.43;10;1;00000101;00001000;1;2;0492")); + + verifyPosition(decoder, text( + "STT;6009999006;3FFFFF;26;398;0;20170827;20:04:37;087d4760;310;410;0ba0;23;+40.123420;-074.995971;000.031;000.00;8;1;00000001;00000000;1;1;0006")); + verifyPosition(decoder, text( "ST500STT;205450135;07;843;20170816;23:24:45;+19.338432;-099.179817;000.283;000.00;6;1;141121;12.89;0;0;1;4659;002.795;0;001.891;611;4.0")); -- cgit v1.2.3 From e05f0b83a911c522123a5a2cd14d6c16bd2de027 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Sep 2017 04:38:18 +1200 Subject: Fix GV200 INF message decoding --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 988fd71c8..090e02812 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -65,7 +65,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:[0-9A-Z]{17},)?") // vin .expression("(?:[^,]+)?,") // device name .number("(xx),") // state - .expression("(?:[0-9F]{20})?,") // iccid + .expression("(?:[0-9Ff]{20})?,") // iccid .number("(d{1,2}),") // rssi .number("d{1,2},") .expression("[01],") // external power diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 812973fb8..2b0395e48 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, buffer( + "+RESP:GTINF,04040E,861074023747143,gv200,41,8959301000648637556f,24,0,1,0,1,4.4,0,1,0,0,20170912221854,0,00,01,-0500,1,20170912193448,1D5B$")); + verifyAttributes(decoder, buffer( "+RESP:GTINF,210102,354524044950583,,42,89011702272048900184,11,99,0,,,4.08,0,1,1,0,0,20170831170831,87,0.00,,,,20170831171010,0064$")); -- cgit v1.2.3 From c82fd979ad17ecfb7dd8f3e366c067b66f4cdabc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 15 Sep 2017 02:46:40 +1200 Subject: Handle MVT380 no power value --- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 2 +- test/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 469ef3f76..2d0590f5e 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -69,7 +69,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { .number("(x+)?|") // adc2 .number("(x+)?|") // adc3 .number("(x+)|") // battery - .number("(x+),") // power + .number("(x+)?,") // power .groupBegin() .expression("([^,]+)?,") // event specific .expression("[^,]*,") // reserved diff --git a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java index d50cae8bc..cbbbd17f6 100644 --- a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { MeitrackProtocolDecoder decoder = new MeitrackProtocolDecoder(new MeitrackProtocol()); + verifyPosition(decoder, buffer( + "$$B136,011691002364761,AAA,29,47.055220,28.893193,170914144240,V,0,7,0,0,0,132,129754946,129793197,259|2|02F8|413F,0000,000D|000C||028C|,*9E")); + verifyNotNull(decoder, buffer( "$$F153,863835026880190,AAA,29,25.313160,55.422473,170628150902,V,0,0,0,0,0.0,0,6553,6697,0|0|0000|00000000,0000,0002|0000|0000|018B|0000,,,3,0000,,110,386*22")); -- cgit v1.2.3 From bb599edbd964dd036f3433625034ce985cfc4eef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Sep 2017 10:23:39 +1200 Subject: Handle all Telic formats --- src/org/traccar/protocol/TelicProtocolDecoder.java | 2 +- test/org/traccar/protocol/TelicProtocolDecoderTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index a875009a1..2c0d714c6 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -35,7 +35,7 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("dddd") .number("(d{6}|d{15})") // device id - .number("(dd),") // type + .number("(d{1,2}),") // type .number("d{12},") // event time .number("d+,") .number("(dd)(dd)(dd)") // date (ddmmyy) diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index 84b6a797b..ed8245e1f 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -13,6 +13,12 @@ public class TelicProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "0026355565071347499|206|01|001002008")); + verifyPosition(decoder, text( + "052028495198,160917073641,0,160917073642,43879,511958,3,24,223,17,,,-3,142379,,0010,00,64,205,0,0499")); + + verifyPosition(decoder, text( + "01302849516,160917073503,0,160917073504,43907,512006,3,11,160,14,,,-7,141811,,0010,00,64,206,0,0499")); + verifyPosition(decoder, text( "002135556507134749999,010817171138,0,010817171138,004560973,50667173,3,0,0,11,1,1,100,958071,20601,000000,00,4142,0000,0000,0208,10395,0")); -- cgit v1.2.3 From bfdd87a80fb57e065dfb84d6d10f5339f77fdaf4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Sep 2017 07:44:00 +1200 Subject: Fix Aplicom EBS decoding --- .../traccar/protocol/AplicomProtocolDecoder.java | 98 +++++++++++----------- .../protocol/AplicomProtocolDecoderTest.java | 3 + 2 files changed, 52 insertions(+), 49 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index ef02cda7e..94d12c633 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -470,59 +470,59 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // length while (buf.readableBytes() > 0) { - position.set("towedPosition", buf.readUnsignedByte()); + buf.readUnsignedByte(); // towed position int type = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); + int end = buf.readerIndex() + length; - if (type == 0x01) { - position.set("brakeFlags", ChannelBuffers.hexDump(buf.readBytes(length))); - } else if (type == 0x02) { - position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); - position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0); - position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5); - position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0); - } else if (type == 0x03) { - position.set("axleLoadSum", buf.readUnsignedShort() * 2); - } else if (type == 0x04) { - position.set("tyrePressure", buf.readUnsignedByte() * 10); - position.set("pneumaticPressure", buf.readUnsignedByte() * 5); - } else if (type == 0x05) { - position.set("brakeLining", buf.readUnsignedByte() * 0.4); - position.set("brakeTemperature", buf.readUnsignedByte() * 10); - } else if (type == 0x06) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 5); - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5); - position.set(Position.KEY_ODOMETER_SERVICE, (buf.readUnsignedInt() - 2105540607) * 5); - } else if (type == 0x0A) { - ChannelBuffer brakeData = buf.readBytes(length); - position.set("absStatusCounter", brakeData.readUnsignedShort()); - position.set("atvbStatusCounter", brakeData.readUnsignedShort()); - position.set("vdcActiveCounter", brakeData.readUnsignedShort()); - } else if (type == 0x0B) { - position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length))); - } else if (type == 0x0C) { - position.set("missingPgn", ChannelBuffers.hexDump(buf.readBytes(length))); - } else if (type == 0x0D) { - switch (buf.readUnsignedByte()) { - case 1: - position.set("brakeManufacturer", "Wabco"); - break; - case 2: - position.set("brakeManufacturer", "Knorr"); - break; - case 3: - position.set("brakeManufacturer", "Haldex"); - break; - default: - position.set("brakeManufacturer", "Unknown"); - break; - } - buf.readUnsignedByte(); - position.set(Position.KEY_VIN, buf.readBytes(17).toString(StandardCharsets.US_ASCII)); - position.set("towedDetectionStatus", buf.readUnsignedByte()); - } else if (type == 0x0E) { - buf.skipBytes(length); + switch (type) { + case 0x01: + position.set("brakeFlags", ChannelBuffers.hexDump(buf.readBytes(length))); + break; + case 0x02: + position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); + position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0); + position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5); + position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0); + break; + case 0x03: + position.set("axleLoadSum", buf.readUnsignedShort() * 2); + break; + case 0x04: + position.set("tyrePressure", buf.readUnsignedByte() * 10); + position.set("pneumaticPressure", buf.readUnsignedByte() * 5); + break; + case 0x05: + position.set("brakeLining", buf.readUnsignedByte() * 0.4); + position.set("brakeTemperature", buf.readUnsignedByte() * 10); + break; + case 0x06: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 5L); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5L); + position.set(Position.KEY_ODOMETER_SERVICE, (buf.readUnsignedInt() - 2105540607) * 5L); + break; + case 0x0A: + position.set("absStatusCounter", buf.readUnsignedShort()); + position.set("atvbStatusCounter", buf.readUnsignedShort()); + position.set("vdcActiveCounter", buf.readUnsignedShort()); + break; + case 0x0B: + position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length))); + break; + case 0x0C: + position.set("missingPgn", ChannelBuffers.hexDump(buf.readBytes(length))); + break; + case 0x0D: + buf.readUnsignedByte(); + position.set("towedDetectionStatus", buf.readUnsignedInt()); + buf.skipBytes(17); // vin + break; + case 0x0E: + default: + break; } + + buf.readerIndex(end); } } diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 2498d94b3..862cff055 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol()); + verifyAttributes(decoder, binary( + "44c30144f667c4316500e903ffdfbc00f059aebeb659aebeb302e3f5860065fe32120000ae0000000e47000000000000000000000000000127cd0000014c00000000000000ff010a002900000000000000014542016d0001010090070e140144f667c4316559ae620402e3f7f300660714c0010d15ff0f3332373937313100000000000000000000002a01010737341d331fffcf0103020b8601060c0001a5860001a58600000000010b1001ca01ca7d007d007c7cffffffffffff010a240000ffff0000000100010001ffff0000ffffffffffffffffffffffffffff00000002ffff010c06fec6febffeec")); + verifyAttributes(decoder, binary( "45c20144f667c06ff9005d0161ef17000104596da2dc4b10c0c01d99020d6c04004cba7a010d44463030303235333731363238303030000000000000000000000000000000000000000000000000000001010d44463030303235333731363238303030000000000000031c")); -- cgit v1.2.3 From 561c616418918da4bb1d75c95347e25c23f72f6a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Sep 2017 21:58:04 +1200 Subject: Add Meitrack unit test --- test/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java index cbbbd17f6..07411dbc8 100644 --- a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { MeitrackProtocolDecoder decoder = new MeitrackProtocolDecoder(new MeitrackProtocol()); + verifyPosition(decoder, buffer( + "$$V177,863835026871173,AAA,35,34.516428,10.470160,170915154043,A,9,12,68,74,0.9,9,1988259,525882,605|2|008C|0007B5A6,0200,0003|0000|0000|01A6|0571,00000001,,3,0000,010A92,360,511*74")); + verifyPosition(decoder, buffer( "$$B136,011691002364761,AAA,29,47.055220,28.893193,170914144240,V,0,7,0,0,0,132,129754946,129793197,259|2|02F8|413F,0000,000D|000C||028C|,*9E")); -- cgit v1.2.3 From 849878cf105baed2348c605f7232012efb294480 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Sep 2017 05:57:33 +1200 Subject: Add genx format setter --- src/org/traccar/protocol/GenxProtocolDecoder.java | 6 +++++- test/org/traccar/protocol/GenxProtocolDecoderTest.java | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java index 1f9e5512c..3b716796c 100644 --- a/src/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -30,7 +30,11 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { public GenxProtocolDecoder(GenxProtocol protocol) { super(protocol); - String[] columns = Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4").split(","); + setReportColumns(Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); + } + + public void setReportColumns(String format) { + String[] columns = format.split(","); reportColumns = new int[columns.length]; for (int i = 0; i < columns.length; i++) { reportColumns[i] = Integer.parseInt(columns[i]); diff --git a/test/org/traccar/protocol/GenxProtocolDecoderTest.java b/test/org/traccar/protocol/GenxProtocolDecoderTest.java index 5e99b8fb8..43d9e7d6e 100644 --- a/test/org/traccar/protocol/GenxProtocolDecoderTest.java +++ b/test/org/traccar/protocol/GenxProtocolDecoderTest.java @@ -16,6 +16,11 @@ public class GenxProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "000036004130,08/31/2017 17:24:37,45.47257,-73.65506,3,0,117,1.14,124,ON,1489,0,5,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U")); + decoder.setReportColumns("1,2,3,4"); + + verifyPosition(decoder, text( + "000036035855,04/16/2017 21:19:07,45.46485,-73.65424,24,32,61:213,342.51,157,ON,20984,0,12,O,18,0.000,95.0,24.0,1990,64.0894,0.0219,316.009,71,0.00,16.78,5.10,NA,U,UUU,0,-95.0,U")); + } } -- cgit v1.2.3 From 6aaa8dd3b3ffff7927325616efb9b9bdd8228a67 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 21 Sep 2017 10:53:55 +0500 Subject: Make check for valid in MotionEventHandler optional --- src/org/traccar/Context.java | 3 ++- src/org/traccar/events/FuelDropEventHandler.java | 2 +- src/org/traccar/events/MotionEventHandler.java | 3 ++- src/org/traccar/reports/model/TripsConfig.java | 13 ++++++++++++- test/org/traccar/events/MotionEventHandlerTest.java | 6 +++--- test/org/traccar/reports/ReportUtilsTest.java | 16 ++++++++-------- 6 files changed, 28 insertions(+), 15 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 340eb742c..cf857178f 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -258,7 +258,8 @@ public final class Context { config.getLong("report.trip.minimalTripDuration", 300) * 1000, config.getLong("report.trip.minimalParkingDuration", 300) * 1000, config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000, - config.getBoolean("report.trip.useIgnition")); + config.getBoolean("report.trip.useIgnition"), + config.getBoolean("event.motion.processInvalidPositions")); } public static void init(String[] arguments) throws Exception { diff --git a/src/org/traccar/events/FuelDropEventHandler.java b/src/org/traccar/events/FuelDropEventHandler.java index 4fc512162..2ee3e1a58 100644 --- a/src/org/traccar/events/FuelDropEventHandler.java +++ b/src/org/traccar/events/FuelDropEventHandler.java @@ -35,7 +35,7 @@ public class FuelDropEventHandler extends BaseEventHandler { if (device == null) { return null; } - if (!Context.getIdentityManager().isLatestPosition(position) || !position.getValid()) { + if (!Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index ae64c10ea..0c1c4848f 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -109,7 +109,8 @@ public class MotionEventHandler extends BaseEventHandler { if (device == null) { return null; } - if (!Context.getIdentityManager().isLatestPosition(position) || !position.getValid()) { + if (!Context.getIdentityManager().isLatestPosition(position) + || !tripsConfig.getProcessInvalidPositions() && !position.getValid()) { return null; } diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java index 22fddd072..ca361a466 100644 --- a/src/org/traccar/reports/model/TripsConfig.java +++ b/src/org/traccar/reports/model/TripsConfig.java @@ -22,12 +22,13 @@ public class TripsConfig { } public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition) { + long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; this.minimalNoDataDuration = minimalNoDataDuration; this.useIgnition = useIgnition; + this.processInvalidPositions = processInvalidPositions; } private double minimalTripDistance; @@ -80,4 +81,14 @@ public class TripsConfig { this.useIgnition = useIgnition; } + private boolean processInvalidPositions; + + public boolean getProcessInvalidPositions() { + return processInvalidPositions; + } + + public void setProcessInvalidPositions(boolean processInvalidPositions) { + this.processInvalidPositions = processInvalidPositions; + } + } diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index b88328e58..a2e5cf651 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -31,7 +31,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -72,7 +72,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithStatus() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false)); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 360000)); @@ -93,7 +93,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testStopWithPositionIgnition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, 0, true)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0, true, false)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index 261291255..23fdbd0b1 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -80,7 +80,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:06:00.000", 0, 3000), position("2016-01-01 00:07:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); @@ -132,7 +132,7 @@ public class ReportUtilsTest extends BaseTest { data.get(5).set(Position.KEY_IGNITION, false); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false); Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); @@ -200,7 +200,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:10:00.000", 0, 7000), position("2016-01-01 00:11:00.000", 0, 7000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); @@ -248,7 +248,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); @@ -274,7 +274,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); @@ -300,7 +300,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 0, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); @@ -326,7 +326,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); @@ -348,7 +348,7 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false); + TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false); Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); -- cgit v1.2.3 From 36ad4ac525b8eb25ac1c2eed8c05d690754399c5 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 21 Sep 2017 18:01:10 +0500 Subject: Move speedThreshold to TripsConfig --- src/org/traccar/BasePipelineFactory.java | 2 +- src/org/traccar/Context.java | 3 +- src/org/traccar/reports/ReportUtils.java | 11 +++--- src/org/traccar/reports/Stops.java | 4 +-- src/org/traccar/reports/Trips.java | 4 +-- src/org/traccar/reports/model/TripsConfig.java | 13 ++++++- .../org/traccar/events/MotionEventHandlerTest.java | 6 ++-- test/org/traccar/reports/ReportUtilsTest.java | 42 +++++++++++----------- 8 files changed, 46 insertions(+), 39 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index ac1d450c5..771ab8acb 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -153,7 +153,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { Context.getConfig().getBoolean("geolocation.processInvalidPositions")); } - motionHandler = new MotionHandler(Context.getConfig().getDouble("event.motion.speedThreshold", 0.01)); + motionHandler = new MotionHandler(Context.getTripsConfig().getSpeedThreshold()); if (Context.getConfig().hasKey("location.latitudeHemisphere") || Context.getConfig().hasKey("location.longitudeHemisphere")) { diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index cf857178f..3b24c6460 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -259,7 +259,8 @@ public final class Context { config.getLong("report.trip.minimalParkingDuration", 300) * 1000, config.getLong("report.trip.minimalNoDataDuration", 3600) * 1000, config.getBoolean("report.trip.useIgnition"), - config.getBoolean("event.motion.processInvalidPositions")); + config.getBoolean("event.motion.processInvalidPositions"), + config.getDouble("event.motion.speedThreshold", 0.01)); } public static void init(String[] arguments) throws Exception { diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 5f718feac..f6f386e99 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -253,8 +253,7 @@ public final class ReportUtils { } } - private static boolean isMoving(ArrayList positions, int index, - TripsConfig tripsConfig, double speedThreshold) { + private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { if (tripsConfig.getMinimalNoDataDuration() > 0) { boolean beforeGap = index < positions.size() - 1 && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() @@ -270,12 +269,12 @@ public final class ReportUtils { && 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; + return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); } } public static Collection detectTripsAndStops(Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, double speedThreshold, Class reportClass) { + TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); @@ -283,12 +282,12 @@ public final class ReportUtils { boolean trips = reportClass.equals(TripReport.class); MotionEventHandler motionHandler = new MotionEventHandler(tripsConfig); DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig, speedThreshold)); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { Map event = motionHandler.updateMotionState(deviceState, positions.get(i), - isMoving(positions, i, tripsConfig, speedThreshold)); + isMoving(positions, i, tripsConfig)); if (startEventIndex == -1 && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null || trips == deviceState.getMotionState() && event != null)) { diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 1e72cc927..14b3a2437 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -39,14 +39,12 @@ public final class Stops { } private static Collection detectStops(long deviceId, Date from, Date to) throws SQLException { - double speedThreshold = Context.getConfig().getDouble("event.motion.speedThreshold", 0.01); - boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); Collection result = ReportUtils.detectTripsAndStops( Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, speedThreshold, StopReport.class); + Context.getTripsConfig(), ignoreOdometer, StopReport.class); return result; } diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 1ee62e87c..696defa94 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -38,14 +38,12 @@ public final class Trips { } private static Collection detectTrips(long deviceId, Date from, Date to) throws SQLException { - double speedThreshold = Context.getConfig().getDouble("event.motion.speedThreshold", 0.01); - boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); Collection result = ReportUtils.detectTripsAndStops( Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, speedThreshold, TripReport.class); + Context.getTripsConfig(), ignoreOdometer, TripReport.class); return result; } diff --git a/src/org/traccar/reports/model/TripsConfig.java b/src/org/traccar/reports/model/TripsConfig.java index ca361a466..0f0c615d3 100644 --- a/src/org/traccar/reports/model/TripsConfig.java +++ b/src/org/traccar/reports/model/TripsConfig.java @@ -22,13 +22,14 @@ public class TripsConfig { } public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions) { + long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; this.minimalParkingDuration = minimalParkingDuration; this.minimalNoDataDuration = minimalNoDataDuration; this.useIgnition = useIgnition; this.processInvalidPositions = processInvalidPositions; + this.speedThreshold = speedThreshold; } private double minimalTripDistance; @@ -91,4 +92,14 @@ public class TripsConfig { this.processInvalidPositions = processInvalidPositions; } + private double speedThreshold; + + public double getSpeedThreshold() { + return speedThreshold; + } + + public void setSpeedThreshold(double speedThreshold) { + this.speedThreshold = speedThreshold; + } + } diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index a2e5cf651..3fc63adf0 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -31,7 +31,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithPosition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false, 0.01)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); @@ -72,7 +72,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testMotionWithStatus() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false, 0.01)); Position position = new Position(); position.setTime(new Date(System.currentTimeMillis() - 360000)); @@ -93,7 +93,7 @@ public class MotionEventHandlerTest extends BaseTest { @Test public void testStopWithPositionIgnition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( - new TripsConfig(500, 300 * 1000, 300 * 1000, 0, true, false)); + new TripsConfig(500, 300 * 1000, 300 * 1000, 0, true, false, 0.01)); Position position = new Position(); position.setTime(date("2017-01-01 00:00:00")); diff --git a/test/org/traccar/reports/ReportUtilsTest.java b/test/org/traccar/reports/ReportUtilsTest.java index 23fdbd0b1..4f7a4eb68 100644 --- a/test/org/traccar/reports/ReportUtilsTest.java +++ b/test/org/traccar/reports/ReportUtilsTest.java @@ -80,9 +80,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:06:00.000", 0, 3000), position("2016-01-01 00:07:00.000", 0, 3000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -96,7 +96,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -132,9 +132,9 @@ public class ReportUtilsTest extends BaseTest { data.get(5).set(Position.KEY_IGNITION, false); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -148,7 +148,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -162,7 +162,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -200,9 +200,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:10:00.000", 0, 7000), position("2016-01-01 00:11:00.000", 0, 7000)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -216,7 +216,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -248,9 +248,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -274,9 +274,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 1, 0), position("2016-01-01 00:05:00.000", 2, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -300,9 +300,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 0, 0), position("2016-01-01 00:05:00.000", 0, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -326,9 +326,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:04:00.000", 5, 0), position("2016-01-01 00:05:00.000", 5, 0)); - TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -348,9 +348,9 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:24:00.000", 5, 800), position("2016-01-01 00:25:00.000", 5, 900)); - TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false); + TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops(data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -364,7 +364,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, 0.01, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops(data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From a5643fa4ddbf3b2788eaf100e065b7ff30a49f13 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Sep 2017 10:14:40 +1300 Subject: Add eeLink unit test --- test/org/traccar/protocol/EelinkProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index d62357fe3..ca2bb463e 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "6767050020213b59c6aecdff41dce70b8b977d00000001fe000a36e30078fe010159c6aecd")); + verifyPosition(decoder, binary( "676705002102b459ae7388fcd360d7034332b1000000028f000a4f64002eb101010159ae7388")); -- cgit v1.2.3 From 62e2696c2d8e619d90cb978fa60f714312649866 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Sep 2017 14:45:14 +1300 Subject: Support additional eeLink parameters --- src/org/traccar/model/Position.java | 1 + .../traccar/protocol/EelinkProtocolDecoder.java | 41 ++++++++++++++++++++++ src/org/traccar/protocol/H02ProtocolDecoder.java | 2 +- src/org/traccar/protocol/WatchProtocolDecoder.java | 2 +- .../protocol/EelinkProtocolDecoderTest.java | 3 ++ 5 files changed, 47 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index c188124af..31af3d38a 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -37,6 +37,7 @@ public class Position extends Message { public static final String KEY_ODOMETER_SERVICE = "serviceOdometer"; // meters public static final String KEY_ODOMETER_TRIP = "tripOdometer"; // meters public static final String KEY_HOURS = "hours"; + public static final String KEY_STEPS = "steps"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; public static final String KEY_IMAGE = "image"; diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 2526282b1..8d0f8016a 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -217,6 +217,45 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(7); // bss2 } + if (buf.readableBytes() >= 2) { + int status = buf.readUnsignedShort(); + position.setValid(BitUtil.check(status, 0)); + if (BitUtil.check(status, 1)) { + position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); + } + position.set(Position.KEY_STATUS, status); + } + + if (buf.readableBytes() >= 2) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + } + + if (buf.readableBytes() >= 4) { + position.set(Position.PREFIX_ADC + 0, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + } + + if (buf.readableBytes() >= 4) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } + + if (buf.readableBytes() >= 4) { + buf.readUnsignedShort(); // gsm counter + buf.readUnsignedShort(); // gps counter + } + + if (buf.readableBytes() >= 4) { + position.set(Position.KEY_STEPS, buf.readUnsignedShort()); + buf.readUnsignedShort(); // walking time + } + + if (buf.readableBytes() >= 12) { + position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort() / 256.0); + position.set("humidity", buf.readUnsignedShort() * 0.1); + position.set("illuminance", buf.readUnsignedInt() / 256.0); + position.set("co2", buf.readUnsignedInt()); + } + return position; } @@ -240,6 +279,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(buf.readBytes(8)).substring(1)); } else { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; @@ -262,6 +302,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; } + } return null; diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index aea8f0b3b..e4b18e277 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -392,7 +392,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, parser.nextInt()); position.set(Position.KEY_SATELLITES, parser.nextInt()); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set("steps", parser.nextInt()); + position.set(Position.KEY_STEPS, parser.nextInt()); position.set("turnovers", parser.nextInt()); dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index adab65245..86dc9456d 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -205,7 +205,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, parser.nextInt(0)); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - position.set("steps", parser.nextInt(0)); + position.set(Position.KEY_STEPS, parser.nextInt(0)); int status = parser.nextHexInt(0); position.set(Position.KEY_ALARM, decodeAlarm(status)); diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index ca2bb463e..115eef1a3 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "6767120048000559c1829213059a7400008e277d000c000000000800cc00080d2a000034df3cf0b429dd82cad3048910320000000000007b7320d005ba0000000019a000000000000000000000")); + verifyPosition(decoder, binary( "6767050020213b59c6aecdff41dce70b8b977d00000001fe000a36e30078fe010159c6aecd")); -- cgit v1.2.3 From b5fc7e0899475547da99c06319ede5cc68f647e4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 25 Sep 2017 23:03:11 +1300 Subject: Improve H02 protocol decoder --- src/org/traccar/protocol/H02ProtocolDecoder.java | 4 +--- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index e4b18e277..dd5d4abd7 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -154,12 +154,10 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .text("VP1,") .or() .groupBegin() - .text("V1,") - .or() .text("V4,") .expression("(.*),") // response .or() - .text("V19,") + .expression("V[^,]*,") .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) .groupEnd() diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 59882a91f..e0130aa5d 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyNull(decoder, buffer( + "*HQ,353505221264507,VI1,075146,0,5238.25900,N,00507.33429,E,0.54,0,250917,FFFFFFFF,cc,28, db,d75b#")); + verifyNull(decoder, buffer( "*HQ,353505510948929,V1,,V,,N,,E,0.00,0,,FFFFF7FF,f0,a,11a0,c0c6#")); -- cgit v1.2.3 From 152dde860450adb9ae8409d69f429f35ad1b3b13 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 26 Sep 2017 11:57:08 +0500 Subject: Improve Teltonika IO decoding --- src/org/traccar/model/CellTower.java | 6 ++ .../traccar/protocol/TeltonikaProtocolDecoder.java | 120 ++++++++++++++++++--- test/org/traccar/ProtocolTest.java | 4 + .../protocol/TeltonikaProtocolDecoderTest.java | 6 ++ 4 files changed, 124 insertions(+), 12 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/CellTower.java b/src/org/traccar/model/CellTower.java index 2eb56dd33..6d1dfbd7f 100644 --- a/src/org/traccar/model/CellTower.java +++ b/src/org/traccar/model/CellTower.java @@ -106,4 +106,10 @@ public class CellTower { this.signalStrength = signalStrength; } + public void setOperator(long operator) { + String operatorString = String.valueOf(operator); + mobileCountryCode = Integer.parseInt(operatorString.substring(0, 3)); + mobileNetworkCode = Integer.parseInt(operatorString.substring(3)); + } + } diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 4700350d4..3dd00ead7 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -113,15 +113,15 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 19: position.set("axisZ", readValue(buf, length, true)); break; + case 21: + position.set("gsmLevel", readValue(buf, length, false)); + break; case 66: position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); break; case 67: position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); break; - case 70: - position.set(Position.KEY_DEVICE_TEMP, readValue(buf, length, true) * 0.1); - break; case 72: position.set(Position.PREFIX_TEMP + 1, readValue(buf, length, true) * 0.1); break; @@ -134,15 +134,92 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 78: position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(readValue(buf, length, false))); break; + case 80: + position.set("workMode", readValue(buf, length, false)); + break; + case 179: + position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); + break; + case 180: + position.set(Position.PREFIX_OUT + 2, readValue(buf, length, false) == 1); + break; + case 181: + position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + break; case 182: position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); break; + case 239: + position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); + break; + case 240: + position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + break; + case 241: + position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); + break; + default: + position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); + break; + } + } + + private void decodeGh3000Parameter(Position position, int id, ChannelBuffer buf, int length) { + switch (id) { + case 1: + position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length, false)); + break; + case 2: + position.set("usbConnected", readValue(buf, length, false) == 1); + break; + case 5: + position.set("uptime", readValue(buf, length, false)); + break; + case 20: + position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); + break; + case 21: + position.set(Position.KEY_VDOP, readValue(buf, length, false) * 0.1); + break; + case 22: + position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + break; + case 67: + position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + break; + case 221: + position.set("button", readValue(buf, length, false)); + break; + case 222: + if (readValue(buf, length, false) == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + break; + case 240: + position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + break; + case 244: + position.set("roaming", readValue(buf, length, false) == 1); + break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; } } + private void decodeNetwork(Position position) { + long cid = position.getLong(Position.PREFIX_IO + 205); + int lac = position.getInteger(Position.PREFIX_IO + 206); + if (cid != 0 && lac != 0) { + CellTower cellTower = CellTower.fromLacCid(lac, cid); + long operator = position.getInteger(Position.KEY_OPERATOR); + if (operator != 0) { + cellTower.setOperator(operator); + } + position.setNetwork(new Network(cellTower)); + } + } + private void decodeLocation(Position position, ChannelBuffer buf, int codec) { int globalMask = 0x0f; @@ -189,14 +266,19 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { cellTower.setSignalStrength((int) buf.readUnsignedByte()); } - position.setNetwork(new Network(cellTower)); + if (BitUtil.check(locationMask, 7)) { + cellTower.setOperator(buf.readUnsignedInt()); + } - } else if (BitUtil.check(locationMask, 6)) { - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - } + position.setNetwork(new Network(cellTower)); - if (BitUtil.check(locationMask, 7)) { - position.set(Position.KEY_OPERATOR, buf.readUnsignedInt()); + } else { + if (BitUtil.check(locationMask, 6)) { + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + } + if (BitUtil.check(locationMask, 7)) { + position.set(Position.KEY_OPERATOR, buf.readUnsignedInt()); + } } } else { @@ -233,7 +315,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 1); + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 1); + } else { + decodeParameter(position, buf.readUnsignedByte(), buf, 1); + } } } @@ -241,7 +327,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 2); + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 2); + } else { + decodeParameter(position, buf.readUnsignedByte(), buf, 2); + } } } @@ -249,7 +339,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 4); + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 4); + } else { + decodeParameter(position, buf.readUnsignedByte(), buf, 4); + } } } @@ -269,6 +363,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + decodeNetwork(position); + } private List parseData( diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 7bff41acd..01395fc11 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -257,6 +257,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_DRIVER_UNIQUE_ID) instanceof String); } + if (attributes.containsKey(Position.KEY_STEPS)) { + Assert.assertTrue(attributes.get(Position.KEY_STEPS) instanceof Number); + } + 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/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index a945178a1..beae48d67 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -59,6 +59,12 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "00000000000000a608010000013f14a1d1ce000f0eb790209a778000ab010c0500000000000000000100003390")); + verifyPositions(decoder, binary( + "000000000000004508010000015eb70a86d00024089d4d21dee3860137005f12005f000e06ef01f00150011503c800450108b5000bb6000642382718005fcd057ace19d3430f57440000000001000002bf")); + + verifyPositions(decoder, binary( + "000000000000004a08010000015ebc1da508002411926621f15246010b00b913005e000f06ef01f00150011505c800450108b5000bb6000642381b18005ecd0318ce19cd430f5844000001f1000061a900010000c8e1")); + decoder.setExtended(true); verifyPositions(decoder, false, binary( -- cgit v1.2.3 From 2e4fe0f4201ff43f65e36fb1ba386a1fa26b9aab Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 26 Sep 2017 14:17:28 +0500 Subject: Added intermediate "decodeParameter" function and KEY_ROAMING attribute --- src/org/traccar/model/Position.java | 1 + .../traccar/protocol/TeltonikaProtocolDecoder.java | 32 ++++++++++------------ test/org/traccar/ProtocolTest.java | 4 +++ 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 31af3d38a..93456b1b0 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -30,6 +30,7 @@ public class Position extends Message { public static final String KEY_SATELLITES_VISIBLE = "satVisible"; public static final String KEY_RSSI = "rssi"; public static final String KEY_GPS = "gps"; + public static final String KEY_ROAMING = "roaming"; public static final String KEY_EVENT = "event"; public static final String KEY_ALARM = "alarm"; public static final String KEY_STATUS = "status"; diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 3dd00ead7..8754d7d81 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -93,7 +93,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeParameter(Position position, int id, ChannelBuffer buf, int length) { + private void decodeOtherParameter(Position position, int id, ChannelBuffer buf, int length) { switch (id) { case 1: case 2: @@ -199,7 +199,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); break; case 244: - position.set("roaming", readValue(buf, length, false) == 1); + position.set(Position.KEY_ROAMING, readValue(buf, length, false) == 1); break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); @@ -207,6 +207,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeParameter(Position position, int id, ChannelBuffer buf, int length, int codec) { + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, id, buf, length); + } else { + decodeOtherParameter(position, id, buf, length); + } + } + private void decodeNetwork(Position position) { long cid = position.getLong(Position.PREFIX_IO + 205); int lac = position.getInteger(Position.PREFIX_IO + 206); @@ -315,11 +323,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 1); - } else { - decodeParameter(position, buf.readUnsignedByte(), buf, 1); - } + decodeParameter(position, buf.readUnsignedByte(), buf, 1, codec); } } @@ -327,11 +331,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 2); - } else { - decodeParameter(position, buf.readUnsignedByte(), buf, 2); - } + decodeParameter(position, buf.readUnsignedByte(), buf, 2, codec); } } @@ -339,11 +339,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 4); - } else { - decodeParameter(position, buf.readUnsignedByte(), buf, 4); - } + decodeParameter(position, buf.readUnsignedByte(), buf, 4, codec); } } @@ -351,7 +347,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_FM4X00) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 8); + decodeOtherParameter(position, buf.readUnsignedByte(), buf, 8); } } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 01395fc11..1daefabd6 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -261,6 +261,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_STEPS) instanceof Number); } + if (attributes.containsKey(Position.KEY_ROAMING)) { + Assert.assertTrue(attributes.get(Position.KEY_ROAMING) instanceof Boolean); + } + if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { for (CellTower cellTower : position.getNetwork().getCellTowers()) { checkInteger(cellTower.getMobileCountryCode(), 0, 999); -- cgit v1.2.3 From 7573aa48ebc870005cd03c6246290efed5c8e657 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 28 Sep 2017 01:47:17 +1300 Subject: Support new H02 message types --- src/org/traccar/protocol/H02ProtocolDecoder.java | 8 ++++++++ test/org/traccar/protocol/H02ProtocolDecoderTest.java | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index dd5d4abd7..4414870d2 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -161,7 +161,11 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) .groupEnd() + .groupBegin() .expression("([ABV])?,") // validity + .or() + .number("(d+),") // coding scheme + .groupEnd() .groupBegin() .number("-(d+)-(d+.d+),") // latitude .or() @@ -279,6 +283,10 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.setValid(parser.next().equals("A")); } + if (parser.hasNext()) { + parser.nextInt(); // coding scheme + position.setValid(true); + } if (parser.hasNext(2)) { position.setLatitude(-parser.nextCoordinate()); diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index e0130aa5d..bea65a540 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,7 +11,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); - verifyNull(decoder, buffer( + verifyPosition(decoder, buffer( "*HQ,353505221264507,VI1,075146,0,5238.25900,N,00507.33429,E,0.54,0,250917,FFFFFFFF,cc,28, db,d75b#")); verifyNull(decoder, buffer( -- cgit v1.2.3 From 5678fb06b466839ee4a34ec85f6b23a816a830cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 28 Sep 2017 23:08:45 +1300 Subject: Add H02 unit test --- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index bea65a540..b5dcd9ffe 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyPosition(decoder, buffer( + "*HQ,353505221264507,V2,100220,0,5238.26259,N,00507.33983,E,0.25,0,280917,FFFFFFFF,cc,28, db,d75b#")); + verifyPosition(decoder, buffer( "*HQ,353505221264507,VI1,075146,0,5238.25900,N,00507.33429,E,0.54,0,250917,FFFFFFFF,cc,28, db,d75b#")); -- cgit v1.2.3 From cff01fd43198ce786981dd8a51061dd0d415ccfd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 29 Sep 2017 19:17:55 +1300 Subject: Improve GT06 frame decoder --- src/org/traccar/protocol/Gt06FrameDecoder.java | 19 +++++++++---------- test/org/traccar/protocol/Gt06FrameDecoderTest.java | 12 ++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index f35af6572..9b93979e4 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2017 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. @@ -26,7 +26,6 @@ public class Gt06FrameDecoder extends FrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { - // Check minimum length if (buf.readableBytes() < 5) { return null; } @@ -35,19 +34,19 @@ public class Gt06FrameDecoder extends FrameDecoder { if (buf.getByte(buf.readerIndex()) == 0x78) { length += 1 + buf.getUnsignedByte(buf.readerIndex() + 2); - - int type = buf.getUnsignedByte(buf.readerIndex() + 3); - if (type == Gt06ProtocolDecoder.MSG_STATUS && length == 13) { - length += 2; // workaround for #1727 - } - } else { length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2); } - // Check length and return buffer if (buf.readableBytes() >= length) { - return buf.readBytes(length); + if (buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { + return buf.readBytes(length); + } else { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x0d); + if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { + return buf.readBytes(endIndex + 2 - buf.readerIndex()); + } + } } return null; diff --git a/test/org/traccar/protocol/Gt06FrameDecoderTest.java b/test/org/traccar/protocol/Gt06FrameDecoderTest.java index 12ee6bb60..78d1eb920 100644 --- a/test/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/test/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -11,6 +11,18 @@ public class Gt06FrameDecoderTest extends ProtocolTest { Gt06FrameDecoder decoder = new Gt06FrameDecoder(); + Assert.assertEquals( + binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"), + decoder.decode(null, null, binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"))); + + Assert.assertEquals( + binary("7878121011091c0b1e2e98058507f80097a6ac03344a0d0a"), + decoder.decode(null, null, binary("7878121011091c0b1e2e98058507f80097a6ac03344a0d0a"))); + + Assert.assertEquals( + binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"), + decoder.decode(null, null, binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"))); + Assert.assertEquals( binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"), decoder.decode(null, null, binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"))); -- cgit v1.2.3 From 6c2ef65bce9b3d9c7a88da941acf14603965ef93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 29 Sep 2017 19:26:08 +1300 Subject: Add GT06 test cases --- test/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 4042c3bf0..05acd314e 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,15 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "7878121011091c0b1b2999058508040097a89e0034520d0a")); + + verifyNull(decoder, binary( + "78780869170928113413ac9e17b30808514494fcf6e148596cb0ce2c67bd4a6eb0ce2c67bd4b0018e7d4333e55ec086be7f2df5fe48d8c94fc6657e48d8cb8f378510600cc0400d37a3d4600d37a3c5000d37a3b6400d376716400d305ac6400d393506e0d0a")); + + verifyNull(decoder, binary( + "787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a")); + verifyNotNull(decoder, binary( "78783b281108111002050136041bcf0000bf09000000000000000000000000000000000000000000000000000000000000000000000000ff00020007d3280d0a")); @@ -167,6 +176,14 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, binary( "78782516110819110208d402f264dc08289a4058d4c70901944600d300c0954606040600014057e90d0a")); + verifyNull(decoder, binary( + "78780d010359339075005244340d0a")); + + verifyNull(decoder, binary( + "787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a")); + + verifyNull(decoder, binary( + "787801080d0a")); } -- cgit v1.2.3 From 8e137d15f3db64909f5bd6e1ceb4b6a0bef8bed1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 Oct 2017 08:48:34 +1300 Subject: Add Megastek test case --- test/org/traccar/protocol/MegastekProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java index a20a0b69b..106baff98 100644 --- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MegastekProtocolDecoderTest extends ProtocolTest { MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol()); + verifyNull(decoder, text( + "0140$MGV002,354550056642321,GVT900-3,S,300917,071731,V,,,,,00,00,00,99.9,0.000,0.00,,0.0,457,01,0741,00CD,,0000,0000,20,10,0, , ,,1-1,94,PW ON;!")); + verifyPosition(decoder, text( "$MGV002,869152024446923,,S,290816,200627,V,5056.21059,N,00439.25034,E,00,00,00,99.9,,,-25.1,,206,01,0BBB,4418,28,,,,,,,,,01,093,Timer;")); -- cgit v1.2.3 From 81e6d5825615fbe0be253e500b2c997f304349e6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 Oct 2017 08:56:53 +1300 Subject: Workaround for GT06 frame decoder --- src/org/traccar/protocol/Gt06FrameDecoder.java | 19 ++++++++++--------- test/org/traccar/protocol/Gt06FrameDecoderTest.java | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index 9b93979e4..c8b5e56ae 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -38,17 +38,18 @@ public class Gt06FrameDecoder extends FrameDecoder { length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2); } - if (buf.readableBytes() >= length) { - if (buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { - return buf.readBytes(length); - } else { - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x0d); - if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { - return buf.readBytes(endIndex + 2 - buf.readerIndex()); - } - } + if (buf.readableBytes() >= length && buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { + return buf.readBytes(length); } + int endIndex = buf.readerIndex() - 1; + do { + endIndex = buf.indexOf(endIndex + 1, buf.writerIndex(), (byte) 0x0d); + if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { + return buf.readBytes(endIndex + 2 - buf.readerIndex()); + } + } while (endIndex > 0); + return null; } diff --git a/test/org/traccar/protocol/Gt06FrameDecoderTest.java b/test/org/traccar/protocol/Gt06FrameDecoderTest.java index 78d1eb920..ff9d4f51d 100644 --- a/test/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/test/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -11,6 +11,10 @@ public class Gt06FrameDecoderTest extends ProtocolTest { Gt06FrameDecoder decoder = new Gt06FrameDecoder(); + Assert.assertEquals( + binary("78780d0103563140414198583c0d0a"), + decoder.decode(null, null, binary("78780d0103563140414198583c0d0a"))); + Assert.assertEquals( binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"), decoder.decode(null, null, binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"))); @@ -23,10 +27,6 @@ public class Gt06FrameDecoderTest extends ProtocolTest { binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"), decoder.decode(null, null, binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"))); - Assert.assertEquals( - binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"), - decoder.decode(null, null, binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"))); - Assert.assertEquals( binary("787808134606020002044dc5050d0a"), decoder.decode(null, null, binary("787808134606020002044dc5050d0a"))); -- cgit v1.2.3 From 662cbd6f1b2c0eae0bbc59fe9341c043f5b7872a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 5 Oct 2017 08:38:46 +0900 Subject: Make some parameters optional --- src/org/traccar/protocol/CradlepointProtocolDecoder.java | 8 ++++---- test/org/traccar/protocol/CradlepointProtocolDecoderTest.java | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java index a1b42edf9..67a140cf7 100644 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -40,11 +40,11 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { .expression("([EW]),") .number("(d+.d+)?,") // speed .number("(d+.d+)?,") // course - .expression("([^,]+),") // carrier + .expression("([^,]+)?,") // carrier .expression("([^,]+)?,") // serdis - .number("(-?d+),") // rsrp - .number("(-?d+),") // rssi - .number("(-?d+),") // rsrq + .number("(-?d+)?,") // rsrp + .number("(-?d+)?,") // rssi + .number("(-?d+)?,") // rsrq .expression("([^,]+)?,") // ecio .expression("([^,]+)?") // wan ip .compile(); diff --git a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java index 4f37d3e1e..7eae791d5 100644 --- a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest { CradlepointProtocolDecoder decoder = new CradlepointProtocolDecoder(new CradlepointProtocol()); + verifyPosition(decoder, text( + "353547063544681,170515,3613.25,N,11559.14,W,0.0,,,,,,,,")); + + verifyPosition(decoder, text( + "353547060558130,170519,4337.17,N,11612.34,W,0.0,294.7,,,,,,,")); + verifyPosition(decoder, text( "+12084014675,162658,4337.174385,N,11612.338373,W,0.0,,Verizon,,-71,-44,-11,,")); -- cgit v1.2.3 From 7ae0d8de4b5c78e9265a9a5cbb5b19ef19a4f017 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 8 Oct 2017 13:43:01 +0800 Subject: Support alternative Xexun ignition --- src/org/traccar/protocol/XexunProtocolDecoder.java | 2 ++ test/org/traccar/protocol/XexunProtocolDecoderTest.java | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'test/org') diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index a5a38c370..ca0a8669e 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -68,9 +68,11 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { if (value != null) { switch (value.toLowerCase()) { case "acc on": + case "ACCStart": position.set(Position.KEY_IGNITION, true); break; case "acc off": + case "ACCStop": position.set(Position.KEY_IGNITION, false); break; case "help me!": diff --git a/test/org/traccar/protocol/XexunProtocolDecoderTest.java b/test/org/traccar/protocol/XexunProtocolDecoderTest.java index 686d3f53f..8587ee295 100644 --- a/test/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -55,6 +55,12 @@ public class XexunProtocolDecoderTest extends ProtocolTest { decoder = new XexunProtocolDecoder(new XexunProtocol(), true); + verifyPosition(decoder, text( + "171007160505,,GPRMC,160505.000,A,5323.4680,N,00252.4202,W,000.0,129.7,071017,,,A*7A,F,ACCStart, imei:864504031916915,10,41.1,F:4.28V,1,135,19824,234,15,0062,B7D5")); + + verifyPosition(decoder, text( + "171007160525,,GPRMC,160525.000,A,5323.4680,N,00252.4202,W,000.0,129.7,071017,,,A*78,F,ACCStop, imei:864504031916915,10,41.1,F:4.28V,1,134,42896,234,15,0062,B7D5")); + verifyPosition(decoder, text( "170505103845,TELKOMSEL,GPRMC,103845.000,A,0340.2482,N,09841.9689,E,0.00,68.23,050517,,,A*5D,F,ACC On, imei:013227002782161,05,-8.2,F:4.22V,1,141,44712,510,10,2BE5,EC47")); -- cgit v1.2.3 From e876250991faccdca04a1f36ddaf847c9f392275 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 11 Oct 2017 21:20:44 +0800 Subject: Add PT502 test case --- test/org/traccar/protocol/Pt502ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/org') diff --git a/test/org/traccar/protocol/Pt502ProtocolDecoderTest.java b/test/org/traccar/protocol/Pt502ProtocolDecoderTest.java index 62b3bbdaa..24b570937 100644 --- a/test/org/traccar/protocol/Pt502ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Pt502ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Pt502ProtocolDecoderTest extends ProtocolTest { Pt502ProtocolDecoder decoder = new Pt502ProtocolDecoder(new Pt502Protocol()); + verifyPosition(decoder, text( + "$PHO0-1,1360000260,123012.000,A,0913.9644,N,07548.8345,W,0.0,309.8,111017,,,A/00000,10000/0,0,0,0/64551600//f98//")); + verifyPosition(decoder, text( "$POS,865328026243864,151105.000,A,1332.7096,N,204.6787,E,0.0,10.00,050517,,,A/00000,10/1,0/234//FD9/")); -- cgit v1.2.3 From 3f5a5e81fe08c7ae0b136d52b4840d5085e12f23 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 15 Oct 2017 11:15:55 +0800 Subject: Update tzone protocol --- src/org/traccar/protocol/TzoneProtocolDecoder.java | 11 ++++++++++- test/org/traccar/protocol/TzoneProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java index 76903c90c..079ad3126 100644 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java @@ -203,7 +203,16 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { if (blockLength >= 13) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("terminalInfo", buf.readUnsignedByte()); - position.set(Position.PREFIX_IO + 1, buf.readUnsignedShort()); + + int status = buf.readUnsignedByte(); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 0)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 1)); + status = buf.readUnsignedByte(); + position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 4)); + if (BitUtil.check(status, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("gsmStatus", buf.readUnsignedByte()); position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); diff --git a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java index aa8f61772..68c8bbdbc 100644 --- a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { TzoneProtocolDecoder decoder = new TzoneProtocolDecoder(new TzoneProtocol()); + verifyPosition(decoder, binary( + "545a005624240111010e0000086169303626931411091b151d2600160801de26ec002f633411091b151d2500000000160c0000040d2a34df000eaa4000001b37016000000000319c0000000000000000000000000000003a84240d0a")); + verifyPosition(decoder, binary( "545a005024240153011000000863835025559464110103080a22001609011bed79245964a9110103080a22000a0000550c00000604396f04222c000daac000151701a204870000000000000003000959000546190d0a")); -- cgit v1.2.3 From 4ba8252588c0d280434c83b9d855098be3a15dd9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 19 Oct 2017 04:35:39 +1300 Subject: Update Cradlepoint decoder (fix #3581) --- .../protocol/CradlepointProtocolDecoder.java | 26 +++++++++++++++------- .../protocol/CradlepointProtocolDecoderTest.java | 12 ++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java index 67a140cf7..e8f95a60c 100644 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -18,11 +18,13 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; +import java.util.Date; import java.util.regex.Pattern; public class CradlepointProtocolDecoder extends BaseProtocolDecoder { @@ -33,7 +35,7 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .expression("([^,]+),") // id - .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d{1,6}),") // time (hhmmss) .number("(d+)(dd.d+),") // latitude .expression("([NS]),") .number("(d+)(dd.d+),") // longitude @@ -58,16 +60,21 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS)); + int time = parser.nextInt(); + DateBuilder dateBuilder = new DateBuilder(new Date()); + dateBuilder.setHour(time / 100 / 100); + dateBuilder.setMinute(time / 100 % 100); + dateBuilder.setSecond(time % 100); + position.setTime(dateBuilder.getDate()); position.setValid(true); position.setLatitude(parser.nextCoordinate()); @@ -75,9 +82,12 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(parser.nextDouble(0)); position.setCourse(parser.nextDouble(0)); - parser.skip(3); - - position.set(Position.KEY_RSSI, parser.nextDouble()); + position.set("carrid", parser.next()); + position.set("serdis", parser.next()); + position.set("rsrp", parser.next()); + position.set("dbm", parser.next()); + position.set("rsrq", parser.next()); + position.set("ecio", parser.next()); return position; } diff --git a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java index 7eae791d5..757298682 100644 --- a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java @@ -10,6 +10,18 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest { CradlepointProtocolDecoder decoder = new CradlepointProtocolDecoder(new CradlepointProtocol()); + verifyPosition(decoder, text( + "356526070063940,0,4337.19009,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,")); + + verifyPosition(decoder, text( + "356526070063940,1,4337.19008,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,")); + + verifyPosition(decoder, text( + "+14063964266,162658,4333.62404,N,11636.23469,W,0.0,,Verizon Wireless,LTE,-107,-74,-16,,100.68.169.178")); + + verifyPosition(decoder, text( + "+12084014675,162658,4337.174385,N,11612.338373,W,0.0,,Verizon,,-71,-44,-11,,")); + verifyPosition(decoder, text( "353547063544681,170515,3613.25,N,11559.14,W,0.0,,,,,,,,")); -- cgit v1.2.3 From 9ace2318b9ea5a2d949800eedff8398808d3a6ce Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 Oct 2017 18:24:27 +1300 Subject: Support GVT900E device protocol --- src/org/traccar/protocol/MegastekProtocolDecoder.java | 8 ++++---- test/org/traccar/protocol/MegastekProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 994e2d983..3ef52acd1 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -267,7 +267,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { .or().text(" ") .groupEnd("?").text(",") .number("(d+)?,") // rfid - .number("d*,") + .expression("[^,]*,") .number("(d+)?,") // battery .expression("([^,]*);") // alert .any() @@ -280,13 +280,13 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); if (parser.next().equals("S")) { diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java index 106baff98..583de513c 100644 --- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MegastekProtocolDecoderTest extends ProtocolTest { MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol()); + verifyPosition(decoder, text( + "0170$MGV002,354550056642321,GVT900-3,S,011017,090208,A,1635.8484,N,10446.6095,E,00,09,00,0.91,16.980,257.73,177.6,0.0,457,01,0741,00C0,21,0000,0000,20,10,0, , ,,1-1,54,Dist;!")); + verifyNull(decoder, text( "0140$MGV002,354550056642321,GVT900-3,S,300917,071731,V,,,,,00,00,00,99.9,0.000,0.00,,0.0,457,01,0741,00CD,,0000,0000,20,10,0, , ,,1-1,94,PW ON;!")); -- cgit v1.2.3 From f6f514bea19a75544378fdbfccb6808ea1a0424e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 Oct 2017 11:15:44 +1300 Subject: Add Megastek test case --- test/org/traccar/protocol/MegastekFrameDecoderTest.java | 6 +++--- test/org/traccar/protocol/MegastekProtocolDecoderTest.java | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'test/org') diff --git a/test/org/traccar/protocol/MegastekFrameDecoderTest.java b/test/org/traccar/protocol/MegastekFrameDecoderTest.java index c2a8f4ecd..9a327bb1f 100644 --- a/test/org/traccar/protocol/MegastekFrameDecoderTest.java +++ b/test/org/traccar/protocol/MegastekFrameDecoderTest.java @@ -11,15 +11,15 @@ public class MegastekFrameDecoderTest extends ProtocolTest { MegastekFrameDecoder decoder = new MegastekFrameDecoder(); - Assert.assertEquals( + verifyFrame( binary("30313337244d47563030322c3335343535303035303239323636392c4756543930302c522c3134313231352c3033313830342c412c2c532c2c452c30302c30332c30302c332e36372c302e3030302c302e30302c3131372e312c302e302c3531302c31302c2c2c2c303030302c303030302c32322c31322c302c202c202c2c312d312c39382c5057204f4e3b21"), decoder.decode(null, null, binary("30313337244d47563030322c3335343535303035303239323636392c4756543930302c522c3134313231352c3033313830342c412c2c532c2c452c30302c30332c30302c332e36372c302e3030302c302e30302c3131372e312c302e302c3531302c31302c2c2c2c303030302c303030302c32322c31322c302c202c202c2c312d312c39382c5057204f4e3b21"))); - Assert.assertEquals( + verifyFrame( binary("244d47563030322c3031333737373030373533363433342c2c522c3031303131342c3030303035372c562c303030302e303030302c4e2c30303030302e303030302c452c30302c30302c30302c39392e392c302e3030302c302e30302c302e302c38302e3236332c3531302c38392c323334322c303330422c2c303030302c303030302c3230302c39362c302c202c202c2c2c2c54696d65723b21"), decoder.decode(null, null, binary("244d47563030322c3031333737373030373533363433342c2c522c3031303131342c3030303035372c562c303030302e303030302c4e2c30303030302e303030302c452c30302c30302c30302c39392e392c302e3030302c302e30302c302e302c38302e3236332c3531302c38392c323334322c303330422c2c303030302c303030302c3230302c39362c302c202c202c2c2c2c54696d65723b210d0a"))); - Assert.assertEquals( + verifyFrame( binary("53545832363034373520202020202020202020024f244750524d432c3133313131302e30302c562c2c2c2c2c2c2c3036303931332c2c2c4e2a37362c3232322c30312c383135412c443435352c31312c39372c303030302c303030312c302c54696d65723b3735"), decoder.decode(null, null, binary("53545832363034373520202020202020202020024f244750524d432c3133313131302e30302c562c2c2c2c2c2c2c3036303931332c2c2c4e2a37362c3232322c30312c383135412c443435352c31312c39372c303030302c303030312c302c54696d65723b37350d0a"))); diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java index 583de513c..9bb705f17 100644 --- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MegastekProtocolDecoderTest extends ProtocolTest { MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol()); + verifyNull(decoder, text( + "0112$MGV002,,GVT900-3,S,010114,000003,,,,,,00,00,00,,0.000,0.00,,0.0,,,,,,0000,0000,14,10,0, , ,,1-0,0,Low Ext Vol;!")); + verifyPosition(decoder, text( "0170$MGV002,354550056642321,GVT900-3,S,011017,090208,A,1635.8484,N,10446.6095,E,00,09,00,0.91,16.980,257.73,177.6,0.0,457,01,0741,00C0,21,0000,0000,20,10,0, , ,,1-1,54,Dist;!")); -- cgit v1.2.3 From 96e15853b9c28bd31295ca2c014e226e4a50aaa1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Oct 2017 23:41:30 +1300 Subject: Improve TAIP validity handling --- src/org/traccar/protocol/TaipProtocolDecoder.java | 3 +-- test/org/traccar/protocol/TaipProtocolDecoderTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'test/org') diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index c6220ab1d..e7117a5c9 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -68,7 +68,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { .number("(x{8})") // odometer .number("[01]") // gps power .groupEnd("?") - .number("(d)") // fix mode .any() .compile(); @@ -162,7 +161,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); } - position.setValid(parser.nextInt(0) != 0); + position.setValid(true); String[] attributes = null; beginIndex = sentence.indexOf(';'); diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index e2de26ec0..beba54d74 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">RPV46640+4197412-0752857900015802;ID=5102;*71<")); + + verifyNull(decoder, text( + ">RCP46640+419741-075285802;ID=5102;*6C<")); + verifyPosition(decoder, text( ">REV001958003965+0307178+1016144900031532;IO=300;SV=8;BL=4159;CF=8161,C,13;AD=14145;IX=10233040;FF=0,0,0,0;VO=338578;ID=357042063052352<")); -- cgit v1.2.3