From 65d0cdf1a38861ac4a53b9c7fa6489c20c179df6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 22 Nov 2018 17:01:51 +1300 Subject: Support H002 protocol --- src/org/traccar/protocol/Pt60Protocol.java | 2 +- src/org/traccar/protocol/Pt60ProtocolDecoder.java | 125 +++++++++++++-------- .../traccar/protocol/Pt60ProtocolDecoderTest.java | 9 ++ 3 files changed, 90 insertions(+), 46 deletions(-) diff --git a/src/org/traccar/protocol/Pt60Protocol.java b/src/org/traccar/protocol/Pt60Protocol.java index 18ea2edb1..c502426c5 100644 --- a/src/org/traccar/protocol/Pt60Protocol.java +++ b/src/org/traccar/protocol/Pt60Protocol.java @@ -28,7 +28,7 @@ public class Pt60Protocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@")); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Pt60ProtocolDecoder(Pt60Protocol.this)); diff --git a/src/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/org/traccar/protocol/Pt60ProtocolDecoder.java index 7027115f7..51a916475 100644 --- a/src/org/traccar/protocol/Pt60ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt60ProtocolDecoder.java @@ -25,7 +25,6 @@ import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Pattern; @@ -36,26 +35,37 @@ public class Pt60ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - public static final int MSG_TRACK = 6; - public static final int MSG_STEP_COUNT = 13; - public static final int MSG_HEART_RATE = 14; + public static final int MSG_G_TRACK = 6; + public static final int MSG_G_STEP_COUNT = 13; + public static final int MSG_G_HEART_RATE = 14; + + public static final int MSG_B_POSITION = 1; private static final Pattern PATTERN = new PatternBuilder() - .text("@G#@,") // header - .number("Vdd,") // protocol version - .number("(d+),") // type - .number("(d+),") // imei - .number("(d+),") // imsi + .expression("@(.)#@[,|]") // header + .number("V?dd[,|]") // protocol version + .number("(d+)[,|]") // type + .number("(d+)[,|]") // imei + .number("d+[,|]") // imsi + .groupBegin() + .number("[01][,|]") // state + .number("d+[,|]") // battery + .groupEnd("?") .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(dd)(dd)(dd)[,|]") // time (hhmmss) .expression("(.*)") // data .compile(); - private void sendResponse(Channel channel, SocketAddress remoteAddress) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String format, int type, String imei) { if (channel != null) { - DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - channel.writeAndFlush(new NetworkMessage( - "@G#@,V01,38," + dateFormat.format(new Date()) + ",@R#@", remoteAddress)); + String message; + String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); + if (format.equals("G")) { + message = String.format("@G#@,V01,38,%s,@R#@", time); + } else { + message = String.format("@B#@|01|%03d|%s|0|%s|@E#@", type + 1, imei, time); + } + channel.writeAndFlush(new NetworkMessage(message, remoteAddress)); } } @@ -63,59 +73,84 @@ public class Pt60ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - sendResponse(channel, remoteAddress); - Parser parser = new Parser(PATTERN, (String) msg); if (!parser.matches()) { return null; } + String format = parser.next(); int type = parser.nextInt(); + String imei = parser.next(); - if (type != MSG_TRACK && type != MSG_STEP_COUNT && type != MSG_HEART_RATE) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { return null; } - Position position = new Position(getProtocolName()); + sendResponse(channel, remoteAddress, format, type, imei); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next(), parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); + if (format.equals("G")) { - position.setDeviceTime(parser.nextDateTime()); + if (type != MSG_G_TRACK && type != MSG_G_STEP_COUNT && type != MSG_G_HEART_RATE) { + return null; + } - String[] values = parser.next().split(","); + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setDeviceTime(parser.nextDateTime()); - if (type == MSG_TRACK) { + String[] values = parser.next().split(","); - position.setValid(true); - position.setFixTime(position.getDeviceTime()); + if (type == MSG_G_TRACK) { + + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + + String[] coordinates = values[0].split(";"); + position.setLatitude(Double.parseDouble(coordinates[0])); + position.setLongitude(Double.parseDouble(coordinates[1])); + + } else { - String[] coordinates = values[0].split(";"); - position.setLatitude(Double.parseDouble(coordinates[0])); - position.setLongitude(Double.parseDouble(coordinates[1])); + getLastLocation(position, position.getDeviceTime()); + + switch (type) { + case MSG_G_STEP_COUNT: + position.set(Position.KEY_STEPS, Integer.parseInt(values[0])); + break; + case MSG_G_HEART_RATE: + position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[0])); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[1])); + break; + default: + break; + } + + } + + return position; } else { - getLastLocation(position, position.getDeviceTime()); - - switch (type) { - case MSG_STEP_COUNT: - position.set(Position.KEY_STEPS, Integer.parseInt(values[0])); - break; - case MSG_HEART_RATE: - position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[0])); - position.set(Position.KEY_BATTERY, Integer.parseInt(values[1])); - break; - default: - break; + if (type != MSG_B_POSITION) { + return null; } - } + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setDeviceTime(parser.nextDateTime()); + + String[] values = parser.next().split("\\|"); - return position; + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + + position.setLongitude(Double.parseDouble(values[0])); + position.setLatitude(Double.parseDouble(values[1])); + + return position; + + } } } diff --git a/test/org/traccar/protocol/Pt60ProtocolDecoderTest.java b/test/org/traccar/protocol/Pt60ProtocolDecoderTest.java index f150c61a6..d2e06b193 100644 --- a/test/org/traccar/protocol/Pt60ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Pt60ProtocolDecoderTest.java @@ -10,6 +10,15 @@ public class Pt60ProtocolDecoderTest extends ProtocolTest { Pt60ProtocolDecoder decoder = new Pt60ProtocolDecoder(null); + verifyNull(decoder, text( + "@B#@|01|033|864891030184954|9425010450971470|0|4|20181120151744|")); + + verifyPosition(decoder, text( + "@B#@|01|001|111112222233333|8888888888888888|1|55|20160715150323|125.48276|37.615124|111.059279|49.346383|1|")); + + verifyPosition(decoder, text( + "@B#@|01|001|111112222233333|8888888888888888|1|55|20160715150323|125.48276|37.615124|1|")); + verifyAttributes(decoder, text( "@G#@,V01,14,357653051059785,9404223001501310,20180419165604,101,26,")); -- cgit v1.2.3