aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2016-09-07 20:09:30 +1200
committerAnton Tananaev <anton.tananaev@gmail.com>2016-09-07 20:09:30 +1200
commitabe051d297b445f8fb76d4069918b79e9e74d0c9 (patch)
tree0a6e37b70d1ee6a3ac6de64aea3af4b980f02ec9 /src/org/traccar/protocol
parent5e6a5e69994aff3c1fe9aca427c746438a22c325 (diff)
downloadtraccar-server-abe051d297b445f8fb76d4069918b79e9e74d0c9.tar.gz
traccar-server-abe051d297b445f8fb76d4069918b79e9e74d0c9.tar.bz2
traccar-server-abe051d297b445f8fb76d4069918b79e9e74d0c9.zip
Implement OBD support for Meiligao
Diffstat (limited to 'src/org/traccar/protocol')
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java241
1 files changed, 136 insertions, 105 deletions
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 41e248791..8b559beec 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();
@@ -172,6 +192,102 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
}
+ 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(Position.PREFIX_TEMP + 1, parser.nextInt());
+ position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble());
+ position.set(Position.KEY_ODOMETER, parser.nextDouble());
+
+ return position;
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -183,39 +299,22 @@ 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);
- }
- return null;
- case MSG_HEARTBEAT:
- if (channel != null) {
- 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:
- return null;
+ if (channel != null) {
+ if (command == MSG_LOGIN) {
+ response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
+ sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response);
+ } else if (command == MSG_HEARTBEAT) {
+ response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
+ sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response);
+ } else if (command == MSG_SERVER) {
+ response = ChannelBuffers.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII);
+ sendResponse(channel, remoteAddress, id, MSG_SERVER, response);
+ }
}
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 +338,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;
}
}