diff options
Diffstat (limited to 'src/org/traccar/protocol/Tk103ProtocolDecoder.java')
-rw-r--r-- | src/org/traccar/protocol/Tk103ProtocolDecoder.java | 173 |
1 files changed, 164 insertions, 9 deletions
diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index be3def453..eda29e3f8 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -26,6 +26,7 @@ import org.traccar.helper.PatternBuilder; 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.regex.Pattern; @@ -40,6 +41,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN = new PatternBuilder() + .text("(").optional() .number("(d+)(,)?") // device id .expression("(.{4}),?") // command .number("(d*)") @@ -63,21 +65,28 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .number("(?:L(x+))?") // odometer .any() .number("([+-]ddd.d)?") // temperature + .groupBegin() + .number("([+-]?d+.d{1,2}),") // altitude + .number("(d+)$") // number of visible satellites + .groupEnd("?") .text(")").optional() .compile(); private static final Pattern PATTERN_BATTERY = new PatternBuilder() + .text("(").optional() .number("(d+),") // device id .text("ZC20,") .number("(dd)(dd)(dd),") // date (ddmmyy) .number("(dd)(dd)(dd),") // time (hhmmss) - .number("d+,") // battery level + .number("(d+),") // battery level .number("(d+),") // battery voltage .number("(d+),") // power voltage .number("d+") // installed + .any() .compile(); private static final Pattern PATTERN_NETWORK = new PatternBuilder() + .text("(").optional() .number("(d{12})") // device id .text("BZ00,") .number("(d+),") // mcc @@ -87,6 +96,31 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_LBSWIFI = new PatternBuilder() + .text("(").optional() + .number("(d+),") // device id + .expression("(.{4}),") // command + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(d+),") // lac + .number("(d+),") // cid + .number("(d+),") // number of wifi macs + .number("((?:(?:xx:){5}(?:xx)\\*[-+]?d+\\*d+,)*)") + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd)") // time (hhmmss) + .any() + .compile(); + + private static final Pattern PATTERN_COMMAND_RESULT = new PatternBuilder() + .text("(").optional() + .number("(d+),") // device id + .expression(".{4},") // command + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .expression("\\$([\\s\\S]*?)(?:\\$|$)") // message + .any() + .compile(); + private String decodeAlarm(int value) { switch (value) { case 1: @@ -112,30 +146,53 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0')); break; case "ZC11": + case "DW31": + case "DW51": position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); break; case "ZC12": + case "DW32": + case "DW52": position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); break; case "ZC13": + case "DW33": + case "DW53": position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); break; case "ZC15": + case "DW35": + case "DW55": position.set(Position.KEY_IGNITION, true); break; case "ZC16": + case "DW36": + case "DW56": position.set(Position.KEY_IGNITION, false); break; + case "ZC29": + case "DW42": + case "DW62": + position.set(Position.KEY_IGNITION, true); + break; case "ZC17": + case "DW37": + case "DW57": position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); break; case "ZC25": + case "DW3E": + case "DW5E": position.set(Position.KEY_ALARM, Position.ALARM_SOS); break; case "ZC26": + case "DW3F": + case "DW5F": position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); break; case "ZC27": + case "DW40": + case "DW60": position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); break; default: @@ -143,6 +200,23 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } } + private Integer decodeBattery(int value) { + switch (value) { + case 6: + return 100; + case 5: + return 80; + case 4: + return 50; + case 3: + return 20; + case 2: + return 10; + default: + return null; + } + } + private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_BATTERY, sentence); if (!parser.matches()) { @@ -160,6 +234,11 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + int batterylevel = parser.nextInt(0); + if (batterylevel != 255) { + position.set(Position.KEY_BATTERY_LEVEL, decodeBattery(batterylevel)); + } + int battery = parser.nextInt(0); if (battery != 65535) { position.set(Position.KEY_BATTERY, battery * 0.01); @@ -195,20 +274,84 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return position; } - @Override + + private Position decodeLbsWifi(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_LBSWIFI, 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()); + + decodeType(position, parser.next(), "0"); + + getLastLocation(position, null); + + Network network = new Network(); + + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt())); + + int wifiCount = parser.nextInt(); + if (parser.hasNext()) { + String[] wifimacs = parser.next().split(","); + if (wifimacs.length == wifiCount) { + for (int i = 0; i < wifiCount; i++) { + String[] wifiinfo = wifimacs[i].split("\\*"); + network.addWifiAccessPoint(WifiAccessPoint.from( + wifiinfo[0], Integer.parseInt(wifiinfo[1]), Integer.parseInt(wifiinfo[2]))); + } + } + } + + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + return position; + } + + private Position decodeCommandResult(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_COMMAND_RESULT, 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()); + + getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.set(Position.KEY_RESULT, parser.next()); + + return position; + + } + +@Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - int beginIndex = sentence.indexOf('('); - if (beginIndex != -1) { - sentence = sentence.substring(beginIndex + 1); - } - if (channel != null) { - String id = sentence.substring(0, 12); - String type = sentence.substring(12, 16); + String id = sentence.substring(1, 13); + String type = sentence.substring(13, 17); if (type.equals("BP00")) { channel.write("(" + id + "AP01HSO)"); return null; @@ -221,6 +364,10 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return decodeBattery(channel, remoteAddress, sentence); } else if (sentence.contains("BZ00")) { return decodeNetwork(channel, remoteAddress, sentence); + } else if (sentence.contains("ZC03")) { + return decodeCommandResult(channel, remoteAddress, sentence); + } else if (sentence.contains("DW5")) { + return decodeLbsWifi(channel, remoteAddress, sentence); } Parser parser = new Parser(PATTERN, sentence); @@ -299,6 +446,14 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); } + if (parser.hasNext()) { + position.setAltitude(parser.nextDouble(0)); + } + + if (parser.hasNext()) { + position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt(0)); + } + return position; } |