diff options
author | ninioe <ninioe@gmail.com> | 2016-08-01 16:12:47 +0300 |
---|---|---|
committer | ninioe <ninioe@gmail.com> | 2016-08-01 16:12:47 +0300 |
commit | 94781fa3ba35e494e309aee19a5e15c14d3193c1 (patch) | |
tree | a1e4a90e9a2fce3db8bc51981aeb8a23cced5e6d | |
parent | b4841fa0a6293c0b895cf6bb65c6c2d871c78397 (diff) | |
parent | e177e7d083a4dd3f64172802661bf658d26d1163 (diff) | |
download | traccar-server-94781fa3ba35e494e309aee19a5e15c14d3193c1.tar.gz traccar-server-94781fa3ba35e494e309aee19a5e15c14d3193c1.tar.bz2 traccar-server-94781fa3ba35e494e309aee19a5e15c14d3193c1.zip |
Merge remote-tracking branch 'refs/remotes/tananaev/master'
46 files changed, 302 insertions, 325 deletions
@@ -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 < :serverTime; + <entry key='database.deletePositions'> + DELETE FROM positions WHERE serverTime < :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×tamp=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", |