From 195e7b5b45c08fa4fad4f9c8797f8807ded1dbea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Sep 2017 23:13:03 +1200 Subject: Support universal Suntech format --- .../traccar/protocol/SuntechProtocolDecoder.java | 116 ++++++++++++++++++--- .../protocol/SuntechProtocolDecoderTest.java | 6 ++ 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 39804159f..3b350ba64 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -19,6 +19,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -70,19 +71,19 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return null; } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + if (deviceSession == null) { + return null; + } + Position position = new Position(); position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); if (type.equals("Emergency") || type.equals("Alert")) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - if (!type.equals("Alert") || protocolType == 0) { position.set(Position.KEY_VERSION_FW, values[index++]); } @@ -137,15 +138,15 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.set(Position.KEY_TYPE, type); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); if (protocol.equals("ST300") || protocol.equals("ST500")) { index += 1; // model @@ -242,18 +243,105 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeUniversal( + Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { + int index = 0; + + String type = values[index++]; + + if (!type.equals("STT")) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); + + int mask = Integer.parseInt(values[index++], 16); + + if (BitUtil.check(mask, 1)) { + index += 1; // model + } + + if (BitUtil.check(mask, 2)) { + position.set(Position.KEY_VERSION_FW, values[index++]); + } + + if (BitUtil.check(mask, 3) && values[index++].equals("0")) { + position.set(Position.KEY_ARCHIVE, true); + } + + if (BitUtil.check(mask, 4) && BitUtil.check(mask, 5)) { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(values[index++] + values[index++])); + } + + if (BitUtil.check(mask, 6)) { + index += 1; // cell + } + + if (BitUtil.check(mask, 7)) { + index += 1; // mcc + } + + if (BitUtil.check(mask, 8)) { + index += 1; // mnc + } + + if (BitUtil.check(mask, 9)) { + index += 1; // lac + } + + if (BitUtil.check(mask, 10)) { + position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); + } + + if (BitUtil.check(mask, 11)) { + position.setLatitude(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 12)) { + position.setLongitude(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 13)) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + } + + if (BitUtil.check(mask, 14)) { + position.setCourse(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 15)) { + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + } + + if (BitUtil.check(mask, 16)) { + position.setValid(values[index++].equals("1")); + } + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String[] values = ((String) msg).split(";"); - String protocol = values[0].substring(0, 5); - - if (protocol.equals("ST910")) { + if (values[0].length() < 5) { + return decodeUniversal(channel, remoteAddress, values); + } else if (values[0].equals("ST910")) { return decode9(channel, remoteAddress, values); } else { - return decode235(channel, remoteAddress, protocol, values); + return decode235(channel, remoteAddress, values[0].substring(0, 5), values); } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index d46ca3d34..45230a339 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -30,6 +30,12 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "STT;100850000;3FFFFF;26;010;1;20161117;08:37:39;0000004F;450;0;0014;20;+37.479323;+126.887827;62.03;65.43;10;1;00000101;00001000;1;2;0492")); + + verifyPosition(decoder, text( + "STT;6009999006;3FFFFF;26;398;0;20170827;20:04:37;087d4760;310;410;0ba0;23;+40.123420;-074.995971;000.031;000.00;8;1;00000001;00000000;1;1;0006")); + verifyPosition(decoder, text( "ST500STT;205450135;07;843;20170816;23:24:45;+19.338432;-099.179817;000.283;000.00;6;1;141121;12.89;0;0;1;4659;002.795;0;001.891;611;4.0")); -- cgit v1.2.3