diff options
-rw-r--r-- | src/org/traccar/protocol/MegastekProtocolDecoder.java | 203 | ||||
-rw-r--r-- | test/org/traccar/protocol/MegastekProtocolDecoderTest.java | 10 |
2 files changed, 161 insertions, 52 deletions
diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index f863df153..d014869d8 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -33,9 +33,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { super(serverManager); } - static private Pattern pattern = Pattern.compile( - "STX," + - "[^,]+," + // Identifier (not IMEI) + static private Pattern patternGPRMC = Pattern.compile( "\\$GPRMC," + "(\\d{2})(\\d{2})(\\d{2})\\.\\d+," + // Time (HHMMSS.SSS) "([AV])," + // Validity @@ -43,10 +41,12 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { "([NS])," + "(\\d+)(\\d{2}\\.\\d+)," + // Longitude (DDDMM.MMMM) "([EW])," + - "(\\d+\\.\\d{2})?," + // Speed - "(\\d+\\.\\d{2})?," + // Course + "(\\d+\\.\\d+)?," + // Speed + "(\\d+\\.\\d+)?," + // Course "(\\d{2})(\\d{2})(\\d{2})" + // Date (DDMMYY) - "[^\\*]+\\*[0-9a-fA-F]{2}," + // Checksumm + "[^\\*]+\\*[0-9a-fA-F]{2}"); // Checksum + + static private Pattern patternSimple = Pattern.compile( "[FL]," + // Flag "([^,]*)," + // Alarm "imei:(\\d+)," + // IMEI @@ -56,25 +56,32 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { "(\\d)?," + // Charger "(\\d+)," + // MCC "(\\d+)," + // MNC - "([0-9a-fA-F]+,[0-9a-fA-F]+);" + // Location code - ".+"); // Checksumm - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, Object msg) - throws Exception { + "(\\p{XDigit}{4},\\p{XDigit}{4});" + // Location code + ".+"); // Checksum - String sentence = (String) msg; + static private Pattern patternAlternative = Pattern.compile( + "(\\d+)," + // MCC + "(\\d+)," + // MNC + "(\\p{XDigit}{4},\\p{XDigit}{4})," + // Location code + "(\\d+)," + // GSM signal + "(\\d+)," + // Battery + "(\\d+)," + // Flags + "(\\d+)," + // Inputs + "(\\d+)," + // Outputs + "(\\d\\.\\d{2})," + // ADC 1 + "(\\d\\.\\d{2})," + // ADC 2 + "(\\d\\.\\d{2})," + // ADC 3 + "([^;]+);" + // Alarm + ".+"); // Checksum + private boolean parseGPRMC(String gprmc, Position position) { + // Parse message - Matcher parser = pattern.matcher(sentence); + Matcher parser = patternGPRMC.matcher(gprmc); if (!parser.matches()) { - return null; + return false; } - // Create new position - Position position = new Position(); - ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("megastek"); int index = 1; // Time @@ -119,50 +126,146 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++))); - position.setTime(time.getTime()); + position.setTime(time.getTime()); - // Alarm - extendedInfo.set("alarm", parser.group(index++)); + return true; + } + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, Object msg) + throws Exception { - // IMEI - String imei = parser.group(index++); - try { - position.setDeviceId(getDataManager().getDeviceByImei(imei).getId()); - } catch(Exception error) { - Log.warning("Unknown device - " + imei); - return null; + String sentence = (String) msg; + + // Detect type + boolean simple = (sentence.charAt(3) == ','); + + // Split message + String id; + String gprmc; + String status; + if (simple) { + + int beginIndex = 4; + int endIndex = sentence.indexOf(',', beginIndex); + id = sentence.substring(beginIndex, endIndex); + + beginIndex = endIndex + 1; + endIndex = sentence.indexOf('*', beginIndex) + 3; + gprmc = sentence.substring(beginIndex, endIndex); + + beginIndex = endIndex + 1; + status = sentence.substring(beginIndex); + + } else { + + int beginIndex = 3; + int endIndex = beginIndex + 16; + id = sentence.substring(beginIndex, endIndex).trim(); + + beginIndex = endIndex + 2; + endIndex = sentence.indexOf('*', beginIndex) + 3; + gprmc = sentence.substring(beginIndex, endIndex); + + beginIndex = endIndex + 1; + status = sentence.substring(beginIndex); + } - // Satellites - String satellites = parser.group(index++); - if (satellites != null) { - extendedInfo.set("satellites", satellites); + // Create new position + Position position = new Position(); + ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("megastek"); + + // Parse location data + if (!parseGPRMC(gprmc, position)) { + return null; } + + if (simple) { - // Altitude - position.setAltitude(Double.valueOf(parser.group(index++))); + // Parse status + Matcher parser = patternSimple.matcher(status); + if (!parser.matches()) { + return null; + } + + int index = 1; - // Battery - position.setPower(Double.valueOf(parser.group(index++))); + // Alarm + extendedInfo.set("alarm", parser.group(index++)); - // Charger - String charger = parser.group(index++); - if (charger != null) { - extendedInfo.set("charger", Integer.valueOf(charger) == 1); - } + // IMEI + String imei = parser.group(index++); + try { + position.setDeviceId(getDataManager().getDeviceByImei(imei).getId()); + } catch(Exception firstError) { + try { + position.setDeviceId(getDataManager().getDeviceByImei(id).getId()); + } catch(Exception secondError) { + Log.warning("Unknown device - " + imei + "(id - " + id + ")"); + return null; + } + } - // MCC - extendedInfo.set("mcc", parser.group(index++)); + // Satellites + String satellites = parser.group(index++); + if (satellites != null) { + extendedInfo.set("satellites", satellites); + } - // MNC - extendedInfo.set("mnc", parser.group(index++)); + // Altitude + position.setAltitude(Double.valueOf(parser.group(index++))); - // LAC - extendedInfo.set("lac", parser.group(index++)); + // Battery + position.setPower(Double.valueOf(parser.group(index++))); - // Extended info - position.setExtendedInfo(extendedInfo.toString()); + // Charger + String charger = parser.group(index++); + if (charger != null) { + extendedInfo.set("charger", Integer.valueOf(charger) == 1); + } + + extendedInfo.set("mcc", parser.group(index++)); + extendedInfo.set("mnc", parser.group(index++)); + extendedInfo.set("lac", parser.group(index++)); + + } else { + // Parse status + Matcher parser = patternAlternative.matcher(status); + if (!parser.matches()) { + return null; + } + + int index = 1; + + try { + position.setDeviceId(getDataManager().getDeviceByImei(id).getId()); + } catch(Exception error) { + Log.warning("Unknown device - " + id); + return null; + } + + extendedInfo.set("mcc", parser.group(index++)); + extendedInfo.set("mnc", parser.group(index++)); + extendedInfo.set("lac", parser.group(index++)); + extendedInfo.set("gsm", parser.group(index++)); + + // Battery + position.setPower(Double.valueOf(parser.group(index++))); + + extendedInfo.set("flags", parser.group(index++)); + extendedInfo.set("input", parser.group(index++)); + extendedInfo.set("output", parser.group(index++)); + extendedInfo.set("adc1", parser.group(index++)); + extendedInfo.set("adc2", parser.group(index++)); + extendedInfo.set("adc3", parser.group(index++)); + extendedInfo.set("alarm", parser.group(index++)); + + } + + position.setExtendedInfo(extendedInfo.toString()); return position; } diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java index f4998d3f9..33ef6fe40 100644 --- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -10,16 +10,22 @@ public class MegastekProtocolDecoderTest { MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(null); decoder.setDataManager(new TestDataManager()); - + assertNotNull(decoder.decode(null, null, "STX,GerAL22,$GPRMC,174752.000,A,3637.060059,S,6416.2354,W,0.00,0.00,030812,,,A*55,F,,imei:861785000249353,05,180.6,Battery=100%,,1,722,310,0FA6,39D0;8F")); - + assertNotNull(decoder.decode(null, null, "STX,GerAL22,$GPRMC,000051.000,A,3637.079590,S,6416.2148,W,1.72,332.98,010109,,,A*52,L,,imei:861785000249353,03,275.3,Battery=68%,,1,722,07,0515,1413;41")); assertNotNull(decoder.decode(null, null, "STX,102110830074542,$GPRMC,114229.000,A,2238.2024,N,11401.9619,E,0.00,0.00,310811,,,A*64,F,LowBattery,imei:012207005553885,03,113.1,Battery=24%,,1,460,01,2531,647E;57")); + assertNotNull(decoder.decode(null, null, + "STX863070014949464 $GPRMC,215942.290,A,4200.1831,N,02128.5904,E,003.1,079.8,090813,,,A*6E,294,02,0064,0F3D,18,17,0000,000000,0000,0.00,0.02,0.00,Store;D8")); + + assertNotNull(decoder.decode(null, null, + "STX123456 $GPRMC,063709.000,A,2238.1998,N,11401.9670,E,0.00,,250313,,,A*7F,460,01,2531,647E,11,87,1000,001001,0000,0.00,0.02,0.00,Timer;4A")); + } } |