aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2023-07-02 09:41:32 -0700
committerAnton Tananaev <anton@traccar.org>2023-07-02 09:41:32 -0700
commita8a06ffd494fc7161ca0edca39ae35be865a383f (patch)
tree8f8a2d65394b3122c83b1dafc9bfa2c275fb45f3
parent957a68d4a378c0f9d5000bc00599427fd78e663d (diff)
downloadtrackermap-server-a8a06ffd494fc7161ca0edca39ae35be865a383f.tar.gz
trackermap-server-a8a06ffd494fc7161ca0edca39ae35be865a383f.tar.bz2
trackermap-server-a8a06ffd494fc7161ca0edca39ae35be865a383f.zip
Support GV350M accessories
-rw-r--r--src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java104
-rw-r--r--src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java8
2 files changed, 112 insertions, 0 deletions
diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java
index e33093d6f..bfd0a4cbb 100644
--- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java
@@ -1154,6 +1154,104 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ private static final Pattern PATTERN_BAA = new PatternBuilder()
+ .text("+RESP:GTBAA,")
+ .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
+ .number("(d{15}|x{14}),") // imei
+ .expression("[^,]*,") // device name
+ .number("x+,") // index
+ .number("d,") // accessory type
+ .number("d,") // accessory model
+ .number("x+,") // alarm type
+ .number("(x{4}),") // append mask
+ .expression("((?:[^,]+,){0,6})") // accessory optionals
+ .expression(PATTERN_LOCATION.pattern())
+ .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 decodeBaa(Channel channel, SocketAddress remoteAddress, String sentence) {
+ Parser parser = new Parser(PATTERN_BAA, sentence);
+ Position position = initPosition(parser, channel, remoteAddress);
+ if (position == null) {
+ return null;
+ }
+
+ int mask = parser.nextHexInt();
+ String[] values = parser.next().split(",");
+ int index = 0;
+ if (BitUtil.check(mask, 0)) {
+ position.set("accessoryName", values[index++]);
+ }
+ if (BitUtil.check(mask, 1)) {
+ position.set("accessoryMac", values[index++]);
+ }
+ if (BitUtil.check(mask, 2)) {
+ position.set("accessoryStatus", Integer.parseInt(values[index++]));
+ }
+ if (BitUtil.check(mask, 3)) {
+ position.set("accessoryVoltage", Integer.parseInt(values[index++]) * 0.001);
+ }
+ if (BitUtil.check(mask, 4)) {
+ position.set("accessoryTemp", Integer.parseInt(values[index++]));
+ }
+ if (BitUtil.check(mask, 5)) {
+ position.set("accessoryHumidity", Integer.parseInt(values[index]));
+ }
+
+ decodeLocation(position, parser);
+
+ decodeDeviceTime(position, parser);
+
+ return position;
+ }
+
+ private static final Pattern PATTERN_BID = new PatternBuilder()
+ .text("+RESP:GTBID,")
+ .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
+ .number("(d{15}|x{14}),") // imei
+ .expression("[^,]*,") // device name
+ .number("d,") // count
+ .number("d,") // accessory model
+ .number("(x{4}),") // append mask
+ .expression("((?:[^,]+,){0,2})") // accessory optionals
+ .expression(PATTERN_LOCATION.pattern())
+ .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 decodeBid(Channel channel, SocketAddress remoteAddress, String sentence) {
+ Parser parser = new Parser(PATTERN_BID, sentence);
+ Position position = initPosition(parser, channel, remoteAddress);
+ if (position == null) {
+ return null;
+ }
+
+ int mask = parser.nextHexInt();
+ String[] values = parser.next().split(",");
+ int index = 0;
+ if (BitUtil.check(mask, 1)) {
+ position.set("accessoryMac", values[index++]);
+ }
+ if (BitUtil.check(mask, 3)) {
+ position.set("accessoryVoltage", Integer.parseInt(values[index]) * 0.001);
+ }
+
+ decodeLocation(position, parser);
+
+ decodeDeviceTime(position, parser);
+
+ return position;
+ }
+
private static final Pattern PATTERN = new PatternBuilder()
.text("+").expression("(?:RESP|BUFF):GT...,")
.number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
@@ -1402,6 +1500,12 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
case "DTT":
result = decodeDtt(channel, remoteAddress, sentence);
break;
+ case "BAA":
+ result = decodeBaa(channel, remoteAddress, sentence);
+ break;
+ case "BID":
+ result = decodeBid(channel, remoteAddress, sentence);
+ break;
default:
result = decodeOther(channel, remoteAddress, sentence, type);
break;
diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java
index 760671cd9..fcd2c6be4 100644
--- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java
@@ -12,6 +12,14 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest {
var decoder = inject(new Gl200TextProtocolDecoder(null));
verifyAttribute(decoder, buffer(
+ "+RESP:GTBAA,F1040C,862599050497393,GV350M,FF,3,0,04,000A,780541256AE9,3065,0,0.0,213,2908.3,-78.691944,-0.951426,20230511173150,,,,,,20230511175001,0159$"),
+ "accessoryVoltage", 3.065);
+
+ verifyAttribute(decoder, buffer(
+ "+RESP:GTBID,C20105,866833040163013,GV350M,1,0,000A,B80EA11FF800,2934,0,0.0,0,1506.5,-99.192686,18.932709,20221026025339,0334,0020,0232,029D4E02,,20221026181026,9F1D$"),
+ "accessoryVoltage", 2.934);
+
+ verifyAttribute(decoder, buffer(
"+RESP:GTDTT,410502,864802030541621,,,,1,35,45637561747261636b0d0a434f4d422c302c39342e302c2d312e302c2c2c4844430d0a,20230421034626,EA2E$"),
Position.KEY_FUEL_LEVEL, 94.0);