mirror of
https://github.com/traccar/traccar.git
synced 2025-01-09 04:07:38 +08:00
Implement Aquila track protocol
This commit is contained in:
parent
a3f912fc98
commit
85bb659197
@ -336,5 +336,6 @@
|
||||
<entry key='castel.port'>5086</entry>
|
||||
<entry key='mxt.port'>5087</entry>
|
||||
<entry key='cityeasy.port'>5088</entry>
|
||||
<entry key='aquila.port'>5089</entry>
|
||||
|
||||
</properties>
|
||||
|
41
src/org/traccar/helper/PatternUtil.java
Normal file
41
src/org/traccar/helper/PatternUtil.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.traccar.helper;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class PatternUtil {
|
||||
|
||||
public static String checkPattern(String pattern, String input) {
|
||||
|
||||
String match = null;
|
||||
|
||||
for (int i = 0; i < pattern.length(); i++) {
|
||||
try {
|
||||
Matcher matcher = Pattern.compile(pattern.substring(0, i) + ".*").matcher(input);
|
||||
if (matcher.matches()) {
|
||||
match = pattern.substring(0, i);
|
||||
}
|
||||
} catch (PatternSyntaxException e) {
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
}
|
45
src/org/traccar/protocol/AquilaProtocol.java
Normal file
45
src/org/traccar/protocol/AquilaProtocol.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.traccar.protocol;
|
||||
|
||||
import org.jboss.netty.bootstrap.ServerBootstrap;
|
||||
import org.jboss.netty.channel.ChannelPipeline;
|
||||
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
|
||||
import org.jboss.netty.handler.codec.string.StringDecoder;
|
||||
import org.traccar.BaseProtocol;
|
||||
import org.traccar.TrackerServer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AquilaProtocol extends BaseProtocol {
|
||||
|
||||
public AquilaProtocol() {
|
||||
super("aquila");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initTrackerServers(List<TrackerServer> serverList) {
|
||||
serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) {
|
||||
@Override
|
||||
protected void addSpecificHandlers(ChannelPipeline pipeline) {
|
||||
pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
|
||||
pipeline.addLast("stringDecoder", new StringDecoder());
|
||||
pipeline.addLast("objectDecoder", new AquilaProtocolDecoder(AquilaProtocol.this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
116
src/org/traccar/protocol/AquilaProtocolDecoder.java
Normal file
116
src/org/traccar/protocol/AquilaProtocolDecoder.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.traccar.protocol;
|
||||
|
||||
import org.jboss.netty.channel.Channel;
|
||||
import org.traccar.BaseProtocolDecoder;
|
||||
import org.traccar.helper.UnitsConverter;
|
||||
import org.traccar.model.Event;
|
||||
import org.traccar.model.Position;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Calendar;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AquilaProtocolDecoder extends BaseProtocolDecoder {
|
||||
|
||||
public AquilaProtocolDecoder(AquilaProtocol protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
private static final Pattern pattern = Pattern.compile(
|
||||
"\\$\\$" +
|
||||
"CLIENT_[^,]+," + // IMEI
|
||||
"(\\d+)," + // Device serial number
|
||||
"(\\d+)," + // Event
|
||||
"(-?\\d+\\.\\d+)," + // Latitude
|
||||
"(-?\\d+\\.\\d+)," + // Longitude
|
||||
"(\\d{2})(\\d{2})(\\d{2})" + // Date (YYMMDD)
|
||||
"(\\d{2})(\\d{2})(\\d{2})," + // Time (HHMMSS)
|
||||
"([AV])," + // Validity
|
||||
"(\\d+)," + // GSM
|
||||
"(\\d+)," + // Speed
|
||||
"\\d+," + // Driver code
|
||||
"(\\d+)," + // Fuel
|
||||
"(\\d+)," + // IO 1
|
||||
"[01]," + // Case open switch
|
||||
"[01]," + // Over speed start
|
||||
"[01]," + // Over speed end
|
||||
"0,0,0," + // Reserved
|
||||
"([01])," + // Power status
|
||||
"([01])," + // IO 2
|
||||
"0," + // Reserved
|
||||
"([01])," + // Ignition
|
||||
"[01]," + // Ignition off event
|
||||
".*");
|
||||
|
||||
@Override
|
||||
protected Object decode(
|
||||
Channel channel, SocketAddress remoteAddress, Object msg)
|
||||
throws Exception {
|
||||
|
||||
String sentence = (String) msg;
|
||||
|
||||
Matcher parser = pattern.matcher(sentence);
|
||||
if (!parser.matches()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Position position = new Position();
|
||||
position.setProtocol(getProtocolName());
|
||||
|
||||
Integer index = 1;
|
||||
|
||||
String id = parser.group(index++);
|
||||
if (!identify(id, channel)) {
|
||||
return null;
|
||||
}
|
||||
position.setDeviceId(getDeviceId());
|
||||
|
||||
position.set(Event.KEY_EVENT, Integer.parseInt(parser.group(index++)));
|
||||
|
||||
position.setLatitude(Double.parseDouble(parser.group(index++)));
|
||||
position.setLongitude(Double.parseDouble(parser.group(index++)));
|
||||
|
||||
Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
time.clear();
|
||||
time.set(Calendar.YEAR, 2000 + Integer.parseInt(parser.group(index++)));
|
||||
time.set(Calendar.MONTH, Integer.parseInt(parser.group(index++)) - 1);
|
||||
time.set(Calendar.DAY_OF_MONTH, Integer.parseInt(parser.group(index++)));
|
||||
time.set(Calendar.HOUR_OF_DAY, Integer.parseInt(parser.group(index++)));
|
||||
time.set(Calendar.MINUTE, Integer.parseInt(parser.group(index++)));
|
||||
time.set(Calendar.SECOND, Integer.parseInt(parser.group(index++)));
|
||||
position.setTime(time.getTime());
|
||||
|
||||
position.setValid(parser.group(index++).equals("A"));
|
||||
|
||||
position.set(Event.KEY_GSM, Integer.parseInt(parser.group(index++)));
|
||||
|
||||
position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(parser.group(index++))));
|
||||
|
||||
position.set(Event.KEY_FUEL, parser.group(index++));
|
||||
position.set(Event.PREFIX_IO + 1, parser.group(index++));
|
||||
position.set(Event.KEY_CHARGE, parser.group(index++));
|
||||
position.set(Event.PREFIX_IO + 2, parser.group(index++));
|
||||
|
||||
position.set(Event.KEY_IGNITION, parser.group(index++).equals("1"));
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
}
|
16
test/org/traccar/helper/PatternUtilTest.java
Normal file
16
test/org/traccar/helper/PatternUtilTest.java
Normal file
@ -0,0 +1,16 @@
|
||||
package org.traccar.helper;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class PatternUtilTest {
|
||||
|
||||
@Test
|
||||
public void testCheckPattern() {
|
||||
|
||||
assertEquals("ab", PatternUtil.checkPattern("abc", "abd"));
|
||||
|
||||
}
|
||||
|
||||
}
|
25
test/org/traccar/protocol/AquilaProtocolDecoderTest.java
Normal file
25
test/org/traccar/protocol/AquilaProtocolDecoderTest.java
Normal file
@ -0,0 +1,25 @@
|
||||
package org.traccar.protocol;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.traccar.helper.DecoderVerifier.verify;
|
||||
|
||||
public class AquilaProtocolDecoderTest extends ProtocolDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testDecode() throws Exception {
|
||||
|
||||
AquilaProtocolDecoder decoder = new AquilaProtocolDecoder(new AquilaProtocol());
|
||||
|
||||
verify(decoder.decode(null, null,
|
||||
"$$CLIENT_1ZF,130329214,1,12.962985,77.576484,140127165433,A,22,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,*26"));
|
||||
|
||||
verify(decoder.decode(null, null,
|
||||
"$$CLIENT_1WP,141216511,3,12.963123,77.534012,150908163534,A,31,0,0,0,7,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,*28"));
|
||||
|
||||
verify(decoder.decode(null, null,
|
||||
"$$CLIENT_1WP,141216511,3,12.963212,77.533989,150908164041,V,31,0,0,0,8,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,*2A"));
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user