aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol/MeiligaoProtocolDecoder.java')
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java272
1 files changed, 155 insertions, 117 deletions
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 41e248791..f0e5032b4 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -80,6 +80,24 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
.expression("([EW])")
.compile();
+ private static final Pattern PATTERN_OBD = new PatternBuilder()
+ .number("(d+.d+),") // battery
+ .number("(d+),") // rpm
+ .number("(d+),") // speed
+ .number("(d+.d+),") // throttle
+ .number("(d+.d+),") // engine load
+ .number("(-?d+),") // coolant temp
+ .number("d+.d+,") // instantaneous fuel
+ .number("(d+.d+),") // average fuel
+ .number("(d+.d+),") // driving range
+ .number("(d+.?d*),") // odometer
+ .number("(d+.d+),")
+ .number("(d+.d+),")
+ .number("(d+),") // error code count
+ .number("d+,") // harsh acceleration count
+ .number("d+") // harsh break count
+ .compile();
+
public static final int MSG_HEARTBEAT = 0x0001;
public static final int MSG_SERVER = 0x0002;
public static final int MSG_LOGIN = 0x5000;
@@ -91,6 +109,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_RFID = 0x9966;
+ public static final int MSG_OBD_RT = 0x9901;
+
private DeviceSession identify(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) {
StringBuilder builder = new StringBuilder();
@@ -142,7 +162,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
}
- private String getMeiligaoServer(Channel channel) {
+ private String getServer(Channel channel) {
String server = Context.getConfig().getString(getProtocolName() + ".server");
if (server == null) {
InetSocketAddress address = (InetSocketAddress) channel.getLocalAddress();
@@ -153,23 +173,123 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
private String decodeAlarm(short value) {
switch (value) {
- case 0x01:
- return Position.ALARM_SOS;
- case 0x10:
- return Position.ALARM_LOW_BATTERY;
- case 0x11:
- return Position.ALARM_OVERSPEED;
- case 0x12:
- return Position.ALARM_MOVEMENT;
- case 0x13:
- return Position.ALARM_GEOFENCE_ENTER;
- case 0x50:
- return Position.ALARM_POWER_OFF;
- case 0x53:
- return Position.ALARM_GPS_ANTENNA_CUT;
- default:
+ case 0x01:
+ return Position.ALARM_SOS;
+ case 0x10:
+ return Position.ALARM_LOW_BATTERY;
+ case 0x11:
+ return Position.ALARM_OVERSPEED;
+ case 0x12:
+ return Position.ALARM_MOVEMENT;
+ case 0x13:
+ return Position.ALARM_GEOFENCE_ENTER;
+ case 0x50:
+ return Position.ALARM_POWER_OFF;
+ case 0x53:
+ return Position.ALARM_GPS_ANTENNA_CUT;
+ default:
+ return null;
+ }
+ }
+
+ private Position decodeRegular(Position position, String sentence) {
+ Parser parser = new Parser(PATTERN, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ if (parser.hasNext()) {
+ dateBuilder.setMillis(parser.nextInt());
+ }
+
+ position.setValid(parser.next().equals("A"));
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+
+ if (parser.hasNext()) {
+ position.setSpeed(parser.nextDouble());
+ }
+
+ if (parser.hasNext()) {
+ position.setCourse(parser.nextDouble());
+ }
+
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ position.set(Position.KEY_HDOP, parser.next());
+
+ if (parser.hasNext()) {
+ position.setAltitude(parser.nextDouble());
+ }
+
+ position.set(Position.KEY_STATUS, parser.next());
+
+ for (int i = 1; i <= 8; i++) {
+ if (parser.hasNext()) {
+ position.set(Position.PREFIX_ADC + i, parser.nextInt(16));
+ }
+ }
+
+ if (parser.hasNext()) {
+ position.set(Position.KEY_GSM, parser.nextInt(16));
+ }
+
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextLong(16));
+ }
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextLong(16));
+ }
+
+ if (parser.hasNext()) {
+ position.set(Position.KEY_RFID, parser.nextInt(16));
+ }
+
+ return position;
+ }
+
+ private Position decodeRfid(Position position, String sentence) {
+ Parser parser = new Parser(PATTERN_RFID, sentence);
+ if (!parser.matches()) {
return null;
}
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt())
+ .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ position.setValid(true);
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+
+ return position;
+ }
+
+ private Position decodeObd(Position position, String sentence) {
+ Parser parser = new Parser(PATTERN_OBD, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+ position.set(Position.KEY_RPM, parser.nextInt());
+ position.set(Position.KEY_OBD_SPEED, parser.nextInt());
+ position.set(Position.KEY_THROTTLE, parser.nextDouble());
+ position.set("engineLoad", parser.nextDouble());
+ position.set(Position.PREFIX_TEMP + 1, parser.nextInt());
+ position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble());
+ position.set("drivingRange", parser.nextDouble() * 1000);
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ position.set("singleFuelConsumption", parser.nextDouble());
+ position.set("totalFuelConsumption", parser.nextDouble());
+
+ return position;
}
@Override
@@ -183,39 +303,25 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
int command = buf.readUnsignedShort();
ChannelBuffer response;
- switch (command) {
- case MSG_LOGIN:
- if (channel != null) {
- response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
- sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response);
- }
+ if (channel != null) {
+ if (command == MSG_LOGIN) {
+ response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
+ sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response);
return null;
- case MSG_HEARTBEAT:
- if (channel != null) {
- response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
- sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response);
- }
+ } else if (command == MSG_HEARTBEAT) {
+ response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
+ sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response);
return null;
- case MSG_SERVER:
- if (channel != null) {
- response = ChannelBuffers.copiedBuffer(
- getMeiligaoServer(channel), StandardCharsets.US_ASCII);
- sendResponse(channel, remoteAddress, id, MSG_SERVER, response);
- }
- return null;
- case MSG_POSITION:
- case MSG_POSITION_LOGGED:
- case MSG_ALARM:
- case MSG_RFID:
- break;
- default:
+ } else if (command == MSG_SERVER) {
+ response = ChannelBuffers.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII);
+ sendResponse(channel, remoteAddress, id, MSG_SERVER, response);
return null;
+ }
}
Position position = new Position();
position.setProtocol(getProtocolName());
- // Custom data
if (command == MSG_ALARM) {
position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte()));
} else if (command == MSG_POSITION_LOGGED) {
@@ -239,85 +345,17 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
}
- Pattern pattern;
- if (command == MSG_RFID) {
- pattern = PATTERN_RFID;
- } else {
- pattern = PATTERN;
- }
-
- Parser parser = new Parser(
- pattern, buf.toString(buf.readerIndex(), buf.readableBytes() - 4, StandardCharsets.US_ASCII));
- if (!parser.matches()) {
- return null;
- }
-
- if (command == MSG_RFID) {
-
- DateBuilder dateBuilder = new DateBuilder()
- .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt())
- .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
- position.setTime(dateBuilder.getDate());
-
- position.setValid(true);
- position.setLatitude(parser.nextCoordinate());
- position.setLongitude(parser.nextCoordinate());
-
- } else {
-
- DateBuilder dateBuilder = new DateBuilder()
- .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
- if (parser.hasNext()) {
- dateBuilder.setMillis(parser.nextInt());
- }
-
- position.setValid(parser.next().equals("A"));
- position.setLatitude(parser.nextCoordinate());
- position.setLongitude(parser.nextCoordinate());
-
- if (parser.hasNext()) {
- position.setSpeed(parser.nextDouble());
- }
-
- if (parser.hasNext()) {
- position.setCourse(parser.nextDouble());
- }
-
- dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
- position.setTime(dateBuilder.getDate());
-
- position.set(Position.KEY_HDOP, parser.next());
-
- if (parser.hasNext()) {
- position.setAltitude(parser.nextDouble());
- }
-
- position.set(Position.KEY_STATUS, parser.next());
-
- for (int i = 1; i <= 8; i++) {
- if (parser.hasNext()) {
- position.set(Position.PREFIX_ADC + i, parser.nextInt(16));
- }
- }
-
- if (parser.hasNext()) {
- position.set(Position.KEY_GSM, parser.nextInt(16));
- }
-
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextLong(16));
- }
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextLong(16));
- }
-
- if (parser.hasNext()) {
- position.set(Position.KEY_RFID, parser.nextInt(16));
- }
+ String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 4, StandardCharsets.US_ASCII);
+ if (command == MSG_POSITION || command == MSG_POSITION_LOGGED || command == MSG_ALARM) {
+ return decodeRegular(position, sentence);
+ } else if (command == MSG_RFID) {
+ return decodeRfid(position, sentence);
+ } else if (command == MSG_OBD_RT) {
+ return decodeObd(position, sentence);
}
- return position;
+ return null;
}
}