From def60bd842f57d2f82057da2bd51eff757459750 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Mar 2019 23:09:08 -0700 Subject: Custom Xirgo XT2169A protocol --- src/org/traccar/protocol/XirgoProtocolDecoder.java | 107 ++++++++++++++++++++- .../traccar/protocol/XirgoProtocolDecoderTest.java | 12 +++ 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/protocol/XirgoProtocolDecoder.java b/src/org/traccar/protocol/XirgoProtocolDecoder.java index d572b0366..ef1695856 100644 --- a/src/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/org/traccar/protocol/XirgoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,10 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; +import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -29,11 +31,17 @@ import java.util.regex.Pattern; public class XirgoProtocolDecoder extends BaseProtocolDecoder { + private Boolean newFormat; + private String form; + public XirgoProtocolDecoder(Protocol protocol) { super(protocol); + form = Context.getConfig().getString(getProtocolName() + ".form"); } - private Boolean newFormat; + public void setForm(String form) { + this.form = form; + } private static final Pattern PATTERN_OLD = new PatternBuilder() .text("$$") @@ -166,6 +174,101 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; + if (form != null) { + return decodeCustom(channel, remoteAddress, sentence); + } else { + return decodeFixed(channel, remoteAddress, sentence); + } + } + + + private Object decodeCustom( + Channel channel, SocketAddress remoteAddress, String sentence) { + + String[] keys = form.split(","); + String[] values = sentence.replace("$$", "").replace("##", "").split(","); + + Position position = new Position(getProtocolName()); + DateBuilder dateBuilder = new DateBuilder(); + + for (int i = 0; i < Math.min(keys.length, values.length); i++) { + switch (keys[i]) { + case "UID": + case "IM": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + break; + case "EV": + decodeEvent(position, Integer.parseInt(values[i])); + break; + case "D": + String[] date = values[i].split("/"); + dateBuilder.setYear(Integer.parseInt(date[0])); + dateBuilder.setMonth(Integer.parseInt(date[1])); + dateBuilder.setDay(Integer.parseInt(date[2])); + break; + case "T": + String[] time = values[i].split(":"); + dateBuilder.setHour(Integer.parseInt(time[0])); + dateBuilder.setMinute(Integer.parseInt(time[1])); + dateBuilder.setSecond(Integer.parseInt(time[2])); + break; + case "LT": + position.setLatitude(Double.parseDouble(values[i])); + break; + case "LN": + position.setLongitude(Double.parseDouble(values[i])); + break; + case "AL": + position.setAltitude(Integer.parseInt(values[i])); + break; + case "GSPT": + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[i]))); + break; + case "HD": + position.setCourse(Integer.parseInt(values[i]) * 0.1); + break; + case "SV": + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); + break; + case "BV": + position.set(Position.KEY_BATTERY, Double.parseDouble(values[i])); + break; + case "CQ": + position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); + break; + case "MI": + position.set(Position.KEY_ODOMETER, Integer.parseInt(values[i])); + break; + case "GS": + position.setValid(Integer.parseInt(values[i]) == 3); + break; + case "SI": + position.set("iccid", values[i]); + break; + case "IG": + int ignition = Integer.parseInt(values[i]); + if (ignition > 0) { + position.set(Position.KEY_IGNITION, ignition == 1); + } + break; + case "OT": + position.set(Position.KEY_OUTPUT, Integer.parseInt(values[i])); + break; + default: + break; + } + } + + position.setTime(dateBuilder.getDate()); + + return position.getDeviceId() > 0 ? position : null; + } + + private Object decodeFixed( + Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser; if (newFormat == null) { diff --git a/test/org/traccar/protocol/XirgoProtocolDecoderTest.java b/test/org/traccar/protocol/XirgoProtocolDecoderTest.java index 18cf51df0..b2e023574 100644 --- a/test/org/traccar/protocol/XirgoProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XirgoProtocolDecoderTest.java @@ -5,6 +5,18 @@ import org.traccar.ProtocolTest; public class XirgoProtocolDecoderTest extends ProtocolTest { + @Test + public void testDecodeCustom() throws Exception { + + XirgoProtocolDecoder decoder = new XirgoProtocolDecoder(null); + + decoder.setForm("UID,EV,D,T,LT,LN,AL,GSPT,SV,HP,BV,CQ,MI,GS,SI,IG,OT"); + + verifyPosition(decoder, text( + "$$184800793,4002,03/15/2019,21:30:21,46.848582,-114.022237,9733,0.0,18,1.1,13.605,20,0,3,89011703278246523602,2,0##")); + + } + @Test public void testDecodeNew() throws Exception { -- cgit v1.2.3