diff options
-rw-r--r-- | src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 77 | ||||
-rw-r--r-- | src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 11 |
2 files changed, 78 insertions, 10 deletions
diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 7a8d67cf9..623352106 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -42,11 +42,45 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; +import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { + private static final HashMap<String, String> DEVICE_MODELS = new HashMap<String, String>() {{ + put("02", "GL200"); + put("04", "GV200"); + put("06", "GV300"); + put("08", "GMT100"); + put("09", "GV50P"); + put("0F", "GV55"); + put("10", "GV55 LITE"); + put("11", "GL500"); + put("1A", "GL300"); + put("1F", "GV500"); + put("25", "GV300"); + put("27", "GV300W"); + put("2C", "GL300W"); + put("2F", "GV55"); + put("30", "GL300"); + put("35", "GV200"); + put("36", "GV500"); + put("3F", "GMT100"); + put("41", "GV75W"); + put("50", "GV55W"); + put("52", "GL50"); + put("55", "GL50B"); + put("5E", "GV500MAP"); + put("6E", "GV310LAU"); + put("C2", "GV600M"); + put("F1", "GV350M"); + put("F8", "GV800W"); + put("FC", "GV600W"); + put("802004", "GV58LAU"); + put("802005", "GV355CEU"); + }}; + private boolean ignoreFixTime; private final DateFormat dateFormat; @@ -62,7 +96,13 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { ignoreFixTime = getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); } - private String getDeviceModel(DeviceSession deviceSession, String value) { + private String getDeviceModel(DeviceSession deviceSession, String value, String protocolVersion) { + if (DEVICE_MODELS.containsKey(protocolVersion.substring(0, 2))) { + return DEVICE_MODELS.get(protocolVersion.substring(0, 2)); + } + if (DEVICE_MODELS.containsKey(protocolVersion.substring(0, 6))) { + return DEVICE_MODELS.get(protocolVersion.substring(0, 6)); + } String model = value.isEmpty() ? getDeviceModel(deviceSession) : value; return model != null ? model.toUpperCase() : ""; } @@ -122,12 +162,12 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_INF = new PatternBuilder() .text("+").expression("(?:RESP|BUFF):GTINF,") - .expression("(?:.{6}|.{10})?,") // protocol version + .expression("(.{6}|.{10})?,") // protocol version .number("(d{15}|x{14}),") // imei .expression("(?:[0-9A-Z]{17},)?") // vin .expression("(?:[^,]+)?,") // device name .number("(xx),") // state - .expression("(?:[0-9Ff]{20})?,") // iccid + .expression("([0-9Ff]{20})?,") // iccid .number("(d{1,2}),") // rssi .number("d{1,2},") .expression("[01]{1,2},") // external power @@ -148,6 +188,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:[01])?,").optional() // pin15 mode .number("(d+)?,") // adc1 .number("(d+)?,").optional() // adc2 + .number("(d+)?,").optional() // adc3 .number("(xx)?,") // digital input .number("(xx)?,") // digital output .number("[-+]dddd,") // timezone @@ -163,10 +204,17 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { 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) { + if (!parser.matches()) { return null; } + String protocolVersion = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); switch (parser.nextHexInt()) { case 0x16: @@ -197,9 +245,15 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { break; } + position.set(Position.KEY_ICCID, parser.next()); position.set(Position.KEY_RSSI, parser.nextInt()); - parser.next(); // odometer or external power + String model = getDeviceModel(deviceSession, "", protocolVersion); + if (model.equals("GV310LAU")) { + position.set(Position.KEY_POWER, parser.nextDouble() / 1000); // odometer or external power + } else { + parser.next(); // odometer or external power + } position.set(Position.KEY_BATTERY, parser.nextDouble()); position.set(Position.KEY_CHARGE, parser.nextInt() == 1); @@ -210,6 +264,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); + if (model.equals("GV310LAU")) { + position.set(Position.PREFIX_ADC + 3, parser.next()); + } position.set(Position.KEY_INPUT, parser.next()); position.set(Position.KEY_OUTPUT, parser.next()); @@ -455,7 +512,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { private Object decodeCan(Channel channel, SocketAddress remoteAddress, String[] v) throws ParseException { int index = 0; index += 1; // header - index += 1; // protocol version + String protocolVersion = v[index++]; // protocol version DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, v[index++]); if (deviceSession == null) { return null; @@ -464,7 +521,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - String model = getDeviceModel(deviceSession, v[index++]); + String model = getDeviceModel(deviceSession, v[index++], protocolVersion); index += 1; // report type index += 1; // can bus state long reportMask = Long.parseLong(v[index++], 16); @@ -872,13 +929,13 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { private Object decodeEri(Channel channel, SocketAddress remoteAddress, String[] v) throws ParseException { int index = 0; index += 1; // header - index += 1; // protocol version + String protocolVersion = v[index++]; // protocol version DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, v[index++]); if (deviceSession == null) { return null; } - String model = getDeviceModel(deviceSession, v[index++]); + String model = getDeviceModel(deviceSession, v[index++], protocolVersion); long mask = Long.parseLong(v[index++], 16); Double power = v[index++].isEmpty() ? null : Integer.parseInt(v[index - 1]) * 0.001; index += 1; // report type diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index b6e50e07d..768704b68 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -487,6 +487,17 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "+ACK:GTGEO,1A0102,135790246811220,,0,0008,20100310172830,11F0")); + verifyAttributes(decoder, buffer( + "+RESP:GTINF,6E0202,868589060187625,RA82,11,89883030000091225018,41,0,1,12349,,4.15,0,1,0,0,20240328231013,0,0,0,0,00,00,+0000,0,20240328231015,7D4F")); + + verifyAttribute(decoder, buffer( + "+RESP:GTINF,6E0202,868589060187625,RA82,11,89883030000091225018,41,0,1,12349,,4.15,0,1,0,0,20240328231013,0,0,0,0,00,00,+0000,0,20240328231015,7D4F"), + Position.KEY_POWER, 12.349); + + verifyAttribute(decoder, buffer( + "+RESP:GTINF,6E0202,868589060187625,RA82,11,89883030000091225018,41,0,1,12349,,4.15,0,1,0,0,20240328231013,0,0,0,0,00,00,+0000,0,20240328231015,7D4F"), + Position.PREFIX_ADC + 3, "0"); + decoder.setModelOverride("GV355CEU"); verifyAttributes(decoder, buffer( |