diff options
Diffstat (limited to 'src/org/traccar/protocol')
-rw-r--r-- | src/org/traccar/protocol/LaipacProtocolDecoder.java | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/src/org/traccar/protocol/LaipacProtocolDecoder.java b/src/org/traccar/protocol/LaipacProtocolDecoder.java index 99189d012..9357123c8 100644 --- a/src/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/org/traccar/protocol/LaipacProtocolDecoder.java @@ -22,6 +22,8 @@ import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; @@ -45,8 +47,18 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d+),") // speed .number("(d+.d+),") // course .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("(.),") // type - .expression("[^*]+").text("*") + .expression("([abZXTSMHFE86430]),") // event code + .expression("([\\d.]+),") // battery voltage + .number("(d+),") // current mileage + .number("(d),") // GPS on/off (1 = on, 0 = off) + .number("(d+),") // Analog port 1 + .number("(d+)") // Analog port 2 + .expression(",([0-9a-fA-F]{4})") // Cell 1 - Cell Net Code + .expression("([0-9a-fA-F]{4}),") // Cell 1 - Cell ID Code + .number("(d{3})") // Cell 2 - Country Code + .number("(d{3})") // Cell 2 - Operator Code + .optional(4) + .text("*") .number("(xx)") // checksum .compile(); @@ -79,6 +91,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { String status = parser.next(); position.setValid(status.toUpperCase().equals("A")); + position.set(Position.KEY_STATUS, status); position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); @@ -88,28 +101,72 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); position.setTime(dateBuilder.getDate()); - String type = parser.next(); + String eventCode = parser.next(); + position.set(Position.KEY_ALARM, decodeAlarm(eventCode)); + position.set(Position.KEY_EVENT, eventCode); + + String batteryVoltage = parser.next(); + batteryVoltage = batteryVoltage.replaceAll("\\.", ""); + position.set(Position.KEY_BATTERY, Double.parseDouble(batteryVoltage) * 0.001); + + position.set(Position.KEY_ODOMETER, parser.nextDouble()); + position.set(Position.KEY_GPS, parser.nextInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001); + position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); + + String lac = parser.next(); + String cid = parser.next(); + String mcc = parser.next(); + String mnc = parser.next(); + if (lac != null + && cid != null + && mcc != null + && mnc != null) { + position.setNetwork(new Network(CellTower.from(Integer.parseInt(mcc), Integer.parseInt(mnc), + Integer.parseInt(lac, 16), Long.parseLong(cid, 16)))); + } + String checksum = parser.next(); if (channel != null) { - - if (Character.isLowerCase(status.charAt(0))) { - String response = "$EAVACK," + type + "," + checksum; + if (eventCode.equals("3")) { + channel.write("$AVCFG,00000000,d*31\r\n"); + } else if (eventCode.equals("X") || eventCode.equals("4")) { + channel.write("$AVCFG,00000000,x*2D\r\n"); + } else if (eventCode.equals("Z")) { + channel.write("$AVCFG,00000000,z*2F\r\n"); + } else if (Character.isLowerCase(status.charAt(0))) { + String response = "$EAVACK," + eventCode + "," + checksum; response += Checksum.nmea(response); + response += "\r\n"; channel.write(response); } - - if (type.equals("S") || type.equals("T")) { - channel.write("$AVCFG,00000000,t*21"); - } else if (type.equals("3")) { - channel.write("$AVCFG,00000000,d*31"); - } else if (type.equals("X") || type.equals("4")) { - channel.write("$AVCFG,00000000,x*2D"); - } - } return position; } + private String decodeAlarm(String event) { + switch (event) { + case "Z": + return Position.ALARM_LOW_BATTERY; + case "X": + return Position.ALARM_GEOFENCE_ENTER; + case "T": + return Position.ALARM_TAMPERING; + case "H": + return Position.ALARM_POWER_OFF; + case "8": + return Position.ALARM_SHOCK; + case "7": + case "4": + return Position.ALARM_GEOFENCE_EXIT; + case "6": + return Position.ALARM_OVERSPEED; + case "3": + return Position.ALARM_SOS; + default: + return null; + } + } } |