From 5193bd866734b6fea1bf96b5d975c52f09cbec2e Mon Sep 17 00:00:00 2001 From: namo Date: Fri, 13 Oct 2017 16:03:25 +0300 Subject: initial flespi integtation: pulling messages from flespi channels and updating devices' position --- setup/default.xml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 95b69e216..0a7b421d7 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -218,4 +218,10 @@ 5147 5148 + + true + https://flespi.io + + + -- cgit v1.2.3 From da4fce0da7be92b381c6cdc1069486bc83a2974d Mon Sep 17 00:00:00 2001 From: namo Date: Thu, 19 Oct 2017 17:59:25 +0300 Subject: Revert "initial flespi integtation: pulling messages from flespi channels and updating devices' position" This reverts commit 5193bd866734b6fea1bf96b5d975c52f09cbec2e. --- checkstyle.xml | 4 +- setup/default.xml | 6 -- src/org/traccar/Context.java | 21 ----- src/org/traccar/Main.java | 6 -- src/org/traccar/flespi/ChannelPullTask.java | 15 ---- src/org/traccar/flespi/FlespiClient.java | 128 ---------------------------- 6 files changed, 1 insertion(+), 179 deletions(-) delete mode 100644 src/org/traccar/flespi/ChannelPullTask.java delete mode 100644 src/org/traccar/flespi/FlespiClient.java (limited to 'setup') diff --git a/checkstyle.xml b/checkstyle.xml index dc038f551..9d0314b06 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -67,9 +67,7 @@ - - - + diff --git a/setup/default.xml b/setup/default.xml index 0a7b421d7..95b69e216 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -218,10 +218,4 @@ 5147 5148 - - true - https://flespi.io - - - diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index e582c5256..3b24c6460 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -21,9 +21,6 @@ import com.ning.http.client.AsyncHttpClient; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.Properties; import org.apache.velocity.app.VelocityEngine; @@ -46,7 +43,6 @@ import org.traccar.database.StatisticsManager; import org.traccar.database.UsersManager; import org.traccar.events.MotionEventHandler; import org.traccar.events.OverspeedEventHandler; -import org.traccar.flespi.FlespiClient; import org.traccar.geocoder.BingMapsGeocoder; import org.traccar.geocoder.FactualGeocoder; import org.traccar.geocoder.GeocodeFarmGeocoder; @@ -267,12 +263,6 @@ public final class Context { config.getDouble("event.motion.speedThreshold", 0.01)); } - private final static List flespiClients = new ArrayList<>(); - - public static List getFlespiClients() { - return flespiClients; - } - public static void init(String[] arguments) throws Exception { config = new Config(); @@ -421,17 +411,6 @@ public final class Context { smppClient = new SmppClient(); } - if (config.getBoolean("flespi.enable")) { - String uri = config.getString("flespi.url"); - String token = config.getString("flespi.token"); - String channelIds = config.getString("flespi.channel.ids"); - List ids = Arrays.asList(channelIds.split(",")); - if (uri != null && token != null) { - for (String channelId : ids) { - flespiClients.add(new FlespiClient(uri, token, channelId)); - } - } - } } public static void init(IdentityManager testIdentityManager) { diff --git a/src/org/traccar/Main.java b/src/org/traccar/Main.java index 0d7c2ecf0..1e2db2693 100644 --- a/src/org/traccar/Main.java +++ b/src/org/traccar/Main.java @@ -15,11 +15,9 @@ */ package org.traccar; -import org.traccar.flespi.FlespiClient; import org.traccar.helper.Log; import java.sql.SQLException; -import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.Locale; @@ -58,10 +56,6 @@ public final class Main { public void run() { Log.info("Shutting down server..."); - List flespiClients = Context.getFlespiClients(); - for (FlespiClient flespiClient : flespiClients) { - flespiClient.stopPullTask(); - } if (Context.getWebServer() != null) { Context.getWebServer().stop(); } diff --git a/src/org/traccar/flespi/ChannelPullTask.java b/src/org/traccar/flespi/ChannelPullTask.java deleted file mode 100644 index 5e5525ec9..000000000 --- a/src/org/traccar/flespi/ChannelPullTask.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.traccar.flespi; - -public class ChannelPullTask implements Runnable { - - private final FlespiClient flespiClient; - - protected ChannelPullTask(FlespiClient flespiClient) { - this.flespiClient = flespiClient; - } - - @Override - public void run() { - flespiClient.channelPull(); - } -} diff --git a/src/org/traccar/flespi/FlespiClient.java b/src/org/traccar/flespi/FlespiClient.java deleted file mode 100644 index 2c98f36b3..000000000 --- a/src/org/traccar/flespi/FlespiClient.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.traccar.flespi; - - -import com.ning.http.client.AsyncCompletionHandler; -import com.ning.http.client.Response; -import org.traccar.Context; -import org.traccar.helper.Log; -import org.traccar.model.Device; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonNumber; -import javax.json.JsonReader; -import javax.json.JsonArray; -import java.util.Date; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -public class FlespiClient { - private final String url; - private final String token; - private final String channel_id; - private final ScheduledExecutorService pullChannelExecutor = Executors.newScheduledThreadPool(5); - private ScheduledFuture pullTask; - private Integer pullDelay = 5; - private int nextKey; - - public FlespiClient(String url, String token, String channelId) { - this.channel_id = channelId; - this.url = url + "/gw/channels/" + channelId + "/messages?data={\"limit_count\":1000000," - + "\"limit_size\":100000000,\"delete\":true,\"timeout\":25,\"curr_key\":%d}"; - this.token = "FlespiToken " + token; - - schedulePull(); - } - - private void schedulePull() { - pullTask = pullChannelExecutor.scheduleAtFixedRate(new ChannelPullTask(this), 1, pullDelay, TimeUnit.SECONDS); - } - - public void stopPullTask() { - if (pullTask != null) { - pullTask.cancel(false); - } - } - - protected synchronized void channelPull() { - Context.getAsyncHttpClient().prepareGet(String.format(this.url, nextKey)) - .addHeader("Authorization", this.token) - .execute(new AsyncCompletionHandler() { - @Override - public Object onCompleted(Response response) throws Exception { - try (JsonReader reader = Json.createReader(response.getResponseBodyAsStream())) { - JsonObject object = reader.readObject(); - JsonArray result = object.getJsonArray("result"); - nextKey = object.getInt("next_key", nextKey); - Log.debug(String.format("channelPull next_key=%d msgs_count=%d", nextKey, result.size())); - for (int i = 0; i < result.size(); i++) { - Position position = decodePosition(result.getJsonObject(i)); - if (position != null && position.getLatitude() != 0 && position.getLongitude() != 0) { - Context.getConnectionManager().updateDevice(position.getDeviceId(), - Device.STATUS_ONLINE, new Date()); - Context.getDeviceManager().updateLatestPosition(position); - } - } - JsonArray errors = object.getJsonArray("errors"); - if (errors != null) { - for (int i = 0; i < errors.size(); i++) { - JsonObject error = errors.getJsonObject(i); - Log.warning("Error in flespi channel: " + error.toString()); - } - if (result == null || result.size() == 0) { - stopPullTask(); - } - } - } - return null; - } - - @Override - public void onThrowable(Throwable t) { - t.printStackTrace(); - } - }); - } - - private Position decodePosition(JsonObject msg) { - Device device = null; - try { - device = Context.getIdentityManager().getByUniqueId(msg.getString("ident")); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - if (device == null) { - return null; - } - Position position = new Position(); - position.setDeviceId(device.getId()); - - - position.setProtocol("flespi"); - - position.setTime(new Date((long) msg.getJsonNumber("timestamp").doubleValue() * 1000)); - JsonNumber lat = msg.getJsonNumber("position.latitude"); - JsonNumber lon = msg.getJsonNumber("position.longitude"); - position.setLatitude((lat != null && lon != null) ? lat.doubleValue() : 0); - position.setLongitude((lat != null && lon != null) ? lon.doubleValue() : 0); - - JsonNumber speed = msg.getJsonNumber("position.speed"); - position.setSpeed(speed != null ? speed.doubleValue() : 0); - - JsonNumber course = msg.getJsonNumber("position.direction"); - position.setCourse(course != null ? course.doubleValue() : 0); - - JsonNumber altitude = msg.getJsonNumber("position.altitude"); - position.setAltitude(altitude != null ? altitude.doubleValue() : 0); - - int satellites = msg.getInt("position.satellites", 0); - position.setValid(lat != null && lon != null && satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - - return position; - } -} -- cgit v1.2.3 From fb82a8167b99f706cb25d828bf1d72424ba98a75 Mon Sep 17 00:00:00 2001 From: namo Date: Thu, 19 Oct 2017 18:00:30 +0300 Subject: flespi integration: listening messages --- setup/default.xml | 1 + src/org/traccar/BaseProtocolDecoder.java | 9 ++ src/org/traccar/ExtendedObjectDecoder.java | 13 +++ src/org/traccar/protocol/FlespiProtocol.java | 49 +++++++++ .../traccar/protocol/FlespiProtocolDecoder.java | 121 +++++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 src/org/traccar/protocol/FlespiProtocol.java create mode 100644 src/org/traccar/protocol/FlespiProtocolDecoder.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 95b69e216..79455d846 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -217,5 +217,6 @@ 5146 5147 5148 + 5149 diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index 2d6286bf8..b0fb72225 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -29,6 +29,8 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import java.util.Iterator; import java.sql.SQLException; public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { @@ -205,6 +207,13 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { if (!positions.isEmpty()) { position = (Position) positions.iterator().next(); } + } else if (decodedMessage instanceof Map) { + Set deviceIds = ((HashMap) decodedMessage).keySet(); + Iterator deviceIdsIterator = deviceIds.iterator(); + while (deviceIdsIterator.hasNext()) { + Context.getConnectionManager().updateDevice( + deviceIdsIterator.next(), Device.STATUS_ONLINE, new Date()); + } } } if (position != null) { diff --git a/src/org/traccar/ExtendedObjectDecoder.java b/src/org/traccar/ExtendedObjectDecoder.java index 268e6f688..a9b3a1053 100644 --- a/src/org/traccar/ExtendedObjectDecoder.java +++ b/src/org/traccar/ExtendedObjectDecoder.java @@ -29,6 +29,9 @@ import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { @@ -69,6 +72,16 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { saveOriginal(o, originalMessage); Channels.fireMessageReceived(ctx, o, e.getRemoteAddress()); } + } else if (decodedMessage instanceof Map) { + Iterator it = ((Map) decodedMessage).entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + List positions = (List) pair.getValue(); + for (Position position : positions) { + saveOriginal(position, originalMessage); + Channels.fireMessageReceived(ctx, position, e.getRemoteAddress()); + } + } } else { saveOriginal(decodedMessage, originalMessage); Channels.fireMessageReceived(ctx, decodedMessage, e.getRemoteAddress()); diff --git a/src/org/traccar/protocol/FlespiProtocol.java b/src/org/traccar/protocol/FlespiProtocol.java new file mode 100644 index 000000000..1164dac2d --- /dev/null +++ b/src/org/traccar/protocol/FlespiProtocol.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 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. + * 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.http.HttpChunkAggregator; +import org.jboss.netty.handler.codec.http.HttpRequestDecoder; +import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; +import org.traccar.model.Command; + +import java.util.List; + +public class FlespiProtocol extends BaseProtocol { + + public FlespiProtocol() { + super("flespi"); + setSupportedDataCommands( + Command.TYPE_CUSTOM); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpChunkAggregator(Integer.MAX_VALUE)); + pipeline.addLast("objectDecoder", new FlespiProtocolDecoder(FlespiProtocol.this)); + } + }); + } +} diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java new file mode 100644 index 000000000..6d5d68382 --- /dev/null +++ b/src/org/traccar/protocol/FlespiProtocolDecoder.java @@ -0,0 +1,121 @@ +/* + * Copyright 2013 - 2017 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. + * 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.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.handler.codec.http.DefaultHttpResponse; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponse; +import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import org.jboss.netty.handler.codec.http.HttpVersion; +import org.jboss.netty.handler.codec.http.HttpHeaders; +import org.jboss.netty.util.CharsetUtil; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.Log; +import org.traccar.model.Position; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonNumber; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; +import java.util.Date; + +public class FlespiProtocolDecoder extends BaseProtocolDecoder { + + public FlespiProtocolDecoder(FlespiProtocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + HttpRequest request = (HttpRequest) msg; + JsonArray result = Json.createReader(new StringReader(request.getContent().toString(StandardCharsets.UTF_8))) + .readArray(); + Map unitsPositions = new HashMap<>(); + Log.debug(String.format("messages received msgs_count=%d", result.size())); + for (int i = 0; i < result.size(); i++) { + JsonObject message = result.getJsonObject(i); + String ident = message.getString("ident"); + if (ident == null) { + continue; + } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident); + if (deviceSession == null) { + continue; + } + if (unitsPositions.get(deviceSession.getDeviceId()) == null) { + unitsPositions.put(deviceSession.getDeviceId(), new LinkedList()); + } + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + decodePosition(message, position); + unitsPositions.get(deviceSession.getDeviceId()).add(position); + } + + sendResponse(channel, HttpResponseStatus.OK); + return unitsPositions; + } + + private void sendResponse(Channel channel, HttpResponseStatus status) { + if (channel != null) { + HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); + response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 10); + response.setContent(ChannelBuffers.copiedBuffer("Hello namo", CharsetUtil.US_ASCII)); + channel.write(response); + } + } + + private void decodePosition(JsonObject msg, Position position) { + position.setProtocol("flespi"); + + position.setTime(new Date((long) msg.getJsonNumber("timestamp").doubleValue() * 1000)); + JsonNumber lat = msg.getJsonNumber("position.latitude"); + JsonNumber lon = msg.getJsonNumber("position.longitude"); + position.setLatitude((lat != null && lon != null) ? lat.doubleValue() : 0); + position.setLongitude((lat != null && lon != null) ? lon.doubleValue() : 0); + + JsonNumber speed = msg.getJsonNumber("position.speed"); + position.setSpeed(speed != null ? speed.doubleValue() : 0); + if (position.getSpeed() == 111) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + + JsonNumber course = msg.getJsonNumber("position.direction"); + position.setCourse(course != null ? course.doubleValue() : 0); + + JsonNumber altitude = msg.getJsonNumber("position.altitude"); + position.setAltitude(altitude != null ? altitude.doubleValue() : 0); + + int satellites = msg.getInt("position.satellites", 0); + position.setValid(position.getLatitude() != 0 && position.getLongitude() != 0 && satellites >= 3); + position.set(Position.KEY_SATELLITES, satellites); + + if (msg.getBoolean("alarm.event.trigger", false)) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + } +} -- cgit v1.2.3 From 8483681361a386d0159422ed089ed3360161811c Mon Sep 17 00:00:00 2001 From: namo Date: Fri, 20 Oct 2017 09:30:36 +0300 Subject: Revert "flespi integration: listening messages" This reverts commit fb82a8167b99f706cb25d828bf1d72424ba98a75. --- setup/default.xml | 1 - src/org/traccar/BaseProtocolDecoder.java | 9 -- src/org/traccar/ExtendedObjectDecoder.java | 13 --- src/org/traccar/protocol/FlespiProtocol.java | 49 --------- .../traccar/protocol/FlespiProtocolDecoder.java | 121 --------------------- 5 files changed, 193 deletions(-) delete mode 100644 src/org/traccar/protocol/FlespiProtocol.java delete mode 100644 src/org/traccar/protocol/FlespiProtocolDecoder.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 79455d846..95b69e216 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -217,6 +217,5 @@ 5146 5147 5148 - 5149 diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index b0fb72225..2d6286bf8 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -29,8 +29,6 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.Set; -import java.util.Iterator; import java.sql.SQLException; public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { @@ -207,13 +205,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { if (!positions.isEmpty()) { position = (Position) positions.iterator().next(); } - } else if (decodedMessage instanceof Map) { - Set deviceIds = ((HashMap) decodedMessage).keySet(); - Iterator deviceIdsIterator = deviceIds.iterator(); - while (deviceIdsIterator.hasNext()) { - Context.getConnectionManager().updateDevice( - deviceIdsIterator.next(), Device.STATUS_ONLINE, new Date()); - } } } if (position != null) { diff --git a/src/org/traccar/ExtendedObjectDecoder.java b/src/org/traccar/ExtendedObjectDecoder.java index a9b3a1053..268e6f688 100644 --- a/src/org/traccar/ExtendedObjectDecoder.java +++ b/src/org/traccar/ExtendedObjectDecoder.java @@ -29,9 +29,6 @@ import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { @@ -72,16 +69,6 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { saveOriginal(o, originalMessage); Channels.fireMessageReceived(ctx, o, e.getRemoteAddress()); } - } else if (decodedMessage instanceof Map) { - Iterator it = ((Map) decodedMessage).entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = (Map.Entry) it.next(); - List positions = (List) pair.getValue(); - for (Position position : positions) { - saveOriginal(position, originalMessage); - Channels.fireMessageReceived(ctx, position, e.getRemoteAddress()); - } - } } else { saveOriginal(decodedMessage, originalMessage); Channels.fireMessageReceived(ctx, decodedMessage, e.getRemoteAddress()); diff --git a/src/org/traccar/protocol/FlespiProtocol.java b/src/org/traccar/protocol/FlespiProtocol.java deleted file mode 100644 index 1164dac2d..000000000 --- a/src/org/traccar/protocol/FlespiProtocol.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2015 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. - * 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.http.HttpChunkAggregator; -import org.jboss.netty.handler.codec.http.HttpRequestDecoder; -import org.jboss.netty.handler.codec.http.HttpResponseEncoder; -import org.traccar.BaseProtocol; -import org.traccar.TrackerServer; -import org.traccar.model.Command; - -import java.util.List; - -public class FlespiProtocol extends BaseProtocol { - - public FlespiProtocol() { - super("flespi"); - setSupportedDataCommands( - Command.TYPE_CUSTOM); - } - - @Override - public void initTrackerServers(List serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { - @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("httpEncoder", new HttpResponseEncoder()); - pipeline.addLast("httpDecoder", new HttpRequestDecoder()); - pipeline.addLast("httpAggregator", new HttpChunkAggregator(Integer.MAX_VALUE)); - pipeline.addLast("objectDecoder", new FlespiProtocolDecoder(FlespiProtocol.this)); - } - }); - } -} diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java deleted file mode 100644 index 6d5d68382..000000000 --- a/src/org/traccar/protocol/FlespiProtocolDecoder.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2013 - 2017 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. - * 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.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.handler.codec.http.DefaultHttpResponse; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpResponse; -import org.jboss.netty.handler.codec.http.HttpResponseStatus; -import org.jboss.netty.handler.codec.http.HttpVersion; -import org.jboss.netty.handler.codec.http.HttpHeaders; -import org.jboss.netty.util.CharsetUtil; -import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; -import org.traccar.helper.Log; -import org.traccar.model.Position; - -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonNumber; -import javax.json.JsonObject; -import java.io.StringReader; -import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.LinkedList; -import java.util.Map; -import java.util.Date; - -public class FlespiProtocolDecoder extends BaseProtocolDecoder { - - public FlespiProtocolDecoder(FlespiProtocol protocol) { - super(protocol); - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - HttpRequest request = (HttpRequest) msg; - JsonArray result = Json.createReader(new StringReader(request.getContent().toString(StandardCharsets.UTF_8))) - .readArray(); - Map unitsPositions = new HashMap<>(); - Log.debug(String.format("messages received msgs_count=%d", result.size())); - for (int i = 0; i < result.size(); i++) { - JsonObject message = result.getJsonObject(i); - String ident = message.getString("ident"); - if (ident == null) { - continue; - } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident); - if (deviceSession == null) { - continue; - } - if (unitsPositions.get(deviceSession.getDeviceId()) == null) { - unitsPositions.put(deviceSession.getDeviceId(), new LinkedList()); - } - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - decodePosition(message, position); - unitsPositions.get(deviceSession.getDeviceId()).add(position); - } - - sendResponse(channel, HttpResponseStatus.OK); - return unitsPositions; - } - - private void sendResponse(Channel channel, HttpResponseStatus status) { - if (channel != null) { - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); - response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 10); - response.setContent(ChannelBuffers.copiedBuffer("Hello namo", CharsetUtil.US_ASCII)); - channel.write(response); - } - } - - private void decodePosition(JsonObject msg, Position position) { - position.setProtocol("flespi"); - - position.setTime(new Date((long) msg.getJsonNumber("timestamp").doubleValue() * 1000)); - JsonNumber lat = msg.getJsonNumber("position.latitude"); - JsonNumber lon = msg.getJsonNumber("position.longitude"); - position.setLatitude((lat != null && lon != null) ? lat.doubleValue() : 0); - position.setLongitude((lat != null && lon != null) ? lon.doubleValue() : 0); - - JsonNumber speed = msg.getJsonNumber("position.speed"); - position.setSpeed(speed != null ? speed.doubleValue() : 0); - if (position.getSpeed() == 111) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - - JsonNumber course = msg.getJsonNumber("position.direction"); - position.setCourse(course != null ? course.doubleValue() : 0); - - JsonNumber altitude = msg.getJsonNumber("position.altitude"); - position.setAltitude(altitude != null ? altitude.doubleValue() : 0); - - int satellites = msg.getInt("position.satellites", 0); - position.setValid(position.getLatitude() != 0 && position.getLongitude() != 0 && satellites >= 3); - position.set(Position.KEY_SATELLITES, satellites); - - if (msg.getBoolean("alarm.event.trigger", false)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - } -} -- cgit v1.2.3 From 563776604e5acfcde8f83ab779406caa8a069ef4 Mon Sep 17 00:00:00 2001 From: namo Date: Fri, 20 Oct 2017 09:42:01 +0300 Subject: flespi integration: listening messages (rev.2) --- setup/default.xml | 1 + src/org/traccar/protocol/FlespiProtocol.java | 46 ++++++++ .../traccar/protocol/FlespiProtocolDecoder.java | 116 +++++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 src/org/traccar/protocol/FlespiProtocol.java create mode 100644 src/org/traccar/protocol/FlespiProtocolDecoder.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 95b69e216..79455d846 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -217,5 +217,6 @@ 5146 5147 5148 + 5149 diff --git a/src/org/traccar/protocol/FlespiProtocol.java b/src/org/traccar/protocol/FlespiProtocol.java new file mode 100644 index 000000000..285fcd9f1 --- /dev/null +++ b/src/org/traccar/protocol/FlespiProtocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 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. + * 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.http.HttpChunkAggregator; +import org.jboss.netty.handler.codec.http.HttpRequestDecoder; +import org.jboss.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class FlespiProtocol extends BaseProtocol { + + public FlespiProtocol() { + super("flespi"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); + pipeline.addLast("httpAggregator", new HttpChunkAggregator(Integer.MAX_VALUE)); + pipeline.addLast("objectDecoder", new FlespiProtocolDecoder(FlespiProtocol.this)); + } + }); + } +} diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java new file mode 100644 index 000000000..a98529b19 --- /dev/null +++ b/src/org/traccar/protocol/FlespiProtocolDecoder.java @@ -0,0 +1,116 @@ +/* + * Copyright 2013 - 2017 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. + * 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.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.handler.codec.http.DefaultHttpResponse; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponse; +import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import org.jboss.netty.handler.codec.http.HttpVersion; +import org.jboss.netty.handler.codec.http.HttpHeaders; +import org.jboss.netty.util.CharsetUtil; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.Log; +import org.traccar.model.Position; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonNumber; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.LinkedList; +import java.util.Date; + +public class FlespiProtocolDecoder extends BaseProtocolDecoder { + + public FlespiProtocolDecoder(FlespiProtocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + HttpRequest request = (HttpRequest) msg; + JsonArray result = Json.createReader(new StringReader(request.getContent().toString(StandardCharsets.UTF_8))) + .readArray(); + List positions = new LinkedList<>(); + Log.debug(String.format("messages received msgs_count=%d", result.size())); + for (int i = 0; i < result.size(); i++) { + JsonObject message = result.getJsonObject(i); + String ident = message.getString("ident"); + if (ident == null) { + continue; + } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident); + if (deviceSession == null) { + continue; + } + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + decodePosition(message, position); + positions.add(position); + } + + sendResponse(channel, HttpResponseStatus.OK); + return positions; + } + + private void sendResponse(Channel channel, HttpResponseStatus status) { + if (channel != null) { + HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); + response.headers().add(HttpHeaders.Names.CONTENT_LENGTH, 10); + response.setContent(ChannelBuffers.copiedBuffer("Hello namo", CharsetUtil.US_ASCII)); + channel.write(response); + } + } + + private void decodePosition(JsonObject msg, Position position) { + position.setProtocol("flespi"); + + position.setTime(new Date((long) msg.getJsonNumber("timestamp").doubleValue() * 1000)); + JsonNumber lat = msg.getJsonNumber("position.latitude"); + JsonNumber lon = msg.getJsonNumber("position.longitude"); + position.setLatitude((lat != null && lon != null) ? lat.doubleValue() : 0); + position.setLongitude((lat != null && lon != null) ? lon.doubleValue() : 0); + + JsonNumber speed = msg.getJsonNumber("position.speed"); + position.setSpeed(speed != null ? speed.doubleValue() : 0); + if (position.getSpeed() == 111) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + + JsonNumber course = msg.getJsonNumber("position.direction"); + position.setCourse(course != null ? course.doubleValue() : 0); + + JsonNumber altitude = msg.getJsonNumber("position.altitude"); + position.setAltitude(altitude != null ? altitude.doubleValue() : 0); + + int satellites = msg.getInt("position.satellites", 0); + position.setValid(position.getLatitude() != 0 && position.getLongitude() != 0 && satellites >= 3); + position.set(Position.KEY_SATELLITES, satellites); + + if (msg.getBoolean("alarm.event.trigger", false)) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + } +} -- cgit v1.2.3 From fa9d7dbce38370a82d59494dec698b2177a45ec2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 25 Oct 2017 22:03:19 +1300 Subject: Implement D-WAY protocol --- setup/default.xml | 1 + src/org/traccar/protocol/DwayProtocol.java | 47 +++++++++ src/org/traccar/protocol/DwayProtocolDecoder.java | 109 +++++++++++++++++++++ .../traccar/protocol/DwayProtocolDecoderTest.java | 21 ++++ 4 files changed, 178 insertions(+) create mode 100644 src/org/traccar/protocol/DwayProtocol.java create mode 100644 src/org/traccar/protocol/DwayProtocolDecoder.java create mode 100644 test/org/traccar/protocol/DwayProtocolDecoderTest.java (limited to 'setup') diff --git a/setup/default.xml b/setup/default.xml index 79455d846..d966cf91c 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -218,5 +218,6 @@ 5147 5148 5149 + 5150 diff --git a/src/org/traccar/protocol/DwayProtocol.java b/src/org/traccar/protocol/DwayProtocol.java new file mode 100644 index 000000000..151d3fe01 --- /dev/null +++ b/src/org/traccar/protocol/DwayProtocol.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017 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. + * 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.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class DwayProtocol extends BaseProtocol { + + public DwayProtocol() { + super("dway"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new DwayProtocolDecoder(DwayProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/DwayProtocolDecoder.java b/src/org/traccar/protocol/DwayProtocolDecoder.java new file mode 100644 index 000000000..993aa91b2 --- /dev/null +++ b/src/org/traccar/protocol/DwayProtocolDecoder.java @@ -0,0 +1,109 @@ +/* + * Copyright 2017 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. + * 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.DeviceSession; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class DwayProtocolDecoder extends BaseProtocolDecoder { + + public DwayProtocolDecoder(DwayProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("AA55,") + .number("d+,") // index + .number("(d+),") // imei + .number("d+,") // type + .number("(dd)(dd)(dd),") // date (yymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(-?d+.d+),") // latitude + .number("(-?d+.d+),") // longitude + .number("(-?d+),") // altitude + .number("(d+.d+),") // speed + .number("(d+),") // course + .number("([01]{4}),") // input + .number("([01]{4}),") // output + .number("([01])([01])([01])([01]),") // flags + .number("(d+),") // battery + .number("(d+),") // adc1 + .number("(d+),") // adc2 + .number("(d+)") // driver + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + if (sentence.startsWith(">H")) { + if (channel != null) { + channel.write(">ALIVE\r\n"); + } + return null; + } + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime()); + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setAltitude(parser.nextDouble(0)); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setCourse(parser.nextDouble(0)); + + position.set(Position.KEY_INPUT, parser.nextBinInt()); + position.set(Position.KEY_OUTPUT, parser.nextBinInt()); + + position.setValid(parser.next().equals("1")); + + position.set(Position.KEY_IGNITION, parser.next().equals("1")); + position.set(Position.KEY_CHARGE, parser.next().equals("1")); + + if (parser.next().equals("1")) { + position.set(Position.KEY_ALARM, Position.ALARM_SHOCK); + } + + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); + position.set(Position.PREFIX_ADC + 1, parser.nextInt() * 0.001); + position.set(Position.PREFIX_ADC + 2, parser.nextInt() * 0.001); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + + return position; + } + +} diff --git a/test/org/traccar/protocol/DwayProtocolDecoderTest.java b/test/org/traccar/protocol/DwayProtocolDecoderTest.java new file mode 100644 index 000000000..33a943b29 --- /dev/null +++ b/test/org/traccar/protocol/DwayProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class DwayProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + DwayProtocolDecoder decoder = new DwayProtocolDecoder(new DwayProtocol()); + + verifyPosition(decoder, text( + "AA55,1,123456,1,140101,101132,22.5500,113.6770,75,70.5,320,1100,0011,1110,3950,33000,24000,12345678")); + + verifyNull(decoder, text( + ">H12345678")); + + } + +} -- cgit v1.2.3