From db6e8564001a31cf7c4954cc422a1422fcd3c14a Mon Sep 17 00:00:00 2001 From: drecchia Date: Tue, 12 Jul 2016 18:36:42 -0300 Subject: - Added support for activate output1, reboot device and request position. --- src/org/traccar/protocol/SuntechProtocolEncoder.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index d988f97be..2f66d8d0c 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2016 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. @@ -25,6 +25,12 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { protected Object encodeCommand(Command command) { switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, "SA200CMD;{%s};02;Reboot\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL: + return formatCommand(command, "SA200CMD;{%s};0{%s};Enable1\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA); case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: -- cgit v1.2.3 From 8ed94697f46788d56d71551940b2f4f4778bb9de Mon Sep 17 00:00:00 2001 From: drecchia Date: Tue, 12 Jul 2016 18:42:01 -0300 Subject: - Added new commands. --- src/org/traccar/protocol/SuntechProtocol.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java index ce0e73280..35d72673c 100644 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ b/src/org/traccar/protocol/SuntechProtocol.java @@ -31,6 +31,9 @@ public class SuntechProtocol extends BaseProtocol { public SuntechProtocol() { super("suntech"); setSupportedCommands( + Command.TYPE_OUTPUT_CONTROL, + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } -- cgit v1.2.3 From 9c20d2d85c9909b41711e7fe198539dc8cd7d485 Mon Sep 17 00:00:00 2001 From: drecchia Date: Tue, 12 Jul 2016 18:50:31 -0300 Subject: - Fix typpo. --- src/org/traccar/protocol/SuntechProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index 2f66d8d0c..e63637584 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -30,7 +30,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "SA200CMD;{%s};0{%s};Enable1\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA); case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: -- cgit v1.2.3 From fee6c4709866248e26f63db2fd265deac7edde99 Mon Sep 17 00:00:00 2001 From: drecchia Date: Tue, 12 Jul 2016 18:57:44 -0300 Subject: - Fix number of params. --- src/org/traccar/protocol/SuntechProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index e63637584..86c07c7d2 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -30,7 +30,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA, Command.KEY_DATA); case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: -- cgit v1.2.3 From 80bbc136baf6a91b967732fdae4238f827b9bf19 Mon Sep 17 00:00:00 2001 From: drecchia Date: Wed, 13 Jul 2016 10:41:29 -0300 Subject: - Fixed pull request issues --- src/org/traccar/protocol/SuntechProtocol.java | 2 +- src/org/traccar/protocol/SuntechProtocolEncoder.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java index 35d72673c..a604a07fd 100644 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ b/src/org/traccar/protocol/SuntechProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015-2016 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. diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index 86c07c7d2..aaf4ac50e 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015-2016 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. @@ -30,7 +30,8 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA, Command.KEY_DATA); + return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", + Command.KEY_UNIQUE_ID, Command.KEY_DATA, Command.KEY_DATA); case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: -- cgit v1.2.3 From e1c811133ba207d2233ac7f9ef531102a91eb4eb Mon Sep 17 00:00:00 2001 From: drecchia Date: Wed, 13 Jul 2016 10:43:22 -0300 Subject: - Removed trailing space. --- src/org/traccar/protocol/SuntechProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index aaf4ac50e..c41cc7ef9 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -30,7 +30,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", + return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_DATA, Command.KEY_DATA); case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); -- cgit v1.2.3 From e910d9337a35fad663c978ff9121ed64ca28af91 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 14 Jul 2016 15:21:43 +0500 Subject: - Fixed saving parent group when creating new group. - Fixed storing device and group if parent group is not defined. - Fixed Warning in browser console about missed requirements. --- debug.xml | 2 +- setup/unix/traccar.xml | 2 +- setup/windows/traccar.xml | 2 +- src/org/traccar/database/QueryBuilder.java | 6 +++++- web/app/view/GroupsController.js | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/debug.xml b/debug.xml index 73ddacc6a..09a575450 100644 --- a/debug.xml +++ b/debug.xml @@ -187,7 +187,7 @@ - INSERT INTO groups (name) VALUES (:name); + INSERT INTO groups (name, groupId) VALUES (:name, :groupId); diff --git a/setup/unix/traccar.xml b/setup/unix/traccar.xml index 83abb48fd..a8bf9c334 100644 --- a/setup/unix/traccar.xml +++ b/setup/unix/traccar.xml @@ -139,7 +139,7 @@ - INSERT INTO groups (name) VALUES (:name); + INSERT INTO groups (name, groupId) VALUES (:name, :groupId); diff --git a/setup/windows/traccar.xml b/setup/windows/traccar.xml index 72f04d0a0..a67d8c53c 100644 --- a/setup/windows/traccar.xml +++ b/setup/windows/traccar.xml @@ -139,7 +139,7 @@ - INSERT INTO groups (name) VALUES (:name); + INSERT INTO groups (name, groupId) VALUES (:name, :groupId); diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java index 73569ac2a..477434fb5 100644 --- a/src/org/traccar/database/QueryBuilder.java +++ b/src/org/traccar/database/QueryBuilder.java @@ -175,7 +175,11 @@ public final class QueryBuilder { public QueryBuilder setLong(String name, long value) throws SQLException { for (int i : indexes(name)) { try { - statement.setLong(i, value); + if (value == 0) { + statement.setNull(i, Types.INTEGER); + } else { + statement.setLong(i, value); + } } catch (SQLException error) { statement.close(); connection.close(); diff --git a/web/app/view/GroupsController.js b/web/app/view/GroupsController.js index 1764423d7..4cf1459a6 100644 --- a/web/app/view/GroupsController.js +++ b/web/app/view/GroupsController.js @@ -19,6 +19,7 @@ Ext.define('Traccar.view.GroupsController', { alias: 'controller.groups', requires: [ + 'Traccar.view.GroupDialog', 'Traccar.view.GroupGeofences' ], -- cgit v1.2.3 From 2a13bcccc26cf673bd9cd6be045099018f2f4d55 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 14 Jul 2016 15:49:05 +0500 Subject: Indentation --- src/org/traccar/database/QueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java index 477434fb5..b91218a13 100644 --- a/src/org/traccar/database/QueryBuilder.java +++ b/src/org/traccar/database/QueryBuilder.java @@ -178,7 +178,7 @@ public final class QueryBuilder { if (value == 0) { statement.setNull(i, Types.INTEGER); } else { - statement.setLong(i, value); + statement.setLong(i, value); } } catch (SQLException error) { statement.close(); -- cgit v1.2.3 From add55d83f367c0001deadadac4b83cc6542eb234 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 14 Jul 2016 16:50:28 +0500 Subject: Set long as NULL only for *Id fields --- src/org/traccar/database/QueryBuilder.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java index b91218a13..7d8731933 100644 --- a/src/org/traccar/database/QueryBuilder.java +++ b/src/org/traccar/database/QueryBuilder.java @@ -175,7 +175,20 @@ public final class QueryBuilder { public QueryBuilder setLong(String name, long value) throws SQLException { for (int i : indexes(name)) { try { - if (value == 0) { + statement.setLong(i, value); + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setLong(String name, long value, boolean nullIfZero) throws SQLException { + for (int i : indexes(name)) { + try { + if (value == 0 && nullIfZero) { statement.setNull(i, Types.INTEGER); } else { statement.setLong(i, value); @@ -249,7 +262,11 @@ public final class QueryBuilder { } else if (method.getReturnType().equals(int.class)) { setInteger(name, (Integer) method.invoke(object)); } else if (method.getReturnType().equals(long.class)) { - setLong(name, (Long) method.invoke(object)); + if (name.endsWith("Id")) { + setLong(name, (Long) method.invoke(object), true); + } else { + setLong(name, (Long) method.invoke(object)); + } } else if (method.getReturnType().equals(double.class)) { setDouble(name, (Double) method.invoke(object)); } else if (method.getReturnType().equals(String.class)) { -- cgit v1.2.3 From a8c7b44d06fd6112568c6ad0ed57c5af9db00ded Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 14 Jul 2016 17:53:54 +0500 Subject: Remove duplicating code --- src/org/traccar/database/QueryBuilder.java | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java index 7d8731933..1a83daab9 100644 --- a/src/org/traccar/database/QueryBuilder.java +++ b/src/org/traccar/database/QueryBuilder.java @@ -173,16 +173,7 @@ public final class QueryBuilder { } public QueryBuilder setLong(String name, long value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setLong(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; + return setLong(name, value, false); } public QueryBuilder setLong(String name, long value, boolean nullIfZero) throws SQLException { @@ -262,11 +253,7 @@ public final class QueryBuilder { } else if (method.getReturnType().equals(int.class)) { setInteger(name, (Integer) method.invoke(object)); } else if (method.getReturnType().equals(long.class)) { - if (name.endsWith("Id")) { - setLong(name, (Long) method.invoke(object), true); - } else { - setLong(name, (Long) method.invoke(object)); - } + setLong(name, (Long) method.invoke(object), name.endsWith("Id")); } else if (method.getReturnType().equals(double.class)) { setDouble(name, (Double) method.invoke(object)); } else if (method.getReturnType().equals(String.class)) { -- cgit v1.2.3 From 901c483ac358e5dc38f2014287e5018e79aa7b08 Mon Sep 17 00:00:00 2001 From: drecchia Date: Thu, 14 Jul 2016 13:34:36 -0300 Subject: - Fixed style --- src/org/traccar/protocol/SuntechProtocol.java | 2 +- src/org/traccar/protocol/SuntechProtocolEncoder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java index a604a07fd..4a40e1bfc 100644 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ b/src/org/traccar/protocol/SuntechProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 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. diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index c41cc7ef9..708b24e79 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 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. -- cgit v1.2.3 From d71210f1f408c757d4fe3da07829bbc3362a7e93 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 15 Jul 2016 15:33:08 +0500 Subject: Move code related to devices to DeviceManager --- src/org/traccar/BaseProtocolDecoder.java | 6 +- src/org/traccar/Context.java | 17 +- src/org/traccar/DefaultDataHandler.java | 5 +- src/org/traccar/DistanceHandler.java | 4 +- src/org/traccar/FilterHandler.java | 4 +- src/org/traccar/MainEventHandler.java | 7 +- src/org/traccar/api/AsyncSocket.java | 2 +- src/org/traccar/api/resource/DeviceResource.java | 10 +- src/org/traccar/api/resource/PositionResource.java | 2 +- src/org/traccar/database/ConnectionManager.java | 72 ++---- src/org/traccar/database/DataManager.java | 133 +---------- src/org/traccar/database/DeviceManager.java | 261 +++++++++++++++++++++ src/org/traccar/database/GeofenceManager.java | 4 +- src/org/traccar/database/IdentityManager.java | 3 + src/org/traccar/database/PermissionsManager.java | 2 +- src/org/traccar/events/GeofenceEventHandler.java | 2 +- src/org/traccar/events/MotionEventHandler.java | 23 +- src/org/traccar/events/OverspeedEventHandler.java | 2 +- test/org/traccar/ProtocolTest.java | 5 + 19 files changed, 342 insertions(+), 222 deletions(-) create mode 100644 src/org/traccar/database/DeviceManager.java (limited to 'src') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index 3429f41f0..9a253e351 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -47,7 +47,9 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { Device device = Context.getIdentityManager().getDeviceByUniqueId(uniqueId); if (device != null) { deviceId = device.getId(); - Context.getConnectionManager().addActiveDevice(deviceId, protocol, channel, remoteAddress); + if (Context.getConnectionManager() != null) { + Context.getConnectionManager().addActiveDevice(deviceId, protocol, channel, remoteAddress); + } return true; } else { deviceId = 0; @@ -78,7 +80,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { public void getLastLocation(Position position, Date deviceTime) { position.setOutdated(true); - Position last = Context.getConnectionManager().getLastPosition(getDeviceId()); + Position last = Context.getIdentityManager().getLastPosition(getDeviceId()); if (last != null) { position.setFixTime(last.getFixTime()); position.setValid(last.getValid()); diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 0bb18b675..d32837755 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -18,6 +18,7 @@ package org.traccar; import com.ning.http.client.AsyncHttpClient; import org.traccar.database.ConnectionManager; import org.traccar.database.DataManager; +import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; @@ -67,6 +68,12 @@ public final class Context { return dataManager; } + private static DeviceManager deviceManager; + + public static DeviceManager getDeviceManager() { + return deviceManager; + } + private static ConnectionManager connectionManager; public static ConnectionManager getConnectionManager() { @@ -142,7 +149,12 @@ public final class Context { if (config.hasKey("database.url")) { dataManager = new DataManager(config); } - identityManager = dataManager; + + if (dataManager != null) { + deviceManager = new DeviceManager(dataManager); + } + + identityManager = deviceManager; if (config.getBoolean("geocoder.enable")) { String type = config.getString("geocoder.type", "google"); @@ -205,7 +217,7 @@ public final class Context { permissionsManager = new PermissionsManager(dataManager); - connectionManager = new ConnectionManager(dataManager); + connectionManager = new ConnectionManager(); if (config.getBoolean("event.geofenceHandler")) { geofenceManager = new GeofenceManager(dataManager); @@ -225,7 +237,6 @@ public final class Context { public static void init(IdentityManager testIdentityManager) { config = new Config(); - connectionManager = new ConnectionManager(null); identityManager = testIdentityManager; } diff --git a/src/org/traccar/DefaultDataHandler.java b/src/org/traccar/DefaultDataHandler.java index 594961389..8923c3a0e 100644 --- a/src/org/traccar/DefaultDataHandler.java +++ b/src/org/traccar/DefaultDataHandler.java @@ -25,10 +25,7 @@ public class DefaultDataHandler extends BaseDataHandler { try { Context.getDataManager().addPosition(position); - Position lastPosition = Context.getConnectionManager().getLastPosition(position.getDeviceId()); - if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) > 0) { - Context.getDataManager().updateLatestPosition(position); - } + Context.getDeviceManager().updateLatestPosition(position); } catch (Exception error) { Log.warning(error); } diff --git a/src/org/traccar/DistanceHandler.java b/src/org/traccar/DistanceHandler.java index b22815033..9f174a6c7 100644 --- a/src/org/traccar/DistanceHandler.java +++ b/src/org/traccar/DistanceHandler.java @@ -25,8 +25,8 @@ import java.math.RoundingMode; public class DistanceHandler extends BaseDataHandler { private Position getLastPosition(long deviceId) { - if (Context.getConnectionManager() != null) { - return Context.getConnectionManager().getLastPosition(deviceId); + if (Context.getIdentityManager() != null) { + return Context.getIdentityManager().getLastPosition(deviceId); } return null; } diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index ab570ee26..5315bad9e 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -57,8 +57,8 @@ public class FilterHandler extends BaseDataHandler { } private Position getLastPosition(long deviceId) { - if (Context.getConnectionManager() != null) { - return Context.getConnectionManager().getLastPosition(deviceId); + if (Context.getIdentityManager() != null) { + return Context.getIdentityManager().getLastPosition(deviceId); } return null; } diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index a0df34de5..771009aca 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -37,7 +37,7 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { Position position = (Position) e.getMessage(); - String uniqueId = Context.getDataManager().getDeviceById(position.getDeviceId()).getUniqueId(); + String uniqueId = Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId(); // Log position StringBuilder s = new StringBuilder(); @@ -54,11 +54,6 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { s.append(", result: ").append(cmdResult); } Log.info(s.toString()); - - Position lastPosition = Context.getConnectionManager().getLastPosition(position.getDeviceId()); - if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) > 0) { - Context.getConnectionManager().updatePosition(position); - } } } diff --git a/src/org/traccar/api/AsyncSocket.java b/src/org/traccar/api/AsyncSocket.java index d1e5594f4..4422dbccd 100644 --- a/src/org/traccar/api/AsyncSocket.java +++ b/src/org/traccar/api/AsyncSocket.java @@ -48,7 +48,7 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U super.onWebSocketConnect(session); Map> data = new HashMap<>(); - data.put(KEY_POSITIONS, Context.getConnectionManager().getInitialState(userId)); + data.put(KEY_POSITIONS, Context.getDeviceManager().getInitialState(userId)); sendData(data); Context.getConnectionManager().addListener(userId, this); diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java index d6c53dc04..f48df7553 100644 --- a/src/org/traccar/api/resource/DeviceResource.java +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -44,20 +44,20 @@ public class DeviceResource extends BaseResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { if (all) { Context.getPermissionsManager().checkAdmin(getUserId()); - return Context.getDataManager().getAllDevicesCached(); + return Context.getDeviceManager().getAllDevices(); } else { if (userId == 0) { userId = getUserId(); } Context.getPermissionsManager().checkUser(getUserId(), userId); - return Context.getDataManager().getDevices(userId); + return Context.getDeviceManager().getDevices(userId); } } @POST public Response add(Device entity) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); - Context.getDataManager().addDevice(entity); + Context.getDeviceManager().addDevice(entity); Context.getDataManager().linkDevice(getUserId(), entity.getId()); Context.getPermissionsManager().refresh(); if (Context.getGeofenceManager() != null) { @@ -71,7 +71,7 @@ public class DeviceResource extends BaseResource { public Response update(@PathParam("id") long id, Device entity) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDevice(getUserId(), id); - Context.getDataManager().updateDevice(entity); + Context.getDeviceManager().updateDevice(entity); if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refresh(); } @@ -83,7 +83,7 @@ public class DeviceResource extends BaseResource { public Response remove(@PathParam("id") long id) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDevice(getUserId(), id); - Context.getDataManager().removeDevice(id); + Context.getDeviceManager().removeDevice(id); Context.getPermissionsManager().refresh(); if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refresh(); diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index 2da517d4f..e00e06e7a 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -39,7 +39,7 @@ public class PositionResource extends BaseResource { @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { if (deviceId == 0) { - return Context.getConnectionManager().getInitialState(getUserId()); + return Context.getDeviceManager().getInitialState(getUserId()); } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); return Context.getDataManager().getPositions( diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 8796673b1..46ccab81e 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -28,12 +28,9 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.sql.SQLException; -import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -45,21 +42,11 @@ public class ConnectionManager { private final long deviceTimeout; private final Map activeDevices = new HashMap<>(); - private final Map positions = new HashMap<>(); private final Map> listeners = new HashMap<>(); private final Map timeouts = new HashMap<>(); - public ConnectionManager(DataManager dataManager) { + public ConnectionManager() { deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; - if (dataManager != null) { - try { - for (Position position : dataManager.getLatestPositions()) { - positions.put(position.getDeviceId(), position); - } - } catch (SQLException error) { - Log.warning(error); - } - } } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { @@ -80,31 +67,28 @@ public class ConnectionManager { return activeDevices.get(deviceId); } - public synchronized void updateDevice(final long deviceId, String status, Date time) { + public void updateDevice(final long deviceId, String status, Date time) { Device device = Context.getIdentityManager().getDeviceById(deviceId); if (device == null) { return; } - if (status.equals(Device.STATUS_MOVING) || status.equals(Device.STATUS_STOPPED)) { - device.setMotion(status); - } else { - if (!status.equals(device.getStatus())) { - Event event = new Event(Event.TYPE_DEVICE_OFFLINE, deviceId); - if (status.equals(Device.STATUS_ONLINE)) { - event.setType(Event.TYPE_DEVICE_ONLINE); - } - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().updateEvent(event, null); - } + if (!status.equals(device.getStatus())) { + Event event = new Event(Event.TYPE_DEVICE_OFFLINE, deviceId); + if (status.equals(Device.STATUS_ONLINE)) { + event.setType(Event.TYPE_DEVICE_ONLINE); } - device.setStatus(status); - - Timeout timeout = timeouts.remove(deviceId); - if (timeout != null) { - timeout.cancel(); + if (Context.getNotificationManager() != null) { + Context.getNotificationManager().updateEvent(event, null); } } + device.setStatus(status); + + Timeout timeout = timeouts.remove(deviceId); + if (timeout != null) { + timeout.cancel(); + } + if (time != null) { device.setLastUpdate(time); @@ -122,12 +106,16 @@ public class ConnectionManager { } try { - Context.getDataManager().updateDeviceStatus(device); + Context.getDeviceManager().updateDeviceStatus(device); } catch (SQLException error) { Log.warning(error); } - for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { + updateDevice(device); + } + + public synchronized void updateDevice(Device device) { + for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateDevice(device); @@ -138,7 +126,6 @@ public class ConnectionManager { public synchronized void updatePosition(Position position) { long deviceId = position.getDeviceId(); - positions.put(deviceId, position); for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { if (listeners.containsKey(userId)) { @@ -157,23 +144,6 @@ public class ConnectionManager { } } - public Position getLastPosition(long deviceId) { - return positions.get(deviceId); - } - - public synchronized Collection getInitialState(long userId) { - - List result = new LinkedList<>(); - - for (long deviceId : Context.getPermissionsManager().getDevicePermissions(userId)) { - if (positions.containsKey(deviceId)) { - result.add(positions.get(deviceId)); - } - } - - return result; - } - public interface UpdateListener { void onUpdateDevice(Device device); void onUpdatePosition(Position position); diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 0dc3c5c52..0aecaf2e7 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -62,9 +62,9 @@ import org.traccar.model.GeofencePermission; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; -public class DataManager implements IdentityManager { +public class DataManager { - private static final long DEFAULT_REFRESH_DELAY = 300; + public static final long DEFAULT_REFRESH_DELAY = 300; private final Config config; @@ -72,11 +72,6 @@ public class DataManager implements IdentityManager { private final long dataRefreshDelay; - private final ReadWriteLock devicesLock = new ReentrantReadWriteLock(); - private final Map devicesById = new HashMap<>(); - private final Map devicesByUniqueId = new HashMap<>(); - private long devicesLastUpdate; - private final ReadWriteLock groupsLock = new ReentrantReadWriteLock(); private final Map groupsById = new HashMap<>(); private long groupsLastUpdate; @@ -136,85 +131,6 @@ public class DataManager implements IdentityManager { } } - private void updateDeviceCache(boolean force) throws SQLException { - boolean needWrite; - devicesLock.readLock().lock(); - try { - needWrite = force || System.currentTimeMillis() - devicesLastUpdate > dataRefreshDelay; - } finally { - devicesLock.readLock().unlock(); - } - - if (needWrite) { - devicesLock.writeLock().lock(); - try { - if (force || System.currentTimeMillis() - devicesLastUpdate > dataRefreshDelay) { - devicesById.clear(); - devicesByUniqueId.clear(); - ConnectionManager connectionManager = Context.getConnectionManager(); - GeofenceManager geofenceManager = Context.getGeofenceManager(); - for (Device device : getAllDevices()) { - devicesById.put(device.getId(), device); - devicesByUniqueId.put(device.getUniqueId(), device); - if (connectionManager != null && geofenceManager != null) { - Position lastPosition = connectionManager.getLastPosition(device.getId()); - if (lastPosition != null) { - device.setGeofenceIds(geofenceManager.getCurrentDeviceGeofences(lastPosition)); - } - } - } - devicesLastUpdate = System.currentTimeMillis(); - } - } finally { - devicesLock.writeLock().unlock(); - } - } - } - - @Override - public Device getDeviceById(long id) { - boolean forceUpdate; - devicesLock.readLock().lock(); - try { - forceUpdate = !devicesById.containsKey(id); - } finally { - devicesLock.readLock().unlock(); - } - - try { - updateDeviceCache(forceUpdate); - } catch (SQLException e) { - Log.warning(e); - } - - devicesLock.readLock().lock(); - try { - return devicesById.get(id); - } finally { - devicesLock.readLock().unlock(); - } - } - - @Override - public Device getDeviceByUniqueId(String uniqueId) throws SQLException { - boolean forceUpdate; - devicesLock.readLock().lock(); - try { - forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean("database.ignoreUnknown"); - } finally { - devicesLock.readLock().unlock(); - } - - updateDeviceCache(forceUpdate); - - devicesLock.readLock().lock(); - try { - return devicesByUniqueId.get(uniqueId); - } finally { - devicesLock.readLock().unlock(); - } - } - private void updateGroupCache(boolean force) throws SQLException { boolean needWrite; groupsLock.readLock().lock(); @@ -347,72 +263,33 @@ public class DataManager implements IdentityManager { .executeQuery(GroupPermission.class); } - private Collection getAllDevices() throws SQLException { + public Collection getAllDevices() throws SQLException { return QueryBuilder.create(dataSource, getQuery("database.selectDevicesAll")) .executeQuery(Device.class); } - public Collection getAllDevicesCached() { - boolean forceUpdate; - devicesLock.readLock().lock(); - try { - forceUpdate = devicesById.isEmpty(); - } finally { - devicesLock.readLock().unlock(); - } - - try { - updateDeviceCache(forceUpdate); - } catch (SQLException e) { - Log.warning(e); - } - - devicesLock.readLock().lock(); - try { - return devicesById.values(); - } finally { - devicesLock.readLock().unlock(); - } - } - - public Collection getDevices(long userId) throws SQLException { - Collection devices = new ArrayList<>(); - for (long id : Context.getPermissionsManager().getDevicePermissions(userId)) { - devices.add(getDeviceById(id)); - } - return devices; - } - public void addDevice(Device device) throws SQLException { device.setId(QueryBuilder.create(dataSource, getQuery("database.insertDevice"), true) .setObject(device) .executeUpdate()); - updateDeviceCache(true); } public void updateDevice(Device device) throws SQLException { QueryBuilder.create(dataSource, getQuery("database.updateDevice")) .setObject(device) .executeUpdate(); - updateDeviceCache(true); } public void updateDeviceStatus(Device device) throws SQLException { QueryBuilder.create(dataSource, getQuery("database.updateDeviceStatus")) .setObject(device) .executeUpdate(); - if (devicesById.containsKey(device.getId())) { - Device cachedDevice = devicesById.get(device.getId()); - cachedDevice.setStatus(device.getStatus()); - cachedDevice.setMotion(device.getMotion()); - } } public void removeDevice(long deviceId) throws SQLException { QueryBuilder.create(dataSource, getQuery("database.deleteDevice")) .setLong("id", deviceId) .executeUpdate(); - updateDeviceCache(true); } public void linkDevice(long userId, long deviceId) throws SQLException { @@ -514,10 +391,6 @@ public class DataManager implements IdentityManager { .setDate("now", new Date()) .setObject(position) .executeUpdate(); - if (devicesById.containsKey(position.getDeviceId())) { - Device cachedDevice = devicesById.get(position.getDeviceId()); - cachedDevice.setPositionId(position.getId()); - } } public Collection getLatestPositions() throws SQLException { diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java new file mode 100644 index 000000000..70df1cc1a --- /dev/null +++ b/src/org/traccar/database/DeviceManager.java @@ -0,0 +1,261 @@ +package org.traccar.database; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.traccar.Config; +import org.traccar.Context; +import org.traccar.helper.Log; +import org.traccar.model.Device; +import org.traccar.model.Position; + +public class DeviceManager implements IdentityManager { + + private final Config config; + private final DataManager dataManager; + private final long dataRefreshDelay; + + private final ReadWriteLock devicesLock = new ReentrantReadWriteLock(); + private final Map devicesById = new HashMap<>(); + private final Map devicesByUniqueId = new HashMap<>(); + private long devicesLastUpdate; + + private final Map positions = new ConcurrentHashMap<>(); + + public DeviceManager(DataManager dataManager) { + this.dataManager = dataManager; + this.config = Context.getConfig(); + dataRefreshDelay = config.getLong("database.refreshDelay", DataManager.DEFAULT_REFRESH_DELAY) * 1000; + if (dataManager != null) { + try { + for (Position position : dataManager.getLatestPositions()) { + positions.put(position.getDeviceId(), position); + } + } catch (SQLException error) { + Log.warning(error); + } + } + } + + private void updateDeviceCache(boolean force) throws SQLException { + boolean needWrite; + devicesLock.readLock().lock(); + try { + needWrite = force || System.currentTimeMillis() - devicesLastUpdate > dataRefreshDelay; + } finally { + devicesLock.readLock().unlock(); + } + + if (needWrite) { + devicesLock.writeLock().lock(); + try { + if (force || System.currentTimeMillis() - devicesLastUpdate > dataRefreshDelay) { + devicesById.clear(); + devicesByUniqueId.clear(); + GeofenceManager geofenceManager = Context.getGeofenceManager(); + for (Device device : dataManager.getAllDevices()) { + devicesById.put(device.getId(), device); + devicesByUniqueId.put(device.getUniqueId(), device); + if (geofenceManager != null) { + Position lastPosition = getLastPosition(device.getId()); + if (lastPosition != null) { + device.setGeofenceIds(geofenceManager.getCurrentDeviceGeofences(lastPosition)); + } + } + } + devicesLastUpdate = System.currentTimeMillis(); + } + } finally { + devicesLock.writeLock().unlock(); + } + } + } + + @Override + public Device getDeviceById(long id) { + boolean forceUpdate; + devicesLock.readLock().lock(); + try { + forceUpdate = !devicesById.containsKey(id); + } finally { + devicesLock.readLock().unlock(); + } + + try { + updateDeviceCache(forceUpdate); + } catch (SQLException e) { + Log.warning(e); + } + + devicesLock.readLock().lock(); + try { + return devicesById.get(id); + } finally { + devicesLock.readLock().unlock(); + } + } + + @Override + public Device getDeviceByUniqueId(String uniqueId) throws SQLException { + boolean forceUpdate; + devicesLock.readLock().lock(); + try { + forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean("database.ignoreUnknown"); + } finally { + devicesLock.readLock().unlock(); + } + + updateDeviceCache(forceUpdate); + + devicesLock.readLock().lock(); + try { + return devicesByUniqueId.get(uniqueId); + } finally { + devicesLock.readLock().unlock(); + } + } + + public Collection getAllDevices() { + boolean forceUpdate; + devicesLock.readLock().lock(); + try { + forceUpdate = devicesById.isEmpty(); + } finally { + devicesLock.readLock().unlock(); + } + + try { + updateDeviceCache(forceUpdate); + } catch (SQLException e) { + Log.warning(e); + } + + devicesLock.readLock().lock(); + try { + return devicesById.values(); + } finally { + devicesLock.readLock().unlock(); + } + } + + public Collection getDevices(long userId) throws SQLException { + Collection devices = new ArrayList<>(); + devicesLock.readLock().lock(); + try { + for (long id : Context.getPermissionsManager().getDevicePermissions(userId)) { + devices.add(devicesById.get(id)); + } + } finally { + devicesLock.readLock().unlock(); + } + return devices; + } + + public void addDevice(Device device) throws SQLException { + dataManager.addDevice(device); + + devicesLock.writeLock().lock(); + try { + devicesById.put(device.getId(), device); + devicesByUniqueId.put(device.getUniqueId(), device); + } finally { + devicesLock.writeLock().unlock(); + } + } + + public void updateDevice(Device device) throws SQLException { + dataManager.updateDevice(device); + + devicesLock.writeLock().lock(); + try { + devicesById.put(device.getId(), device); + devicesByUniqueId.put(device.getUniqueId(), device); + } finally { + devicesLock.writeLock().unlock(); + } + } + + public void updateDeviceStatus(Device device) throws SQLException { + dataManager.updateDeviceStatus(device); + + devicesLock.writeLock().lock(); + try { + if (devicesById.containsKey(device.getId())) { + Device cachedDevice = devicesById.get(device.getId()); + cachedDevice.setStatus(device.getStatus()); + cachedDevice.setMotion(device.getMotion()); + } + } finally { + devicesLock.writeLock().unlock(); + } + } + + public void removeDevice(long deviceId) throws SQLException { + dataManager.removeDevice(deviceId); + + devicesLock.writeLock().lock(); + try { + if (devicesById.containsKey(deviceId)) { + String deviceUniqueId = devicesById.get(deviceId).getUniqueId(); + devicesById.remove(deviceId); + devicesByUniqueId.remove(deviceUniqueId); + } + } finally { + devicesLock.writeLock().unlock(); + } + + positions.remove(deviceId); + } + + public void updateLatestPosition(Position position) throws SQLException { + + Position lastPosition = getLastPosition(position.getDeviceId()); + if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) > 0) { + + dataManager.updateLatestPosition(position); + + devicesLock.writeLock().lock(); + try { + if (devicesById.containsKey(position.getDeviceId())) { + devicesById.get(position.getDeviceId()).setPositionId(position.getId()); + } + } finally { + devicesLock.writeLock().unlock(); + } + + positions.put(position.getDeviceId(), position); + + if (Context.getConnectionManager() != null) { + Context.getConnectionManager().updatePosition(position); + } + } + } + + @Override + public Position getLastPosition(long deviceId) { + return positions.get(deviceId); + } + + public Collection getInitialState(long userId) { + + List result = new LinkedList<>(); + + if (Context.getPermissionsManager() != null) { + for (long deviceId : Context.getPermissionsManager().getDevicePermissions(userId)) { + if (positions.containsKey(deviceId)) { + result.add(positions.get(deviceId)); + } + } + } + + return result; + } +} diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java index c35e19e9a..dc31172b9 100644 --- a/src/org/traccar/database/GeofenceManager.java +++ b/src/org/traccar/database/GeofenceManager.java @@ -173,7 +173,7 @@ public class GeofenceManager { .add(deviceGeofence.getGeofenceId()); } - for (Device device : dataManager.getAllDevicesCached()) { + for (Device device : Context.getDeviceManager().getAllDevices()) { long groupId = device.getGroupId(); while (groupId != 0) { getDeviceGeofences(deviceGeofencesWithGroups, @@ -190,7 +190,7 @@ public class GeofenceManager { } else { deviceGeofenceIds.clear(); } - Position lastPosition = Context.getConnectionManager().getLastPosition(device.getId()); + Position lastPosition = Context.getIdentityManager().getLastPosition(device.getId()); if (lastPosition != null && deviceGeofencesWithGroups.containsKey(device.getId())) { for (long geofenceId : deviceGeofencesWithGroups.get(device.getId())) { Geofence geofence = getGeofence(geofenceId); diff --git a/src/org/traccar/database/IdentityManager.java b/src/org/traccar/database/IdentityManager.java index 8bdce09a3..8c0de8b38 100644 --- a/src/org/traccar/database/IdentityManager.java +++ b/src/org/traccar/database/IdentityManager.java @@ -16,6 +16,7 @@ package org.traccar.database; import org.traccar.model.Device; +import org.traccar.model.Position; public interface IdentityManager { @@ -23,4 +24,6 @@ public interface IdentityManager { Device getDeviceByUniqueId(String uniqueId) throws Exception; + Position getLastPosition(long deviceId); + } diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index b6dd2e2a9..5a15375b4 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -78,7 +78,7 @@ public class PermissionsManager { users.put(user.getId(), user); } - GroupTree groupTree = new GroupTree(dataManager.getAllGroups(), dataManager.getAllDevicesCached()); + GroupTree groupTree = new GroupTree(dataManager.getAllGroups(), Context.getDeviceManager().getAllDevices()); for (GroupPermission permission : dataManager.getGroupPermissions()) { Set userGroupPermissions = getGroupPermissions(permission.getUserId()); Set userDevicePermissions = getDevicePermissions(permission.getUserId()); diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java index 9a546182d..1ea7aee41 100644 --- a/src/org/traccar/events/GeofenceEventHandler.java +++ b/src/org/traccar/events/GeofenceEventHandler.java @@ -43,7 +43,7 @@ public class GeofenceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = dataManager.getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index d10513d26..4a3d2f0f0 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -38,7 +38,7 @@ public class MotionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getDataManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); if (device == null) { return null; } @@ -53,16 +53,19 @@ public class MotionEventHandler extends BaseEventHandler { if (motion == null) { motion = Device.STATUS_STOPPED; } - if (valid && speed > SPEED_THRESHOLD && !motion.equals(Device.STATUS_MOVING)) { - Context.getConnectionManager().updateDevice(position.getDeviceId(), Device.STATUS_MOVING, null); - result = new ArrayList<>(); - result.add(new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId())); - } else if (valid && speed < SPEED_THRESHOLD && motion.equals(Device.STATUS_MOVING)) { - Context.getConnectionManager().updateDevice(position.getDeviceId(), Device.STATUS_STOPPED, null); - result = new ArrayList<>(); - result.add(new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId())); - } try { + if (valid && speed > SPEED_THRESHOLD && !motion.equals(Device.STATUS_MOVING)) { + device.setMotion(Device.STATUS_MOVING); + Context.getDeviceManager().updateDeviceStatus(device); + result = new ArrayList<>(); + result.add(new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId())); + } else if (valid && speed < SPEED_THRESHOLD && motion.equals(Device.STATUS_MOVING)) { + device.setMotion(Device.STATUS_STOPPED); + Context.getDeviceManager().updateDeviceStatus(device); + result = new ArrayList<>(); + result.add(new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId())); + } + if (result != null && !result.isEmpty()) { for (Event event : result) { if (!Context.getDataManager().getLastEvents(position.getDeviceId(), diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index e14d4bcea..fd005e170 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -40,7 +40,7 @@ public class OverspeedEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getDataManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); if (device == null) { return null; } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 503bc4c00..07a19b691 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -44,6 +44,11 @@ public class ProtocolTest { public Device getDeviceByUniqueId(String uniqueId) { return createDevice(); } + + @Override + public Position getLastPosition(long deviceId) { + return null; + } }); } -- cgit v1.2.3 From 22afcdff52d47e9705c446dc8590deeb6786a701 Mon Sep 17 00:00:00 2001 From: drecchia Date: Fri, 15 Jul 2016 08:22:06 -0300 Subject: - Fixed output control command construction. --- src/org/traccar/protocol/SuntechProtocolEncoder.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index 708b24e79..5f6835e92 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -30,8 +30,14 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "SA200CMD;{%s};0{%s};Enable{%s}\r", - Command.KEY_UNIQUE_ID, Command.KEY_DATA, Command.KEY_DATA); + if (command.getAttributes().containsKey(Command.KEY_DATA)) { + if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { + return formatCommand(command, "SA200CMD;{%s};02;Enable{%s}\r", + Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + } else + return formatCommand(command, "SA200CMD;{%s};02;Disable{%s}\r", + Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + } case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: -- cgit v1.2.3 From 6595b5f4b32c57d8ea4f98512d39292df75a3298 Mon Sep 17 00:00:00 2001 From: drecchia Date: Fri, 15 Jul 2016 19:05:15 -0300 Subject: - Fixed tags. --- src/org/traccar/protocol/SuntechProtocolEncoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/SuntechProtocolEncoder.java b/src/org/traccar/protocol/SuntechProtocolEncoder.java index 5f6835e92..000583759 100644 --- a/src/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/org/traccar/protocol/SuntechProtocolEncoder.java @@ -34,9 +34,10 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { return formatCommand(command, "SA200CMD;{%s};02;Enable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_INDEX); - } else + } else { return formatCommand(command, "SA200CMD;{%s};02;Disable{%s}\r", Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + } } case Command.TYPE_ENGINE_STOP: return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID); -- cgit v1.2.3 From 40bd91fd8a798c33212150afdccf95e5f5ea52c5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2016 16:13:33 +1200 Subject: Fix an issue with custom command --- src/org/traccar/BaseProtocol.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java index 4a3e63db4..eb09022f5 100644 --- a/src/org/traccar/BaseProtocol.java +++ b/src/org/traccar/BaseProtocol.java @@ -33,7 +33,6 @@ public abstract class BaseProtocol implements Protocol { public BaseProtocol(String name) { this.name = name; - supportedCommands.add(Command.TYPE_CUSTOM); } @Override @@ -47,7 +46,9 @@ public abstract class BaseProtocol implements Protocol { @Override public Collection getSupportedCommands() { - return supportedCommands; + Set commands = new HashSet<>(supportedCommands); + commands.add(Command.TYPE_CUSTOM); + return commands; } @Override -- cgit v1.2.3 From d8da0a28c50993e275b5ce9028d9e21ab23944aa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2016 17:24:19 +1200 Subject: Implement T800X custom commands --- src/org/traccar/protocol/T800xProtocol.java | 6 ++- src/org/traccar/protocol/T800xProtocolDecoder.java | 11 ++-- src/org/traccar/protocol/T800xProtocolEncoder.java | 63 ++++++++++++++++++++++ .../traccar/protocol/T800xProtocolEncoderTest.java | 23 ++++++++ 4 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 src/org/traccar/protocol/T800xProtocolEncoder.java create mode 100644 test/org/traccar/protocol/T800xProtocolEncoderTest.java (limited to 'src') diff --git a/src/org/traccar/protocol/T800xProtocol.java b/src/org/traccar/protocol/T800xProtocol.java index f98dfc943..05650124c 100644 --- a/src/org/traccar/protocol/T800xProtocol.java +++ b/src/org/traccar/protocol/T800xProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 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. @@ -20,6 +20,7 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; +import org.traccar.model.Command; import java.util.List; @@ -27,6 +28,8 @@ public class T800xProtocol extends BaseProtocol { public T800xProtocol() { super("t800x"); + setSupportedCommands( + Command.TYPE_CUSTOM); } @Override @@ -35,6 +38,7 @@ public class T800xProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); + pipeline.addLast("objectEncoder", new T800xProtocolEncoder()); pipeline.addLast("objectDecoder", new T800xProtocolDecoder(T800xProtocol.this)); } }); diff --git a/src/org/traccar/protocol/T800xProtocolDecoder.java b/src/org/traccar/protocol/T800xProtocolDecoder.java index 67a4d55ca..dcf45bb06 100644 --- a/src/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/org/traccar/protocol/T800xProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 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. @@ -34,10 +34,11 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final int MSG_LOGIN = 0x01; - private static final int MSG_GPS = 0x02; - private static final int MSG_HEARTBEAT = 0x03; - private static final int MSG_ALARM = 0x04; + public static final int MSG_LOGIN = 0x01; + public static final int MSG_GPS = 0x02; + public static final int MSG_HEARTBEAT = 0x03; + public static final int MSG_ALARM = 0x04; + public static final int MSG_COMMAND = 0x81; private static float readSwappedFloat(ChannelBuffer buf) { byte[] bytes = new byte[4]; diff --git a/src/org/traccar/protocol/T800xProtocolEncoder.java b/src/org/traccar/protocol/T800xProtocolEncoder.java new file mode 100644 index 000000000..d603328e2 --- /dev/null +++ b/src/org/traccar/protocol/T800xProtocolEncoder.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 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.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +import javax.xml.bind.DatatypeConverter; +import java.nio.charset.StandardCharsets; + +public class T800xProtocolEncoder extends BaseProtocolEncoder { + + public static final int MODE_SETTING = 0x01; + public static final int MODE_BROADCAST = 0x02; + public static final int MODE_FORWARD = 0x03; + + private ChannelBuffer encodeContent(Command command, String content) { + + ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + + buf.writeByte('#'); + buf.writeByte('#'); + buf.writeByte(T800xProtocolDecoder.MSG_COMMAND); + buf.writeShort(7 + 8 + 1 + content.length()); + buf.writeShort(1); // serial number + buf.writeBytes(DatatypeConverter.parseHexBinary("0" + getUniqueId(command.getDeviceId()))); + buf.writeByte(MODE_SETTING); + buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); + + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return encodeContent(command, (String) command.getAttributes().get(Command.KEY_DATA)); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + + return null; + } + +} diff --git a/test/org/traccar/protocol/T800xProtocolEncoderTest.java b/test/org/traccar/protocol/T800xProtocolEncoderTest.java new file mode 100644 index 000000000..af3700225 --- /dev/null +++ b/test/org/traccar/protocol/T800xProtocolEncoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class T800xProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + T800xProtocolEncoder encoder = new T800xProtocolEncoder(); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_CUSTOM); + command.set(Command.KEY_DATA, "RELAY,0000,On#"); + + verifyCommand(encoder, command, binary("232381001e000101234567890123450152454c41592c303030302c4f6e23")); + + } + +} -- cgit v1.2.3 From 57f4d3ab8ebb723c891e2b7583b85f6b14d547dd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2016 11:21:25 +1200 Subject: Fix minor decoder issue for Megastek --- src/org/traccar/protocol/MegastekProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 0c332d0da..ca554aa48 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -173,7 +173,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, Integer.parseInt(charger) == 1); } - if (parser.hasNext(3)) { + if (parser.hasNext(4)) { position.set(Position.KEY_MCC, parser.nextInt()); position.set(Position.KEY_MNC, parser.nextInt()); position.set(Position.KEY_LAC, parser.nextInt(16)); -- cgit v1.2.3 From a648c36ae4169ec5ef454f7ed9078cf4f6c7901f Mon Sep 17 00:00:00 2001 From: drecchia Date: Sun, 17 Jul 2016 21:56:02 -0300 Subject: - Carcell protocol for devices: cr2000 and cr250. --- debug.xml | 1 + setup/unix/traccar.xml | 1 + setup/windows/traccar.xml | 1 + src/org/traccar/protocol/CarcellProtocol.java | 52 +++++++ .../traccar/protocol/CarcellProtocolDecoder.java | 166 +++++++++++++++++++++ .../traccar/protocol/CarcellProtocolEncoder.java | 40 +++++ 6 files changed, 261 insertions(+) create mode 100644 src/org/traccar/protocol/CarcellProtocol.java create mode 100644 src/org/traccar/protocol/CarcellProtocolDecoder.java create mode 100644 src/org/traccar/protocol/CarcellProtocolEncoder.java (limited to 'src') diff --git a/debug.xml b/debug.xml index 09a575450..a55d1a6a6 100644 --- a/debug.xml +++ b/debug.xml @@ -436,5 +436,6 @@ 5111 5112 5113 + 5114 diff --git a/setup/unix/traccar.xml b/setup/unix/traccar.xml index a8bf9c334..8a119f35a 100644 --- a/setup/unix/traccar.xml +++ b/setup/unix/traccar.xml @@ -388,5 +388,6 @@ 5111 5112 5113 + 5114 diff --git a/setup/windows/traccar.xml b/setup/windows/traccar.xml index a67d8c53c..049034b01 100644 --- a/setup/windows/traccar.xml +++ b/setup/windows/traccar.xml @@ -388,5 +388,6 @@ 5111 5112 5113 + 5114 diff --git a/src/org/traccar/protocol/CarcellProtocol.java b/src/org/traccar/protocol/CarcellProtocol.java new file mode 100644 index 000000000..5982e9cf8 --- /dev/null +++ b/src/org/traccar/protocol/CarcellProtocol.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 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 java.util.List; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; +import org.traccar.model.Command; + +public class CarcellProtocol extends BaseProtocol { + + public CarcellProtocol() { + super("carcell"); + setSupportedCommands( + Command.TYPE_ENGINE_STOP, + Command.TYPE_ENGINE_RESUME); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectEncoder", new CarcellProtocolEncoder()); + pipeline.addLast("objectDecoder", new CarcellProtocolDecoder(CarcellProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/CarcellProtocolDecoder.java b/src/org/traccar/protocol/CarcellProtocolDecoder.java new file mode 100644 index 000000000..e8c30f276 --- /dev/null +++ b/src/org/traccar/protocol/CarcellProtocolDecoder.java @@ -0,0 +1,166 @@ +/* + * Copyright 2016 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 java.net.SocketAddress; +import java.util.regex.Pattern; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.Parser.CoordinateFormat; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +public class CarcellProtocolDecoder extends BaseProtocolDecoder { + + public CarcellProtocolDecoder(CarcellProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .expression("([$%])") // memory flag + .number("(d+),") // imei + .groupBegin() + .number("([NS])(dd)(dd).(dddd),") // latitude + .number("([EW])(ddd)(dd).(dddd),") // longitude + .or() + .text("CEL,") + .number("([NS])(d+.d+),") // latitude + .number("([EW])(d+.d+),") // longitude + .groupEnd() + .number("(d+),") // speed + .number("(d+),") // course + .groupBegin() + .number("([-+]ddd)([-+]ddd)([-+]ddd),") // x,y,z + .or() + .number("(d+),") // accel + .groupEnd() + .number("(d+),") // battery + .number("(d+),") // csq + .number("(d),") // jamming + .number("(d+),") // hdop + .expression("([CG]),?") // clock type + .number("(dd)(dd)(dd),") // date + .number("(dd)(dd)(dd),") // time + .number("(d),") // block + .number("(d),") // ignition + .groupBegin() + .number("(d),") // cloned + .expression("([AF])") // panic + .number("(d),") // painel + .number("(d+),") // battery voltage + .or() + .number("(dd),") // time + .expression("([AF])") // panic + .number("(d),") // aux + .number("(d{2,4}),") // battery voltage + .number("(d{20}),") // ccid + .groupEnd() + .number("(xx)") // crc + .any() // full format + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + + if (!parser.matches()) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.set(Position.KEY_ARCHIVE, parser.next().equals("%")); + position.setValid(true); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + + position.setDeviceId(getDeviceId()); + + if (parser.hasNext(8)) { + position.setLatitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG_MIN_MIN)); + position.setLongitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG_MIN_MIN)); + } + + if (parser.hasNext(4)) { + position.setLatitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(CoordinateFormat.HEM_DEG)); + } + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + + if (parser.hasNext(3)) { + position.set("x", parser.nextInt()); + position.set("y", parser.nextInt()); + position.set("z", parser.nextInt()); + } + + if (parser.hasNext(1)) { + position.set("accel", parser.nextInt()); + } + + Double internalBattery = (parser.nextDouble() + 100d) * 0.0294d; + position.set(Position.KEY_BATTERY, internalBattery); + position.set(Position.KEY_GSM, parser.nextInt()); + position.set("jamming", parser.next().equals("1")); + position.set(Position.KEY_GPS, parser.nextInt()); + + parser.next(); // clock type + + DateBuilder dateBuilder = new DateBuilder(). + setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.set("blocked", parser.next().equals("1")); + position.set(Position.KEY_IGNITION, parser.next().equals("1")); + + if (parser.hasNext(4)) { + position.set("cloned", parser.next().equals("1")); + + parser.next(); // panic button status + + Integer painelStatus = parser.nextInt(); + position.set(Position.KEY_ALARM, painelStatus.equals("1")); + position.set("painel", painelStatus.equals("2")); + + Double mainVoltage = parser.nextDouble() / 100d; + position.set(Position.KEY_POWER, mainVoltage); + } + + if (parser.hasNext(5)) { + position.set("timeUntilDelivery", parser.nextInt()); + parser.next(); // panic button status + parser.next(); // aux + + Double mainVoltage = parser.nextDouble() / 100d; + position.set(Position.KEY_POWER, mainVoltage); + + position.set("iccid", parser.next()); + } + + return position; + } + +} diff --git a/src/org/traccar/protocol/CarcellProtocolEncoder.java b/src/org/traccar/protocol/CarcellProtocolEncoder.java new file mode 100644 index 000000000..d01a11e52 --- /dev/null +++ b/src/org/traccar/protocol/CarcellProtocolEncoder.java @@ -0,0 +1,40 @@ +/* + * Copyright 2016 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.traccar.StringProtocolEncoder; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +public class CarcellProtocolEncoder extends StringProtocolEncoder { + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_ENGINE_STOP: + return formatCommand(command, "$SRVCMD,{%s},BA#\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME: + return formatCommand(command, "$SRVCMD,{%s},BD#\r\n", Command.KEY_UNIQUE_ID); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + + return null; + } + +} -- cgit v1.2.3 From 8a9ed3cd8a001c0b4fd6ba2869db84195a449769 Mon Sep 17 00:00:00 2001 From: drecchia Date: Sun, 17 Jul 2016 22:00:27 -0300 Subject: - Fixed findbugs warning. --- src/org/traccar/protocol/CarcellProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/CarcellProtocolDecoder.java b/src/org/traccar/protocol/CarcellProtocolDecoder.java index e8c30f276..50b294f45 100644 --- a/src/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/org/traccar/protocol/CarcellProtocolDecoder.java @@ -141,7 +141,7 @@ public class CarcellProtocolDecoder extends BaseProtocolDecoder { parser.next(); // panic button status - Integer painelStatus = parser.nextInt(); + String painelStatus = parser.next(); position.set(Position.KEY_ALARM, painelStatus.equals("1")); position.set("painel", painelStatus.equals("2")); -- cgit v1.2.3 From 24fa824e20cf68d36f760e4b921edb1fb25525b3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2016 14:25:18 +1200 Subject: Support GT06 external power subtype --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 14 +++++++++++++- test/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index ce915fde8..57e2d64b7 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -277,7 +277,19 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_INFO) { int subType = buf.readUnsignedByte(); - if (subType == 0x05) { + if (subType == 0x00) { + + Position position = new Position(); + position.setDeviceId(getDeviceId()); + position.setProtocol(getProtocolName()); + + getLastLocation(position, null); + + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + + return position; + + } else if (subType == 0x05) { Position position = new Position(); position.setDeviceId(getDeviceId()); diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 94d665478..9201caac6 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNothing(decoder, binary( "787805120099abec0d0a")); + verifyAttributes(decoder, binary( + "797900089400000002e852d70d0a")); + verifyNothing(decoder, binary( "78780D01086471700328358100093F040D0A")); -- cgit v1.2.3 From d3e063cf9de8a45bed4dfe87b73aadfd8d2edeab Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2016 16:14:18 +1200 Subject: Decode MiniFinder status flags --- src/org/traccar/model/Position.java | 9 ++++++++ .../protocol/MiniFinderProtocolDecoder.java | 26 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 4e03b2097..e667f097d 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -66,6 +66,15 @@ public class Position extends Message { public static final String PREFIX_IO = "io"; public static final String PREFIX_COUNT = "count"; + public static final String ALARM_SOS = "sos"; + public static final String ALARM_VIBRATION = "vibration"; + public static final String ALARM_MOVEMENT = "movement"; + public static final String ALARM_OVERSPEED = "overspeed"; + public static final String ALARM_FALL_DOWN = "fallDown"; + public static final String ALARM_LOW_BATTERY = "lowBattery"; + public static final String ALARM_MOTION = "motion"; + public static final String ALARM_FAULT = "fault"; + private String protocol; public String getProtocol() { diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java index 089b491d2..96eaaf0fa 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -90,9 +90,33 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(5)) { int flags = parser.nextInt(16); - position.set(Position.KEY_FLAGS, flags); + position.setValid(BitUtil.check(flags, 0)); + if (BitUtil.check(flags, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_FAULT); + } + if (BitUtil.check(flags, 6)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + if (BitUtil.check(flags, 7)) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } + if (BitUtil.check(flags, 8)) { + position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); + } + if (BitUtil.check(flags, 12)) { + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + } + if (BitUtil.check(flags, 14)) { + position.set(Position.KEY_ALARM, Position.ALARM_MOTION); + } + if (BitUtil.check(flags, 15)) { + position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + } + + position.set(Position.KEY_GSM, BitUtil.between(flags, 16, 20)); + position.setAltitude(parser.nextDouble()); position.set(Position.KEY_BATTERY, parser.next()); -- cgit v1.2.3