aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol/Tk103ProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol/Tk103ProtocolDecoder.java')
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolDecoder.java137
1 files changed, 44 insertions, 93 deletions
diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
index e52d60848..2ce7def45 100644
--- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
@@ -29,8 +29,6 @@ import org.traccar.model.Position;
import org.traccar.model.WifiAccessPoint;
import java.net.SocketAddress;
-import java.util.HashMap;
-import java.util.Map;
import java.util.regex.Pattern;
public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
@@ -67,8 +65,8 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
.any()
.number("([+-]ddd.d)?") // temperature
.groupBegin()
- .number("([+-]?d+.d{1,2}),").optional() // altitude
- .number("(d+)$").optional() // number of visible satellites
+ .number("([+-]?d+.d{1,2}),") // altitude
+ .number("(d+)$") // number of visible satellites
.groupEnd("?")
.text(")").optional()
.compile();
@@ -102,12 +100,21 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // lac
.number("(d+),") // cid
.number("(d+),") // number of wifi macs
- .expression("((?:(?:[0-9A-Fa-f]{2}:){5}(?:[0-9A-Fa-f]{2})\\*[-+]?\\d{1,2}\\*\\d{1,2},)*)")
+ .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()
+ .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:
@@ -132,90 +139,61 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
case "BO01":
position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0'));
break;
- // Motion Alert with Location
case "ZC11":
case "DW31":
case "DW51":
position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT);
break;
- // Low Battery Alert with Location
case "ZC12":
case "DW32":
case "DW52":
position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
break;
- // Power Cut Alert with Location
case "ZC13":
case "DW33":
case "DW53":
position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
break;
- // ACC On Alert with Location
case "ZC15":
case "DW35":
case "DW55":
position.set(Position.KEY_IGNITION, true);
break;
- // ACC Off Alert with Location
case "ZC16":
case "DW36":
case "DW56":
position.set(Position.KEY_IGNITION, false);
break;
- // Ignition Alert with Location
case "ZC29":
case "DW42":
case "DW62":
position.set(Position.KEY_IGNITION, true);
break;
- // Dismounting Alert with Location
case "ZC17":
case "DW37":
case "DW57":
position.set(Position.KEY_ALARM, Position.ALARM_REMOVING);
break;
- // SOS Alert with Location
case "ZC25":
case "DW3E":
case "DW5E":
position.set(Position.KEY_ALARM, Position.ALARM_SOS);
break;
- // Tampering Alert with Location:
case "ZC26":
case "DW3F":
case "DW5F":
position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING);
break;
- // Low Power Alert with Location
case "ZC27":
case "DW40":
case "DW60":
position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER);
break;
- // Bad Battery Alert with Location
case "ZC28":
case "DW41":
case "DW61":
position.set(Position.KEY_ALARM, "badBattery");
break;
- // Fuel Cut On with Location
- case "ZC2A":
- case "DW43":
- case "DW63":
- position.set(Position.KEY_FUEL_LEVEL, 0.0);
- break;
- // Fuel Cut Off with Location:
- case "ZC2B":
- case "DW44":
- case "DW64":
- position.set(Position.KEY_FUEL_LEVEL, 1.0);
- break;
- // Fuel Cut Alert with Location:
- case "ZC2C":
- case "DW45":
- case "DW65":
- position.set(Position.KEY_ALARM, "fuelCut");
- break;
default:
break;
}
@@ -228,7 +206,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
case 5:
return 80;
case 4:
- return 60;
+ return 50;
case 3:
return 20;
case 2:
@@ -238,34 +216,6 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
}
}
- private static Map<Long, Position> batteryInfo = new HashMap<Long, Position>();
-
- public void setLastBatteryPower(Position positionWithCurrentBatteryInfo) {
- batteryInfo.put(positionWithCurrentBatteryInfo.getDeviceId(), positionWithCurrentBatteryInfo);
- }
-
- // It is possible to use "processing.copyAttributes" configuration to have battery level in all events,
- // but this will not work if battery events will be filtered somehow and dropped from DB, so it will be no
- // event in DB with latest battery level. So, ensure all our events have latest battery level.
- public void getLastBatteryPower(Position position) {
- if (position != null && position.getDeviceId() != 0) {
- Position bi = batteryInfo.get(position.getDeviceId());
- if (bi == null) {
- bi = new Position();
- getLastLocation(bi, null);
- }
- if (bi.getAttributes().containsKey(Position.KEY_BATTERY_LEVEL)) {
- position.set(Position.KEY_BATTERY_LEVEL, bi.getDouble(Position.KEY_BATTERY_LEVEL));
- }
- if (bi.getAttributes().containsKey(Position.KEY_BATTERY)) {
- position.set(Position.KEY_BATTERY, bi.getDouble(Position.KEY_BATTERY));
- }
- if (bi.getAttributes().containsKey(Position.KEY_POWER)) {
- position.set(Position.KEY_POWER, bi.getDouble(Position.KEY_POWER));
- }
- }
- }
-
private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) {
Parser parser = new Parser(PATTERN_BATTERY, sentence);
if (!parser.matches()) {
@@ -298,8 +248,6 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_POWER, power * 0.1);
}
- setLastBatteryPower(position);
-
return position;
}
@@ -320,8 +268,6 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
getLastLocation(position, null);
- getLastBatteryPower(position);
-
position.setNetwork(new Network(CellTower.from(
parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0))));
@@ -347,21 +293,16 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
getLastLocation(position, null);
- getLastBatteryPower(position);
-
Network network = new Network();
- // Parse LBS
network.addCellTower(CellTower.from(
parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()));
- // Parse WiFi macs number and mac addresses itself.
int wifiCount = parser.nextInt();
if (parser.hasNext()) {
String[] wifimacs = parser.next().split(",");
if (wifimacs.length == wifiCount) {
for (int i = 0; i < wifiCount; i++) {
- // Sample wifi string: “00:80:E1:7F:86:97*-55*6” (mac*rssi*channel_number)
String[] wifiinfo = wifimacs[i].split("\\*");
network.addWifiAccessPoint(WifiAccessPoint.from(
wifiinfo[0], Integer.parseInt(wifiinfo[1]), Integer.parseInt(wifiinfo[2])));
@@ -373,21 +314,35 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
position.setNetwork(network);
}
- // Parse date-time
- DateBuilder dateBuilder = new DateBuilder()
- .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt())
- .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
- // Set both DeviceTime and FixTime here, as some alarm messages like SOS at device start may be
- // sent without valid LBS/WiFi position, so FixTime from getLastLocation will be used as time
- // for this SOS alarm, which can be very old. And traccar UI only display FixTime.
- // Valid flag will be "false" anyway, so it is possible to check should the position and fixTime
- // be trusted or not.
- position.setTime(dateBuilder.getDate());
+ position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
return position;
}
- @Override
+ 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 {
@@ -398,7 +353,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
sentence = sentence.substring(beginIndex + 1);
}
- if (channel != null) {
+ if (channel != null && sentence.length() >= 16) {
String id = sentence.substring(0, 12);
String type = sentence.substring(12, 16);
if (type.equals("BP00")) {
@@ -413,11 +368,10 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return decodeBattery(channel, remoteAddress, sentence);
} else if (sentence.contains("BZ00")) {
return decodeNetwork(channel, remoteAddress, sentence);
- }
-
- Position positionWifi = decodeLbsWifi(channel, remoteAddress, sentence);
- if (positionWifi != null) {
- return positionWifi;
+ } 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);
@@ -438,8 +392,6 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
decodeType(position, parser.next(), parser.next());
- getLastBatteryPower(position);
-
DateBuilder dateBuilder = new DateBuilder();
if (alternative) {
dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
@@ -503,8 +455,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
}
if (parser.hasNext()) {
- // Store amount of visible satellites as RSSI
- position.set(Position.KEY_RSSI, parser.nextInt(0));
+ position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt(0));
}
return position;