aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorninioe <ninioe@gmail.com>2016-08-01 16:12:47 +0300
committerninioe <ninioe@gmail.com>2016-08-01 16:12:47 +0300
commit94781fa3ba35e494e309aee19a5e15c14d3193c1 (patch)
treea1e4a90e9a2fce3db8bc51981aeb8a23cced5e6d
parentb4841fa0a6293c0b895cf6bb65c6c2d871c78397 (diff)
parente177e7d083a4dd3f64172802661bf658d26d1163 (diff)
downloadtraccar-server-94781fa3ba35e494e309aee19a5e15c14d3193c1.tar.gz
traccar-server-94781fa3ba35e494e309aee19a5e15c14d3193c1.tar.bz2
traccar-server-94781fa3ba35e494e309aee19a5e15c14d3193c1.zip
Merge remote-tracking branch 'refs/remotes/tananaev/master'
-rw-r--r--debug.xml20
-rw-r--r--schema/changelog-3.7.xml12
-rw-r--r--setup/unix/traccar.xml9
-rw-r--r--setup/windows/traccar.xml9
-rw-r--r--src/org/traccar/DefaultDataHandler.java1
-rw-r--r--src/org/traccar/ExtendedObjectDecoder.java3
-rw-r--r--src/org/traccar/Main.java9
-rw-r--r--src/org/traccar/MainEventHandler.java7
-rw-r--r--src/org/traccar/api/resource/ServerResource.java5
-rw-r--r--src/org/traccar/database/DataManager.java27
-rw-r--r--src/org/traccar/database/DeviceManager.java42
-rw-r--r--src/org/traccar/database/PermissionsManager.java11
-rw-r--r--src/org/traccar/events/GeofenceEventHandler.java39
-rw-r--r--src/org/traccar/events/MotionEventHandler.java48
-rw-r--r--src/org/traccar/events/OverspeedEventHandler.java40
-rw-r--r--src/org/traccar/model/Device.java13
-rw-r--r--src/org/traccar/model/Group.java12
-rw-r--r--src/org/traccar/model/Server.java12
-rw-r--r--src/org/traccar/protocol/H02ProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/HuaShengProtocolDecoder.java10
-rw-r--r--src/org/traccar/protocol/OsmAndProtocolDecoder.java26
-rw-r--r--src/org/traccar/protocol/T55ProtocolDecoder.java11
-rw-r--r--swagger.json6
-rw-r--r--test/org/traccar/protocol/EelinkProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/HuaShengProtocolDecoderTest.java4
-rw-r--r--test/org/traccar/protocol/MegastekProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/OsmAndProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/T55ProtocolDecoderTest.java2
-rw-r--r--web/app.css6
-rw-r--r--web/app/AttributeFormatter.js20
-rw-r--r--web/app/controller/Root.js2
-rw-r--r--web/app/model/Group.js2
-rw-r--r--web/app/model/Server.js2
-rw-r--r--web/app/view/AttributeController.js (renamed from web/app/view/DeviceDialogController.js)36
-rw-r--r--web/app/view/AttributeDialog.js16
-rw-r--r--web/app/view/BaseEditDialog.js5
-rw-r--r--web/app/view/BaseEditDialogController.js18
-rw-r--r--web/app/view/DeviceDialog.js19
-rw-r--r--web/app/view/Devices.js12
-rw-r--r--web/app/view/MapController.js50
-rw-r--r--web/app/view/Report.js5
-rw-r--r--web/app/view/ServerDialog.js2
-rw-r--r--web/app/view/State.js8
-rw-r--r--web/app/view/UserDialog.js13
-rw-r--r--web/app/view/UserDialogController.js20
-rw-r--r--web/l10n/en.json2
46 files changed, 302 insertions, 325 deletions
diff --git a/debug.xml b/debug.xml
index 346eda292..abd230748 100644
--- a/debug.xml
+++ b/debug.xml
@@ -41,10 +41,11 @@
<entry key='logger.level'>all</entry>
<entry key='logger.file'>target/tracker-server.log</entry>
+ <entry key='deviceManager.lookupGroupsAttribute'>true</entry>
+
<entry key='event.enable'>true</entry>
- <entry key='event.suppressRepeated'>60</entry>
<entry key='event.overspeedHandler'>true</entry>
- <entry key='event.globalSpeedLimit'>90</entry>
+ <entry key='event.overspeed.notRepeat'>true</entry>
<entry key='event.motionHandler'>true</entry>
<entry key='event.geofenceHandler'>true</entry>
<entry key='event.alertHandler'>true</entry>
@@ -80,7 +81,7 @@
<entry key='database.ignoreUnknown'>true</entry>
<entry key='database.xml'>false</entry>
- <entry key='database.saveOriginal'>false</entry>
+ <entry key='database.saveOriginal'>true</entry>
<entry key='database.changelog'>./schema/changelog-master.xml</entry>
@@ -102,7 +103,8 @@
latitude = :latitude,
longitude = :longitude,
zoom = :zoom,
- twelveHourFormat = :twelveHourFormat
+ twelveHourFormat = :twelveHourFormat,
+ attributes = :attributes
WHERE id = :id;
</entry>
@@ -170,7 +172,7 @@
</entry>
<entry key='database.updateDeviceStatus'>
- UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion WHERE id = :id;
+ UPDATE devices SET lastUpdate = :lastUpdate WHERE id = :id;
</entry>
<entry key='database.deleteDevice'>
@@ -190,11 +192,11 @@
</entry>
<entry key='database.insertGroup'>
- INSERT INTO groups (name, groupId) VALUES (:name, :groupId);
+ INSERT INTO groups (name, groupId, attributes) VALUES (:name, :groupId, :attributes);
</entry>
<entry key='database.updateGroup'>
- UPDATE groups SET name = :name, groupId = :groupId WHERE id = :id;
+ UPDATE groups SET name = :name, groupId = :groupId, attributes = :attributes WHERE id = :id;
</entry>
<entry key='database.deleteGroup'>
@@ -323,8 +325,8 @@
DELETE FROM notifications WHERE id = :id;
</entry>
- <entry key='database.clearPositionsHistory'>
- DELETE FROM positions WHERE id != :positionId and deviceid = :deviceId and servertime &lt; :serverTime;
+ <entry key='database.deletePositions'>
+ DELETE FROM positions WHERE serverTime &lt; :serverTime AND id NOT IN (SELECT positionId FROM devices);
</entry>
<!-- PROTOCOL CONFIG -->
diff --git a/schema/changelog-3.7.xml b/schema/changelog-3.7.xml
index e23e44b04..d82dbe91b 100644
--- a/schema/changelog-3.7.xml
+++ b/schema/changelog-3.7.xml
@@ -24,6 +24,18 @@
<column name="attributes" type="VARCHAR(4096)" />
</addColumn>
+ <dropColumn tableName="devices" columnName="motion" />
+
+ <dropColumn tableName="devices" columnName="status" />
+
+ <addColumn tableName="groups">
+ <column name="attributes" type="VARCHAR(4096)" />
+ </addColumn>
+
+ <addColumn tableName="server">
+ <column name="attributes" type="VARCHAR(4096)" />
+ </addColumn>
+
</changeSet>
<changeSet author="author" id="changelog-3.7-notmssql">
diff --git a/setup/unix/traccar.xml b/setup/unix/traccar.xml
index e8b29a296..da09d74d6 100644
--- a/setup/unix/traccar.xml
+++ b/setup/unix/traccar.xml
@@ -51,7 +51,8 @@
latitude = :latitude,
longitude = :longitude,
zoom = :zoom,
- twelveHourFormat = :twelveHourFormat
+ twelveHourFormat = :twelveHourFormat,
+ attributes = :attributes
WHERE id = :id;
</entry>
@@ -119,7 +120,7 @@
</entry>
<entry key='database.updateDeviceStatus'>
- UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion WHERE id = :id;
+ UPDATE devices SET lastUpdate = :lastUpdate WHERE id = :id;
</entry>
<entry key='database.deleteDevice'>
@@ -139,11 +140,11 @@
</entry>
<entry key='database.insertGroup'>
- INSERT INTO groups (name, groupId) VALUES (:name, :groupId);
+ INSERT INTO groups (name, groupId, attributes) VALUES (:name, :groupId, :attributes);
</entry>
<entry key='database.updateGroup'>
- UPDATE groups SET name = :name, groupId = :groupId WHERE id = :id;
+ UPDATE groups SET name = :name, groupId = :groupId, attributes = :attributes WHERE id = :id;
</entry>
<entry key='database.deleteGroup'>
diff --git a/setup/windows/traccar.xml b/setup/windows/traccar.xml
index 6220263ef..a3971e4f8 100644
--- a/setup/windows/traccar.xml
+++ b/setup/windows/traccar.xml
@@ -51,7 +51,8 @@
latitude = :latitude,
longitude = :longitude,
zoom = :zoom,
- twelveHourFormat = :twelveHourFormat
+ twelveHourFormat = :twelveHourFormat,
+ attributes = :attributes
WHERE id = :id;
</entry>
@@ -119,7 +120,7 @@
</entry>
<entry key='database.updateDeviceStatus'>
- UPDATE devices SET status = :status, lastUpdate = :lastUpdate, motion = :motion WHERE id = :id;
+ UPDATE devices SET lastUpdate = :lastUpdate WHERE id = :id;
</entry>
<entry key='database.deleteDevice'>
@@ -139,11 +140,11 @@
</entry>
<entry key='database.insertGroup'>
- INSERT INTO groups (name, groupId) VALUES (:name, :groupId);
+ INSERT INTO groups (name, groupId, attributes) VALUES (:name, :groupId, :attributes);
</entry>
<entry key='database.updateGroup'>
- UPDATE groups SET name = :name, groupId = :groupId WHERE id = :id;
+ UPDATE groups SET name = :name, groupId = :groupId, attributes = :attributes WHERE id = :id;
</entry>
<entry key='database.deleteGroup'>
diff --git a/src/org/traccar/DefaultDataHandler.java b/src/org/traccar/DefaultDataHandler.java
index 8923c3a0e..7194c6a77 100644
--- a/src/org/traccar/DefaultDataHandler.java
+++ b/src/org/traccar/DefaultDataHandler.java
@@ -25,7 +25,6 @@ public class DefaultDataHandler extends BaseDataHandler {
try {
Context.getDataManager().addPosition(position);
- Context.getDeviceManager().updateLatestPosition(position);
} catch (Exception error) {
Log.warning(error);
}
diff --git a/src/org/traccar/ExtendedObjectDecoder.java b/src/org/traccar/ExtendedObjectDecoder.java
index d7ca30de4..1cfc93541 100644
--- a/src/org/traccar/ExtendedObjectDecoder.java
+++ b/src/org/traccar/ExtendedObjectDecoder.java
@@ -36,7 +36,8 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler {
if (Context.getConfig().getBoolean("database.saveOriginal") && decodedMessage instanceof Position) {
Position position = (Position) decodedMessage;
if (originalMessage instanceof ChannelBuffer) {
- position.set(Position.KEY_ORIGINAL, ChannelBuffers.hexDump((ChannelBuffer) originalMessage));
+ ChannelBuffer buf = (ChannelBuffer) originalMessage;
+ position.set(Position.KEY_ORIGINAL, ChannelBuffers.hexDump(buf, 0, buf.writerIndex()));
} else if (originalMessage instanceof String) {
position.set(Position.KEY_ORIGINAL, DatatypeConverter.printHexBinary(
((String) originalMessage).getBytes(StandardCharsets.US_ASCII)));
diff --git a/src/org/traccar/Main.java b/src/org/traccar/Main.java
index e7e8d8ab9..e992691ad 100644
--- a/src/org/traccar/Main.java
+++ b/src/org/traccar/Main.java
@@ -23,8 +23,8 @@ import java.util.TimerTask;
import java.util.Locale;
public final class Main {
- static final long CLEAN_DELAY = 0;
- static final long CLEAN_PERIOD = 24 * 60 * 60 * 1000;
+
+ private static final long CLEAN_PERIOD = 24 * 60 * 60 * 1000;
private Main() {
}
@@ -40,8 +40,7 @@ public final class Main {
Context.getWebServer().start();
}
- Timer timer = new Timer();
- timer.scheduleAtFixedRate(new TimerTask() {
+ new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
@@ -50,7 +49,7 @@ public final class Main {
Log.warning(error);
}
}
- }, CLEAN_DELAY, CLEAN_PERIOD);
+ }, 0, CLEAN_PERIOD);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java
index 771009aca..c01760283 100644
--- a/src/org/traccar/MainEventHandler.java
+++ b/src/org/traccar/MainEventHandler.java
@@ -26,6 +26,7 @@ import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.traccar.helper.Log;
import org.traccar.model.Position;
+import java.sql.SQLException;
import java.text.SimpleDateFormat;
public class MainEventHandler extends IdleStateAwareChannelHandler {
@@ -36,6 +37,11 @@ public class MainEventHandler extends IdleStateAwareChannelHandler {
if (e.getMessage() != null && e.getMessage() instanceof Position) {
Position position = (Position) e.getMessage();
+ try {
+ Context.getDeviceManager().updateLatestPosition(position);
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
String uniqueId = Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId();
@@ -54,6 +60,7 @@ public class MainEventHandler extends IdleStateAwareChannelHandler {
s.append(", result: ").append(cmdResult);
}
Log.info(s.toString());
+
}
}
diff --git a/src/org/traccar/api/resource/ServerResource.java b/src/org/traccar/api/resource/ServerResource.java
index 9e42687ab..0ca0d62aa 100644
--- a/src/org/traccar/api/resource/ServerResource.java
+++ b/src/org/traccar/api/resource/ServerResource.java
@@ -37,14 +37,13 @@ public class ServerResource extends BaseResource {
@PermitAll
@GET
public Server get() throws SQLException {
- return Context.getDataManager().getServer();
+ return Context.getPermissionsManager().getServer();
}
@PUT
public Response update(Server entity) throws SQLException {
Context.getPermissionsManager().checkAdmin(getUserId());
- Context.getDataManager().updateServer(entity);
- Context.getPermissionsManager().refresh();
+ Context.getPermissionsManager().updateServer(entity);
return Response.ok(entity).build();
}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 04d0d44ea..78f1b4109 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -305,28 +305,11 @@ public class DataManager {
}
public void clearPositionsHistory() throws SQLException {
- int histDays = config.getInteger("database.positionsHistoryDays");
- if (histDays == 0) {
- return;
- }
-
- String sql = getQuery("database.clearPositionsHistory");
- if (sql == null) {
- return;
- }
-
- for (Device device : getAllDevices()) {
- Date lastUpdate = device.getLastUpdate();
- if (lastUpdate != null) {
-
- Date dateBefore = new Date(lastUpdate.getTime() - histDays * 24 * 3600 * 1000);
-
- QueryBuilder.create(dataSource, sql)
- .setLong("positionId", device.getPositionId())
- .setLong("deviceId", device.getId())
- .setDate("serverTime", dateBefore)
- .executeUpdate();
- }
+ int historyDays = config.getInteger("database.positionsHistoryDays");
+ if (historyDays != 0) {
+ QueryBuilder.create(dataSource, getQuery("database.deletePositions"))
+ .setDate("serverTime", new Date(System.currentTimeMillis() - historyDays * 24 * 3600 * 1000))
+ .executeUpdate();
}
}
diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java
index 4dd7b41cb..3476139f2 100644
--- a/src/org/traccar/database/DeviceManager.java
+++ b/src/org/traccar/database/DeviceManager.java
@@ -32,6 +32,7 @@ import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.Group;
import org.traccar.model.Position;
+import org.traccar.model.Server;
public class DeviceManager implements IdentityManager {
@@ -40,6 +41,7 @@ public class DeviceManager implements IdentityManager {
private final Config config;
private final DataManager dataManager;
private final long dataRefreshDelay;
+ private boolean lookupGroupsAttribute;
private Map<Long, Device> devicesById;
private Map<String, Device> devicesByUniqueId;
@@ -54,6 +56,7 @@ public class DeviceManager implements IdentityManager {
this.dataManager = dataManager;
this.config = Context.getConfig();
dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000;
+ lookupGroupsAttribute = config.getBoolean("deviceManager.lookupGroupsAttribute");
if (dataManager != null) {
try {
updateGroupCache(true);
@@ -105,7 +108,6 @@ public class DeviceManager implements IdentityManager {
}
}
device.setStatus(Device.STATUS_OFFLINE);
- device.setMotion(Device.STATUS_STOPPED);
}
}
for (Long cachedDeviceId : devicesById.keySet()) {
@@ -176,7 +178,6 @@ public class DeviceManager implements IdentityManager {
if (devicesById.containsKey(device.getId())) {
Device cachedDevice = devicesById.get(device.getId());
cachedDevice.setStatus(device.getStatus());
- cachedDevice.setMotion(device.getMotion());
}
}
@@ -191,10 +192,14 @@ public class DeviceManager implements IdentityManager {
positions.remove(deviceId);
}
+ public boolean isLatestPosition(Position position) {
+ Position lastPosition = getLastPosition(position.getDeviceId());
+ return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) > 0;
+ }
+
public void updateLatestPosition(Position position) throws SQLException {
- Position lastPosition = getLastPosition(position.getDeviceId());
- if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) > 0) {
+ if (isLatestPosition(position)) {
dataManager.updateLatestPosition(position);
@@ -310,4 +315,33 @@ public class DeviceManager implements IdentityManager {
dataManager.removeGroup(groupId);
groupsById.remove(groupId);
}
+
+ public String lookupAttribute(long deviceId, String attributeName) {
+ String result = null;
+ Device device = getDeviceById(deviceId);
+ if (device != null) {
+ if (device.getAttributes().containsKey(attributeName)) {
+ result = (String) device.getAttributes().get(attributeName);
+ }
+ if (result == null && lookupGroupsAttribute) {
+ long groupId = device.getGroupId();
+ while (groupId != 0) {
+ if (getGroupById(groupId) != null) {
+ result = (String) getGroupById(groupId).getAttributes().get(attributeName);
+ if (result != null) {
+ break;
+ }
+ groupId = getGroupById(groupId).getGroupId();
+ } else {
+ groupId = 0;
+ }
+ }
+ }
+ if (result == null) {
+ Server server = Context.getPermissionsManager().getServer();
+ result = (String) server.getAttributes().get(attributeName);
+ }
+ }
+ return result;
+ }
}
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index d786dcc4e..92fcc3ebd 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -34,7 +34,7 @@ public class PermissionsManager {
private final DataManager dataManager;
- private Server server;
+ private volatile Server server;
private final Map<Long, User> users = new HashMap<>();
@@ -153,4 +153,13 @@ public class PermissionsManager {
}
}
+ public Server getServer() {
+ return server;
+ }
+
+ public void updateServer(Server server) throws SQLException {
+ dataManager.updateServer(server);
+ this.server = server;
+ }
+
}
diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java
index 1ea7aee41..a0291dcfa 100644
--- a/src/org/traccar/events/GeofenceEventHandler.java
+++ b/src/org/traccar/events/GeofenceEventHandler.java
@@ -15,30 +15,23 @@
*/
package org.traccar.events;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.traccar.BaseEventHandler;
import org.traccar.Context;
-import org.traccar.database.DataManager;
import org.traccar.database.GeofenceManager;
-import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
public class GeofenceEventHandler extends BaseEventHandler {
- private int suppressRepeated;
private GeofenceManager geofenceManager;
- private DataManager dataManager;
public GeofenceEventHandler() {
- suppressRepeated = Context.getConfig().getInteger("event.suppressRepeated", 60);
geofenceManager = Context.getGeofenceManager();
- dataManager = Context.getDataManager();
}
@Override
@@ -47,7 +40,7 @@ public class GeofenceEventHandler extends BaseEventHandler {
if (device == null) {
return null;
}
- if (position.getId() != device.getPositionId() || !position.getValid()) {
+ if (!Context.getDeviceManager().isLatestPosition(position) || !position.getValid()) {
return null;
}
@@ -63,29 +56,15 @@ public class GeofenceEventHandler extends BaseEventHandler {
device.setGeofenceIds(currentGeofences);
Collection<Event> events = new ArrayList<>();
- try {
- if (dataManager.getLastEvents(position.getDeviceId(),
- Event.TYPE_GEOFENCE_ENTER, suppressRepeated).isEmpty()) {
- for (long geofenceId : newGeofences) {
- Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId());
- event.setGeofenceId(geofenceId);
- events.add(event);
- }
- }
- } catch (SQLException error) {
- Log.warning(error);
+ for (long geofenceId : newGeofences) {
+ Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId());
+ event.setGeofenceId(geofenceId);
+ events.add(event);
}
- try {
- if (dataManager.getLastEvents(position.getDeviceId(),
- Event.TYPE_GEOFENCE_EXIT, suppressRepeated).isEmpty()) {
- for (long geofenceId : oldGeofences) {
- Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId());
- event.setGeofenceId(geofenceId);
- events.add(event);
- }
- }
- } catch (SQLException error) {
- Log.warning(error);
+ for (long geofenceId : oldGeofences) {
+ Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId());
+ event.setGeofenceId(geofenceId);
+ events.add(event);
}
return events;
}
diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java
index 4a3d2f0f0..ddb99185f 100644
--- a/src/org/traccar/events/MotionEventHandler.java
+++ b/src/org/traccar/events/MotionEventHandler.java
@@ -15,25 +15,18 @@
*/
package org.traccar.events;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import org.traccar.BaseEventHandler;
import org.traccar.Context;
-import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
public class MotionEventHandler extends BaseEventHandler {
- private static final double SPEED_THRESHOLD = 0.01;
- private int suppressRepeated;
-
- public MotionEventHandler() {
- suppressRepeated = Context.getConfig().getInteger("event.suppressRepeated", 60);
- }
+ private static final double SPEED_THRESHOLD = 0.01;
@Override
protected Collection<Event> analyzePosition(Position position) {
@@ -42,40 +35,23 @@ public class MotionEventHandler extends BaseEventHandler {
if (device == null) {
return null;
}
- if (position.getId() != device.getPositionId() || !position.getValid()) {
+ if (!Context.getDeviceManager().isLatestPosition(position) || !position.getValid()) {
return null;
}
Collection<Event> result = null;
double speed = position.getSpeed();
- boolean valid = position.getValid();
- String motion = device.getMotion();
- if (motion == null) {
- motion = Device.STATUS_STOPPED;
+ double oldSpeed = 0;
+ Position lastPosition = Context.getDeviceManager().getLastPosition(position.getDeviceId());
+ if (lastPosition != null) {
+ oldSpeed = lastPosition.getSpeed();
}
- 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(),
- event.getType(), suppressRepeated).isEmpty()) {
- event = null;
- }
- }
- }
- } catch (SQLException error) {
- Log.warning(error);
+ if (speed > SPEED_THRESHOLD && oldSpeed <= SPEED_THRESHOLD) {
+ result = new ArrayList<>();
+ result.add(new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId()));
+ } else if (speed <= SPEED_THRESHOLD && oldSpeed > SPEED_THRESHOLD) {
+ result = new ArrayList<>();
+ result.add(new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId()));
}
return result;
}
diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java
index fd005e170..dbdb01ffb 100644
--- a/src/org/traccar/events/OverspeedEventHandler.java
+++ b/src/org/traccar/events/OverspeedEventHandler.java
@@ -15,7 +15,6 @@
*/
package org.traccar.events;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
@@ -24,17 +23,16 @@ import org.traccar.Context;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
-import org.traccar.helper.Log;
import org.traccar.helper.UnitsConverter;
public class OverspeedEventHandler extends BaseEventHandler {
- private double globalSpeedLimit;
- private int suppressRepeated;
+ public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit";
+
+ private boolean notRepeat;
public OverspeedEventHandler() {
- globalSpeedLimit = UnitsConverter.knotsFromKph(Context.getConfig().getInteger("event.globalSpeedLimit", 0));
- suppressRepeated = Context.getConfig().getInteger("event.suppressRepeated", 60);
+ notRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat");
}
@Override
@@ -44,24 +42,30 @@ public class OverspeedEventHandler extends BaseEventHandler {
if (device == null) {
return null;
}
- if (position.getId() != device.getPositionId() || !position.getValid()) {
+ if (!Context.getDeviceManager().isLatestPosition(position) || !position.getValid()) {
return null;
}
Collection<Event> events = new ArrayList<>();
double speed = position.getSpeed();
- boolean valid = position.getValid();
-
- if (valid && globalSpeedLimit != 0 && speed > globalSpeedLimit) {
- try {
- if (Context.getDataManager().getLastEvents(
- position.getDeviceId(), Event.TYPE_DEVICE_OVERSPEED, suppressRepeated).isEmpty()) {
- events.add(new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()));
- }
- } catch (SQLException error) {
- Log.warning(error);
+ double speedLimit = 0;
+ String speedLimitAttribute = Context.getDeviceManager().lookupAttribute(device.getId(), ATTRIBUTE_SPEED_LIMIT);
+ if (speedLimitAttribute != null) {
+ speedLimit = Double.parseDouble(speedLimitAttribute);
+ }
+ if (speedLimit == 0) {
+ return null;
+ }
+ double oldSpeed = 0;
+ if (notRepeat) {
+ Position lastPosition = Context.getDeviceManager().getLastPosition(position.getDeviceId());
+ if (lastPosition != null) {
+ oldSpeed = lastPosition.getSpeed();
}
-
+ }
+ speedLimit = UnitsConverter.knotsFromKph(speedLimit);
+ if (speed > speedLimit && oldSpeed <= speedLimit) {
+ events.add(new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()));
}
return events;
}
diff --git a/src/org/traccar/model/Device.java b/src/org/traccar/model/Device.java
index 1669aee31..e90742836 100644
--- a/src/org/traccar/model/Device.java
+++ b/src/org/traccar/model/Device.java
@@ -92,19 +92,6 @@ public class Device extends Extensible {
this.groupId = groupId;
}
- public static final String STATUS_MOVING = "moving";
- public static final String STATUS_STOPPED = "stopped";
-
- private String motion;
-
- public String getMotion() {
- return motion;
- }
-
- public void setMotion(String motion) {
- this.motion = motion;
- }
-
private List<Long> geofenceIds;
public List<Long> getGeofenceIds() {
diff --git a/src/org/traccar/model/Group.java b/src/org/traccar/model/Group.java
index 00f2b2cfc..e70b3f3d5 100644
--- a/src/org/traccar/model/Group.java
+++ b/src/org/traccar/model/Group.java
@@ -15,17 +15,7 @@
*/
package org.traccar.model;
-public class Group {
-
- private long id;
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
+public class Group extends Extensible {
private String name;
diff --git a/src/org/traccar/model/Server.java b/src/org/traccar/model/Server.java
index 270fd61fa..b1557bf8f 100644
--- a/src/org/traccar/model/Server.java
+++ b/src/org/traccar/model/Server.java
@@ -15,17 +15,7 @@
*/
package org.traccar.model;
-public class Server {
-
- private long id;
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
+public class Server extends Extensible {
private boolean registration;
diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java
index 83ed4b099..bb18a68e2 100644
--- a/src/org/traccar/protocol/H02ProtocolDecoder.java
+++ b/src/org/traccar/protocol/H02ProtocolDecoder.java
@@ -80,7 +80,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
}
}
- position.set(Position.KEY_IGNITION, !BitUtil.check(status, 10));
+ position.set(Position.KEY_IGNITION, BitUtil.check(status, 10));
position.set(Position.KEY_STATUS, status);
}
diff --git a/src/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/org/traccar/protocol/HuaShengProtocolDecoder.java
index 6901f37fb..e7c83d3b3 100644
--- a/src/org/traccar/protocol/HuaShengProtocolDecoder.java
+++ b/src/org/traccar/protocol/HuaShengProtocolDecoder.java
@@ -38,7 +38,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_LOGIN = 0xAA02;
public static final int MSG_LOGIN_RSP = 0xFF03;
- private static void sendResponse(Channel channel, int type, ChannelBuffer content) {
+ private static void sendResponse(Channel channel, int type, int index, ChannelBuffer content) {
if (channel != null) {
ChannelBuffer response = ChannelBuffers.dynamicBuffer();
response.writeByte(0xC0);
@@ -46,7 +46,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
response.writeShort(12 + content.readableBytes());
response.writeShort(type);
response.writeShort(0);
- response.writeInt(1);
+ response.writeInt(index);
response.writeBytes(content);
response.writeByte(0xC0);
channel.write(response);
@@ -80,7 +80,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession != null && channel != null) {
ChannelBuffer content = ChannelBuffers.dynamicBuffer();
content.writeByte(0); // success
- sendResponse(channel, MSG_LOGIN_RSP, content);
+ sendResponse(channel, MSG_LOGIN_RSP, index, content);
}
} else {
buf.skipBytes(length);
@@ -127,9 +127,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(length);
}
- ChannelBuffer content = ChannelBuffers.dynamicBuffer();
- content.writeInt(index);
- sendResponse(channel, MSG_POSITION_RSP, content);
+ sendResponse(channel, MSG_POSITION_RSP, index, ChannelBuffers.dynamicBuffer());
return position;
diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java
index f46511b27..c5884a4d0 100644
--- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java
+++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java
@@ -17,7 +17,9 @@ package org.traccar.protocol;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
+import org.jboss.netty.handler.codec.http.HttpHeaders;
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.QueryStringDecoder;
@@ -40,6 +42,14 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ 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, 0);
+ channel.write(response);
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -63,10 +73,7 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder {
case "deviceid":
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value);
if (deviceSession == null) {
- if (channel != null) {
- channel.write(
- new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
- }
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
return null;
}
position.setDeviceId(deviceSession.getDeviceId());
@@ -123,11 +130,14 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder {
position.setTime(new Date());
}
- if (channel != null) {
- channel.write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK));
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession != null) {
+ sendResponse(channel, HttpResponseStatus.OK);
+ return position;
+ } else {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
}
-
- return position;
}
}
diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java
index 34efc376f..1909d9bea 100644
--- a/src/org/traccar/protocol/T55ProtocolDecoder.java
+++ b/src/org/traccar/protocol/T55ProtocolDecoder.java
@@ -50,7 +50,9 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
.expression("[^,]+")
.number(",(d+)") // satellites
.number(",(d+)") // imei
- .number(",(d+)").optional(3)
+ .number(",([01])") // ignition
+ .number(",(d+)") // fuel
+ .number(",(d+)").optional(5) // battery
.any()
.compile();
@@ -123,13 +125,18 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
position.setTime(dateBuilder.getDate());
- if (parser.hasNext(3)) {
+ if (parser.hasNext(5)) {
position.set(Position.KEY_SATELLITES, parser.next());
+
deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
return null;
}
position.setDeviceId(deviceSession.getDeviceId());
+
+ position.set(Position.KEY_IGNITION, parser.hasNext() && parser.next().equals("1"));
+ position.set(Position.KEY_FUEL, parser.nextInt());
+ position.set(Position.KEY_BATTERY, parser.nextInt());
}
if (deviceSession != null) {
diff --git a/swagger.json b/swagger.json
index a16794a41..8b4157917 100644
--- a/swagger.json
+++ b/swagger.json
@@ -1235,7 +1235,8 @@
},
"twelveHourFormat": {
"type": "boolean"
- }
+ },
+ "attributes": {}
}
},
"Command": {
@@ -1286,7 +1287,8 @@
},
"groupId": {
"type": "integer"
- }
+ },
+ "attributes": {}
}
},
"DevicePermission": {
diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
index 925e90dd6..c1e913415 100644
--- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
@@ -14,6 +14,9 @@ public class EelinkProtocolDecoderTest extends ProtocolTest {
"676701000c007b03525440717505180104"));
verifyPosition(decoder, binary(
+ "676712001e0092579714d60201f90001785003a301cd1a006a118504f2000000000000"));
+
+ verifyPosition(decoder, binary(
"676712003400505784cc0b130246479b07d05a06001800000000070195039f046100002cc52e6466b391604a4900890e7c00000000000006ca"));
verifyPosition(decoder, binary(
diff --git a/test/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/test/org/traccar/protocol/HuaShengProtocolDecoderTest.java
index 083397c77..7cb6b65a0 100644
--- a/test/org/traccar/protocol/HuaShengProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/HuaShengProtocolDecoderTest.java
@@ -13,8 +13,8 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest {
verifyNothing(decoder, binary(
"c000000077aa0200000000000e000100143347315f48312e315f56312e30372e54000300133335353835353035303434303635380004000b3531323030303000050005010006000400070004000800050000090018383936313032353431343533333239313833360d000a000f796573696e7465726e6574c0"));
- //verifyPosition(decoder, binary(
- // "c00000003faa0000000000003ba5a5005a3f00dbdc00000031363037303530373132353700e6d186ffcc7a25002201160010000000010015000000000000000000c0"));
+ verifyPosition(decoder, binary(
+ "c00000004baa00000000000005c400000131363037303630323537303800e6c82effcc7cb0003900a30089000000010015000000000000000000f20559ff577ce3980005000a060500000087c0"));
verifyNothing(decoder, binary(
"c0010c003e0002000000000010020012a0014f42445f3347315f56312e302e330013a0043335353835353035303434303635380006a08701000006a0a1035fc0"));
diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
index 2b86bc149..57700d36a 100644
--- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class MegastekProtocolDecoderTest extends ProtocolTest {
MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol());
verifyPosition(decoder, text(
+ "STX,013950007137061,$GPRMC,191959.000,A,5203.09602,N,00830.77057,E,5.73,255.27,240716,,,A*62,L,Belt Up,imei:013950007137061,0/5,,Battery=52%,,1,262,03,0084,B20E;FD"));
+
+ verifyPosition(decoder, text(
"STX,865067021328417,$GPRMC,064721.000,A,4241.2793,N,02321.9762,E,6.74,346.90,300316,,,1*CA,F,Nil-Alarms,imei:865067021328417,9,559.8,Battery=82%,0,284,03,047E,2B5F;99"));
verifyNothing(decoder, text(
diff --git a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java
index d035ba7ef..6ec885058 100644
--- a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java
@@ -10,6 +10,9 @@ public class OsmAndProtocolDecoderTest extends ProtocolTest {
OsmAndProtocolDecoder decoder = new OsmAndProtocolDecoder(new OsmAndProtocol());
+ verifyNothing(decoder, request(
+ "/?timestamp=1377177267&lat=60.0&lon=30.0"));
+
verifyPosition(decoder, request(
"/?id=902064&lat=42.06288&lon=-88.23412&timestamp=2016-01-27T18%3A55%3A47Z&hdop=6.0&altitude=224.0&speed=0.0"));
diff --git a/test/org/traccar/protocol/T55ProtocolDecoderTest.java b/test/org/traccar/protocol/T55ProtocolDecoderTest.java
index 753b4f689..4cc5f549a 100644
--- a/test/org/traccar/protocol/T55ProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/T55ProtocolDecoderTest.java
@@ -23,7 +23,7 @@ public class T55ProtocolDecoderTest extends ProtocolTest {
"4711/022789000688081/$GPRMC,133343,A,5308.56325,N,1029.12850,E,0.000000,0.000000,290316,,*2A"));
verifyPosition(decoder, text(
- "$GPRMC,073501.000,A,1255.5125,N,07738.2948,E,0.00,0.53,080316,,,D*73,12,865733027593268,10011"));
+ "$GPRMC,073446.000,A,1255.5125,N,07738.2948,E,0.00,0.53,080316,D*71,11,865733027593268,1,090,086"));
verifyNothing(decoder, text(
"$GPFID,ID123456ABC"));
diff --git a/web/app.css b/web/app.css
index 0dbf94ca6..95417606c 100644
--- a/web/app.css
+++ b/web/app.css
@@ -1,10 +1,10 @@
-.status-color-online {
+.view-color-green {
background-color: rgba(77, 250, 144, 0.3);
}
-.status-color-unknown {
+.view-color-yellow {
background-color: rgba(250, 190, 77, 0.3);
}
-.status-color-offline {
+.view-color-red {
background-color: rgba(255, 84, 104, 0.3);
}
diff --git a/web/app/AttributeFormatter.js b/web/app/AttributeFormatter.js
index c32849101..3432ca1e0 100644
--- a/web/app/AttributeFormatter.js
+++ b/web/app/AttributeFormatter.js
@@ -34,24 +34,6 @@ Ext.define('Traccar.AttributeFormatter', {
return Ext.getStore('DistanceUnits').formatValue(value, Traccar.app.getPreference('distanceUnit'));
},
- alarmFormatter: function (attributes) {
- var value = '';
- if (attributes instanceof Object) {//for Traccar.view.Attributes
- if (attributes.hasOwnProperty('alarm')) {
- value = attributes.alarm;
- if (typeof value === 'boolean') {
- value = (value ? Ext.Msg.buttonText.yes : Ext.Msg.buttonText.no);
- }
- }
- } else {//for Traccar.view.Report
- value = attributes;
- if (typeof value === 'boolean') {
- value = (value ? Ext.Msg.buttonText.yes : Ext.Msg.buttonText.no);
- }
- }
- return '<span style="color:red;">' + value + '</span>';
- },
-
defaultFormatter: function (value) {
if (typeof value === 'number') {
return Number(value.toFixed(Traccar.Style.numberPrecision));
@@ -76,8 +58,6 @@ Ext.define('Traccar.AttributeFormatter', {
return this.courseFormatter;
} else if (key === 'distance' || key === 'odometer') {
return this.distanceFormatter;
- } else if (key === 'alarm') {
- return this.alarmFormatter;
} else {
return this.defaultFormatter;
}
diff --git a/web/app/controller/Root.js b/web/app/controller/Root.js
index 7070c48b0..2c565747b 100644
--- a/web/app/controller/Root.js
+++ b/web/app/controller/Root.js
@@ -100,7 +100,7 @@ Ext.define('Traccar.controller.Root', {
},
mutePressed: function () {
- var muteButton = Ext.getCmp('nuteButton');
+ var muteButton = Ext.getCmp('muteButton');
return muteButton && !muteButton.pressed;
},
diff --git a/web/app/model/Group.js b/web/app/model/Group.js
index a28897feb..bb18b5b3f 100644
--- a/web/app/model/Group.js
+++ b/web/app/model/Group.js
@@ -27,5 +27,7 @@ Ext.define('Traccar.model.Group', {
}, {
name: 'groupId',
type: 'int'
+ }, {
+ name: 'attributes'
}]
});
diff --git a/web/app/model/Server.js b/web/app/model/Server.js
index 3f6e466d9..02968c2d6 100644
--- a/web/app/model/Server.js
+++ b/web/app/model/Server.js
@@ -54,6 +54,8 @@ Ext.define('Traccar.model.Server', {
}, {
name: 'twelveHourFormat',
type: 'boolean'
+ }, {
+ name: 'attributes'
}],
proxy: {
diff --git a/web/app/view/DeviceDialogController.js b/web/app/view/AttributeController.js
index 0a0f86883..932a6436b 100644
--- a/web/app/view/DeviceDialogController.js
+++ b/web/app/view/AttributeController.js
@@ -14,25 +14,29 @@
* limitations under the License.
*/
-Ext.define('Traccar.view.DeviceDialogController', {
- extend: 'Traccar.view.BaseEditDialogController',
- alias: 'controller.deviceDialog',
+Ext.define('Traccar.view.AttributeController', {
+ extend: 'Ext.app.ViewController',
+ alias: 'controller.attributeDialog',
- requires: [
- 'Traccar.view.Attributes'
- ],
-
- showAttributesView: function (button) {
- var dialog, record;
+ onSaveClick: function (button) {
+ var dialog, store, record;
dialog = button.up('window').down('form');
+ dialog.updateRecord();
record = dialog.getRecord();
- Ext.create('Traccar.view.BaseWindow', {
- title: Strings.sharedAttributes,
- modal: false,
- items: {
- xtype: 'attributesView',
- record: record
+ store = record.store;
+ if (store) {
+ if (record.phantom) {
+ store.add(record);
}
- }).show();
+ store.sync({
+ failure: function (batch) {
+ store.rejectChanges();
+ Traccar.app.showError(batch.exceptions[0].getError().response);
+ }
+ });
+ } else {
+ record.save();
+ }
+ button.up('window').close();
}
});
diff --git a/web/app/view/AttributeDialog.js b/web/app/view/AttributeDialog.js
index be06b7576..213891ecd 100644
--- a/web/app/view/AttributeDialog.js
+++ b/web/app/view/AttributeDialog.js
@@ -15,13 +15,13 @@
*/
Ext.define('Traccar.view.AttributeDialog', {
- extend: 'Traccar.view.BaseEditDialog',
+ extend: 'Traccar.view.BaseDialog',
requires: [
- 'Traccar.view.BaseEditDialogController'
+ 'Traccar.view.AttributeController'
],
- controller: 'baseEditDialog',
+ controller: 'attributeDialog',
title: Strings.sharedAttribute,
items: {
@@ -35,5 +35,13 @@ Ext.define('Traccar.view.AttributeDialog', {
name: 'value',
fieldLabel: Strings.stateValue
}]
- }
+ },
+
+ buttons: [{
+ text: Strings.sharedSave,
+ handler: 'onSaveClick'
+ }, {
+ text: Strings.sharedCancel,
+ handler: 'closeView'
+ }]
});
diff --git a/web/app/view/BaseEditDialog.js b/web/app/view/BaseEditDialog.js
index 051dfbe93..1af095c98 100644
--- a/web/app/view/BaseEditDialog.js
+++ b/web/app/view/BaseEditDialog.js
@@ -18,6 +18,11 @@ Ext.define('Traccar.view.BaseEditDialog', {
extend: 'Traccar.view.BaseDialog',
buttons: [{
+ text: Strings.sharedAttributes,
+ handler: 'showAttributesView'
+ }, {
+ xtype: 'tbfill'
+ }, {
text: Strings.sharedSave,
handler: 'onSaveClick'
}, {
diff --git a/web/app/view/BaseEditDialogController.js b/web/app/view/BaseEditDialogController.js
index 33bd01bd8..79fd8f2b4 100644
--- a/web/app/view/BaseEditDialogController.js
+++ b/web/app/view/BaseEditDialogController.js
@@ -18,6 +18,10 @@ Ext.define('Traccar.view.BaseEditDialogController', {
extend: 'Ext.app.ViewController',
alias: 'controller.baseEditDialog',
+ requires: [
+ 'Traccar.view.Attributes'
+ ],
+
onSaveClick: function (button) {
var dialog, store, record;
dialog = button.up('window').down('form');
@@ -38,5 +42,19 @@ Ext.define('Traccar.view.BaseEditDialogController', {
record.save();
}
button.up('window').close();
+ },
+
+ showAttributesView: function (button) {
+ var dialog, record;
+ dialog = button.up('window').down('form');
+ record = dialog.getRecord();
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.sharedAttributes,
+ modal: false,
+ items: {
+ xtype: 'attributesView',
+ record: record
+ }
+ }).show();
}
});
diff --git a/web/app/view/DeviceDialog.js b/web/app/view/DeviceDialog.js
index 2938d5dc3..e88618fc5 100644
--- a/web/app/view/DeviceDialog.js
+++ b/web/app/view/DeviceDialog.js
@@ -18,10 +18,10 @@ Ext.define('Traccar.view.DeviceDialog', {
extend: 'Traccar.view.BaseEditDialog',
requires: [
- 'Traccar.view.DeviceDialogController'
+ 'Traccar.view.BaseEditDialog'
],
- controller: 'deviceDialog',
+ controller: 'baseEditDialog',
title: Strings.deviceDialog,
items: {
@@ -45,18 +45,5 @@ Ext.define('Traccar.view.DeviceDialog', {
displayField: 'name',
valueField: 'id'
}]
- },
-
- buttons: [{
- text : Strings.sharedAttributes,
- handler: 'showAttributesView'
- }, {
- xtype: 'tbfill'
- }, {
- text: Strings.sharedSave,
- handler: 'onSaveClick'
- }, {
- text: Strings.sharedCancel,
- handler: 'closeView'
- }]
+ }
});
diff --git a/web/app/view/Devices.js b/web/app/view/Devices.js
index da7695229..ab6436ea6 100644
--- a/web/app/view/Devices.js
+++ b/web/app/view/Devices.js
@@ -57,10 +57,10 @@ Ext.define('Traccar.view.Devices', {
tooltipType: 'title'
}, {
xtype: 'tbfill'
- },{
- id: 'nuteButton',
+ }, {
+ id: 'muteButton',
glyph: 'xf1f7@FontAwesome',
- tooltip: Strings.muteButton,
+ tooltip: Strings.sharedMute,
tooltipType: 'title',
pressed : true,
enableToggle: true,
@@ -156,13 +156,13 @@ Ext.define('Traccar.view.Devices', {
renderer: function (value, metaData, record) {
switch (record.get('status')) {
case 'online':
- metaData.tdCls = 'status-color-online';
+ metaData.tdCls = 'view-color-green';
break;
case 'offline':
- metaData.tdCls = 'status-color-offline';
+ metaData.tdCls = 'view-color-red';
break;
default:
- metaData.tdCls = 'status-color-unknown';
+ metaData.tdCls = 'view-color-yellow';
break;
}
if (Traccar.app.getPreference('twelveHourFormat', false)) {
diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js
index eee74099f..6ef9f91e6 100644
--- a/web/app/view/MapController.js
+++ b/web/app/view/MapController.js
@@ -147,37 +147,39 @@ Ext.define('Traccar.view.MapController', {
this.clearReport(store);
- this.reportRoute = new ol.Feature({
- geometry: new ol.geom.LineString([])
- });
- this.reportRoute.setStyle(this.getRouteStyle());
- this.getView().getRouteSource().addFeature(this.reportRoute);
+ if (data.length > 0) {
+ this.reportRoute = new ol.Feature({
+ geometry: new ol.geom.LineString([])
+ });
+ this.reportRoute.setStyle(this.getRouteStyle());
+ this.getView().getRouteSource().addFeature(this.reportRoute);
- for (i = 0; i < data.length; i++) {
- position = data[i];
+ for (i = 0; i < data.length; i++) {
+ position = data[i];
+
+ point = ol.proj.fromLonLat([
+ position.get('longitude'),
+ position.get('latitude')
+ ]);
+ geometry = new ol.geom.Point(point);
- point = ol.proj.fromLonLat([
- position.get('longitude'),
- position.get('latitude')
- ]);
- geometry = new ol.geom.Point(point);
+ marker = new ol.Feature(geometry);
+ marker.set('record', position);
+ this.reportMarkers[position.get('id')] = marker;
+ this.getView().getReportSource().addFeature(marker);
- marker = new ol.Feature(geometry);
- marker.set('record', position);
- this.reportMarkers[position.get('id')] = marker;
- this.getView().getReportSource().addFeature(marker);
+ style = this.getReportMarker();
+ style.getImage().setRotation(position.get('course') * Math.PI / 180);
+ /*style.getText().setText(
+ Ext.Date.format(position.get('fixTime'), Traccar.Style.dateTimeFormat24));*/
- style = this.getReportMarker();
- style.getImage().setRotation(position.get('course') * Math.PI / 180);
- /*style.getText().setText(
- Ext.Date.format(position.get('fixTime'), Traccar.Style.dateTimeFormat24));*/
+ marker.setStyle(style);
- marker.setStyle(style);
+ this.reportRoute.getGeometry().appendCoordinate(point);
+ }
- this.reportRoute.getGeometry().appendCoordinate(point);
+ this.getView().getMapView().fit(this.reportRoute.getGeometry(), this.getView().getMap().getSize());
}
-
- this.getView().getMapView().fit(this.reportRoute.getGeometry(), this.getView().getMap().getSize());
},
clearReport: function (store) {
diff --git a/web/app/view/Report.js b/web/app/view/Report.js
index 78ff5d52f..4261b9040 100644
--- a/web/app/view/Report.js
+++ b/web/app/view/Report.js
@@ -115,10 +115,5 @@ Ext.define('Traccar.view.Report', {
dataIndex: 'address',
flex: 1,
renderer: Traccar.AttributeFormatter.getFormatter('address')
- }, {
- text: 'Alarm',
- dataIndex: 'attributes',
- flex: 1,
- renderer: Traccar.AttributeFormatter.getFormatter('alarm')
}]
});
diff --git a/web/app/view/ServerDialog.js b/web/app/view/ServerDialog.js
index 67f3a7ab2..1af000042 100644
--- a/web/app/view/ServerDialog.js
+++ b/web/app/view/ServerDialog.js
@@ -31,7 +31,7 @@ Ext.define('Traccar.view.ServerDialog', {
name: 'registration',
fieldLabel: Strings.serverRegistration,
allowBlank: false
- },{
+ }, {
xtype: 'checkboxfield',
name: 'readonly',
fieldLabel: Strings.serverReadonly,
diff --git a/web/app/view/State.js b/web/app/view/State.js
index 1a9f014f5..547fb0cf3 100644
--- a/web/app/view/State.js
+++ b/web/app/view/State.js
@@ -34,6 +34,12 @@ Ext.define('Traccar.view.State', {
}, {
text: Strings.stateValue,
dataIndex: 'value',
- flex: 1
+ flex: 1,
+ renderer: function (value, metaData, record) {
+ if (record.get('name') === 'Alarm') {
+ metaData.tdCls = 'view-color-red';
+ }
+ return value;
+ }
}]
});
diff --git a/web/app/view/UserDialog.js b/web/app/view/UserDialog.js
index 378cc0681..df8a26e7e 100644
--- a/web/app/view/UserDialog.js
+++ b/web/app/view/UserDialog.js
@@ -89,18 +89,5 @@ Ext.define('Traccar.view.UserDialog', {
fieldLabel: Strings.settingsTwelveHourFormat,
allowBlank: false
}]
- }],
-
- buttons: [{
- text : Strings.sharedAttributes,
- handler: 'showAttributesView'
- }, {
- xtype: 'tbfill'
- }, {
- text: Strings.sharedSave,
- handler: 'onSaveClick'
- }, {
- text: Strings.sharedCancel,
- handler: 'closeView'
}]
});
diff --git a/web/app/view/UserDialogController.js b/web/app/view/UserDialogController.js
index 49dfd9d70..c3a4ca62d 100644
--- a/web/app/view/UserDialogController.js
+++ b/web/app/view/UserDialogController.js
@@ -15,13 +15,9 @@
*/
Ext.define('Traccar.view.UserDialogController', {
- extend: 'Ext.app.ViewController',
+ extend: 'Traccar.view.BaseEditDialogController',
alias: 'controller.userDialog',
- requires: [
- 'Traccar.view.Attributes'
- ],
-
init: function () {
if (Traccar.app.getUser().get('admin')) {
this.lookupReference('adminField').setDisabled(false);
@@ -48,19 +44,5 @@ Ext.define('Traccar.view.UserDialogController', {
});
}
button.up('window').close();
- },
-
- showAttributesView: function (button) {
- var dialog, record;
- dialog = button.up('window').down('form');
- record = dialog.getRecord();
- Ext.create('Traccar.view.BaseWindow', {
- title: Strings.sharedAttributes,
- modal: false,
- items: {
- xtype: 'attributesView',
- record: record
- }
- }).show();
}
});
diff --git a/web/l10n/en.json b/web/l10n/en.json
index 32a2a45a4..e1866fe62 100644
--- a/web/l10n/en.json
+++ b/web/l10n/en.json
@@ -19,11 +19,11 @@
"sharedSearch": "Search",
"sharedGeofence": "Geofence",
"sharedGeofences": "Geofences",
- "muteButton": "Mute",
"sharedNotifications": "Notifications",
"sharedAttributes": "Attributes",
"sharedAttribute": "Attribute",
"sharedArea": "Area",
+ "sharedMute": "Mute",
"errorTitle": "Error",
"errorUnknown": "Unknown error",
"errorConnection": "Connection error",