aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-07-14 21:19:53 +1200
committerGitHub <noreply@github.com>2017-07-14 21:19:53 +1200
commit26f1cf12867d6f8bfe86d562a3beecb590b3a9b5 (patch)
treeef3b8d2644aae5c5263241640ebb2e2b251f7b0c
parenta2e1f56adf50746425565557dd38f0e2c81a0222 (diff)
parentb6a318daabbaf485e327cab77adba98413462516 (diff)
downloadtrackermap-server-26f1cf12867d6f8bfe86d562a3beecb590b3a9b5.tar.gz
trackermap-server-26f1cf12867d6f8bfe86d562a3beecb590b3a9b5.tar.bz2
trackermap-server-26f1cf12867d6f8bfe86d562a3beecb590b3a9b5.zip
Merge pull request #3349 from Abyss777/drivers
Drivers implementation
-rw-r--r--schema/changelog-3.14.xml65
-rw-r--r--schema/changelog-master.xml1
-rw-r--r--setup/default.xml57
-rw-r--r--src/org/traccar/BasePipelineFactory.java7
-rw-r--r--src/org/traccar/Context.java9
-rw-r--r--src/org/traccar/api/resource/DeviceDriverResource.java58
-rw-r--r--src/org/traccar/api/resource/DriverPermissionResource.java59
-rw-r--r--src/org/traccar/api/resource/DriverResource.java112
-rw-r--r--src/org/traccar/api/resource/GroupDriverResource.java58
-rw-r--r--src/org/traccar/database/DataManager.java84
-rw-r--r--src/org/traccar/database/DriversManager.java213
-rw-r--r--src/org/traccar/database/PermissionsManager.java13
-rw-r--r--src/org/traccar/events/DriverEventHandler.java50
-rw-r--r--src/org/traccar/model/DeviceDriver.java41
-rw-r--r--src/org/traccar/model/Driver.java40
-rw-r--r--src/org/traccar/model/DriverPermission.java40
-rw-r--r--src/org/traccar/model/Event.java2
-rw-r--r--src/org/traccar/model/GroupDriver.java41
-rw-r--r--src/org/traccar/model/Position.java3
-rw-r--r--src/org/traccar/notification/NotificationFormatter.java7
-rw-r--r--src/org/traccar/processing/CopyAttributesHandler.java9
-rw-r--r--src/org/traccar/protocol/AplicomProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AstraProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/AtrackProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/FifotrackProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/Gl200ProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/GnxProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/Gps103ProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/MegastekProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java4
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/MxtProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/OsmAndProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Pt502ProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/StarLinkProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/Stl060ProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/TeltonikaProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/TmgProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/UlbotechProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/VisiontekProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/WialonProtocolDecoder.java2
-rw-r--r--src/org/traccar/reports/ReportUtils.java23
-rw-r--r--src/org/traccar/reports/model/TripReport.java20
-rw-r--r--templates/export/trips.xlsxbin13189 -> 13239 bytes
-rw-r--r--templates/mail/driverChanged.vm10
-rw-r--r--templates/sms/driverChanged.vm6
-rw-r--r--test/org/traccar/ProtocolTest.java4
-rwxr-xr-xtools/test-generator.py8
48 files changed, 1060 insertions, 25 deletions
diff --git a/schema/changelog-3.14.xml b/schema/changelog-3.14.xml
new file mode 100644
index 000000000..7965bc020
--- /dev/null
+++ b/schema/changelog-3.14.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<databaseChangeLog
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"
+ logicalFilePath="changelog-3.14">
+
+ <changeSet author="author" id="changelog-3.14">
+
+ <createTable tableName="drivers">
+ <column name="id" type="INT" autoIncrement="true">
+ <constraints primaryKey="true" />
+ </column>
+ <column name="name" type="VARCHAR(128)">
+ <constraints nullable="false" />
+ </column>
+ <column name="uniqueid" type="VARCHAR(128)">
+ <constraints nullable="false" />
+ </column>
+ <column name="attributes" type="VARCHAR(4000)">
+ <constraints nullable="false" />
+ </column>
+ </createTable>
+
+ <addUniqueConstraint tableName="drivers" columnNames="uniqueid" constraintName="uk_driver_uniqueid" />
+
+ <createTable tableName="user_driver">
+ <column name="userid" type="INT">
+ <constraints nullable="false" />
+ </column>
+ <column name="driverid" type="INT">
+ <constraints nullable="false" />
+ </column>
+ </createTable>
+
+ <addForeignKeyConstraint baseTableName="user_driver" baseColumnNames="userid" constraintName="fk_user_driver_userid" referencedTableName="users" referencedColumnNames="id" onDelete="CASCADE" />
+ <addForeignKeyConstraint baseTableName="user_driver" baseColumnNames="driverid" constraintName="fk_user_driver_driverid" referencedTableName="drivers" referencedColumnNames="id" onDelete="CASCADE" />
+
+ <createTable tableName="group_driver">
+ <column name="groupid" type="INT">
+ <constraints nullable="false" />
+ </column>
+ <column name="driverid" type="INT">
+ <constraints nullable="false" />
+ </column>
+ </createTable>
+
+ <addForeignKeyConstraint baseTableName="group_driver" baseColumnNames="groupid" constraintName="fk_group_driver_groupid" referencedTableName="groups" referencedColumnNames="id" onDelete="CASCADE" />
+ <addForeignKeyConstraint baseTableName="group_driver" baseColumnNames="driverid" constraintName="fk_group_driver_driverid" referencedTableName="drivers" referencedColumnNames="id" onDelete="CASCADE" />
+
+ <createTable tableName="device_driver">
+ <column name="deviceid" type="INT">
+ <constraints nullable="false" />
+ </column>
+ <column name="driverid" type="INT">
+ <constraints nullable="false" />
+ </column>
+ </createTable>
+
+ <addForeignKeyConstraint baseTableName="device_driver" baseColumnNames="deviceid" constraintName="fk_device_driver_deviceid" referencedTableName="devices" referencedColumnNames="id" onDelete="CASCADE" />
+ <addForeignKeyConstraint baseTableName="device_driver" baseColumnNames="driverid" constraintName="fk_device_driver_driverid" referencedTableName="drivers" referencedColumnNames="id" onDelete="CASCADE" />
+
+ </changeSet>
+</databaseChangeLog> \ No newline at end of file
diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml
index ba93d105f..d1b51b40e 100644
--- a/schema/changelog-master.xml
+++ b/schema/changelog-master.xml
@@ -14,4 +14,5 @@
<include file="changelog-3.10.xml" relativeToChangelogFile="true" />
<include file="changelog-3.11.xml" relativeToChangelogFile="true" />
<include file="changelog-3.12.xml" relativeToChangelogFile="true" />
+ <include file="changelog-3.14.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
diff --git a/setup/default.xml b/setup/default.xml
index 2fc6c3cf0..04530104a 100644
--- a/setup/default.xml
+++ b/setup/default.xml
@@ -431,6 +431,63 @@
DELETE FROM device_attribute WHERE deviceId = :deviceId AND attributeId = :attributeId
</entry>
+ <entry key='database.selectDrivers'>
+ SELECT * FROM drivers
+ </entry>
+
+ <entry key='database.insertDriver'>
+ INSERT INTO drivers (name, uniqueId, attributes)
+ VALUES (:name, :uniqueId, :attributes)
+ </entry>
+
+ <entry key='database.updateDriver'>
+ UPDATE drivers SET
+ name = :name,
+ uniqueId = :uniqueId,
+ attributes = :attributes
+ WHERE id = :id
+ </entry>
+
+ <entry key='database.deleteDriver'>
+ DELETE FROM drivers WHERE id = :id
+ </entry>
+
+ <entry key='database.selectDriverPermissions'>
+ SELECT userId, driverId FROM user_driver
+ </entry>
+
+ <entry key='database.linkDriver'>
+ INSERT INTO user_driver (userId, driverId) VALUES (:userId, :driverId)
+ </entry>
+
+ <entry key='database.unlinkDriver'>
+ DELETE FROM user_driver WHERE userId = :userId AND driverId = :driverId
+ </entry>
+
+ <entry key='database.selectGroupDrivers'>
+ SELECT groupId, driverId FROM group_driver
+ </entry>
+
+ <entry key='database.linkGroupDriver'>
+ INSERT INTO group_driver (groupId, driverId) VALUES (:groupId, :driverId)
+ </entry>
+
+ <entry key='database.unlinkGroupDriver'>
+ DELETE FROM group_driver WHERE groupId = :groupId AND driverId = :driverId
+ </entry>
+
+ <entry key='database.selectDeviceDrivers'>
+ SELECT deviceId, driverId FROM device_driver
+ </entry>
+
+ <entry key='database.linkDeviceDriver'>
+ INSERT INTO device_driver (deviceId, driverId) VALUES (:deviceId, :driverId)
+ </entry>
+
+ <entry key='database.unlinkDeviceDriver'>
+ DELETE FROM device_driver WHERE deviceId = :deviceId AND driverId = :driverId
+ </entry>
+
<!-- PROTOCOL CONFIG -->
<entry key='gps103.port'>5001</entry>
diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java
index bde4b558b..b368c800d 100644
--- a/src/org/traccar/BasePipelineFactory.java
+++ b/src/org/traccar/BasePipelineFactory.java
@@ -30,6 +30,7 @@ import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.handler.logging.LoggingHandler;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.traccar.events.CommandResultEventHandler;
+import org.traccar.events.DriverEventHandler;
import org.traccar.events.FuelDropEventHandler;
import org.traccar.events.GeofenceEventHandler;
import org.traccar.events.IgnitionEventHandler;
@@ -65,6 +66,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory {
private AlertEventHandler alertEventHandler;
private IgnitionEventHandler ignitionEventHandler;
private MaintenanceEventHandler maintenanceEventHandler;
+ private DriverEventHandler driverEventHandler;
private static final class OpenChannelHandler extends SimpleChannelHandler {
@@ -170,6 +172,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory {
alertEventHandler = new AlertEventHandler();
ignitionEventHandler = new IgnitionEventHandler();
maintenanceEventHandler = new MaintenanceEventHandler();
+ driverEventHandler = new DriverEventHandler();
}
}
@@ -263,6 +266,10 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory {
pipeline.addLast("MaintenanceEventHandler", maintenanceEventHandler);
}
+ if (driverEventHandler != null) {
+ pipeline.addLast("DriverEventHandler", driverEventHandler);
+ }
+
pipeline.addLast("mainHandler", new MainEventHandler());
return pipeline;
}
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index 9626d949c..a4fc5b679 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -31,6 +31,7 @@ import org.traccar.database.AttributesManager;
import org.traccar.database.ConnectionManager;
import org.traccar.database.DataManager;
import org.traccar.database.DeviceManager;
+import org.traccar.database.DriversManager;
import org.traccar.database.IdentityManager;
import org.traccar.database.MediaManager;
import org.traccar.database.NotificationManager;
@@ -187,6 +188,12 @@ public final class Context {
return attributesManager;
}
+ private static DriversManager driversManager;
+
+ public static DriversManager getDriversManager() {
+ return driversManager;
+ }
+
private static StatisticsManager statisticsManager;
public static StatisticsManager getStatisticsManager() {
@@ -330,6 +337,8 @@ public final class Context {
attributesManager = new AttributesManager(dataManager);
+ driversManager = new DriversManager(dataManager);
+
statisticsManager = new StatisticsManager();
if (config.getBoolean("sms.smpp.enable")) {
diff --git a/src/org/traccar/api/resource/DeviceDriverResource.java b/src/org/traccar/api/resource/DeviceDriverResource.java
new file mode 100644
index 000000000..341c50909
--- /dev/null
+++ b/src/org/traccar/api/resource/DeviceDriverResource.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.api.resource;
+
+import java.sql.SQLException;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.traccar.Context;
+import org.traccar.api.BaseResource;
+import org.traccar.model.DeviceDriver;
+
+@Path("devices/drivers")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class DeviceDriverResource extends BaseResource {
+
+ @POST
+ public Response add(DeviceDriver entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getDriverId());
+ Context.getDataManager().linkDeviceDriver(entity.getDeviceId(), entity.getDriverId());
+ Context.getDriversManager().refresh();
+ return Response.ok(entity).build();
+ }
+
+ @DELETE
+ public Response remove(DeviceDriver entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getDriverId());
+ Context.getDataManager().unlinkDeviceDriver(entity.getDeviceId(), entity.getDriverId());
+ Context.getDriversManager().refresh();
+ return Response.noContent().build();
+ }
+
+}
diff --git a/src/org/traccar/api/resource/DriverPermissionResource.java b/src/org/traccar/api/resource/DriverPermissionResource.java
new file mode 100644
index 000000000..fd1ca7c6d
--- /dev/null
+++ b/src/org/traccar/api/resource/DriverPermissionResource.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.api.resource;
+
+import java.sql.SQLException;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.traccar.Context;
+import org.traccar.api.BaseResource;
+
+import org.traccar.model.DriverPermission;
+
+@Path("permissions/drivers")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class DriverPermissionResource extends BaseResource {
+
+ @POST
+ public Response add(DriverPermission entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getDriverId());
+ Context.getDataManager().linkDriver(entity.getUserId(), entity.getDriverId());
+ Context.getDriversManager().refreshUserDrivers();
+ return Response.ok(entity).build();
+ }
+
+ @DELETE
+ public Response remove(DriverPermission entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getDriverId());
+ Context.getDataManager().unlinkDriver(entity.getUserId(), entity.getDriverId());
+ Context.getDriversManager().refreshUserDrivers();
+ return Response.noContent().build();
+ }
+
+}
diff --git a/src/org/traccar/api/resource/DriverResource.java b/src/org/traccar/api/resource/DriverResource.java
new file mode 100644
index 000000000..7fe0af473
--- /dev/null
+++ b/src/org/traccar/api/resource/DriverResource.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.api.resource;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.traccar.Context;
+import org.traccar.api.BaseResource;
+import org.traccar.database.DriversManager;
+import org.traccar.model.Driver;
+
+@Path("drivers")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class DriverResource extends BaseResource {
+
+ @GET
+ public Collection<Driver> get(
+ @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("groupId") long groupId,
+ @QueryParam("deviceId") long deviceId, @QueryParam("refresh") boolean refresh) throws SQLException {
+
+ DriversManager driversManager = Context.getDriversManager();
+ if (refresh) {
+ driversManager.refreshDrivers();
+ }
+
+ Set<Long> result = new HashSet<>();
+ if (all) {
+ if (Context.getPermissionsManager().isAdmin(getUserId())) {
+ result.addAll(driversManager.getAllDrivers());
+ } else {
+ Context.getPermissionsManager().checkManager(getUserId());
+ result.addAll(driversManager.getManagedDrivers(getUserId()));
+ }
+ } else {
+ if (userId == 0) {
+ userId = getUserId();
+ }
+ Context.getPermissionsManager().checkUser(getUserId(), userId);
+ result.addAll(driversManager.getUserDrivers(userId));
+ }
+
+ if (groupId != 0) {
+ Context.getPermissionsManager().checkGroup(getUserId(), groupId);
+ result.retainAll(driversManager.getGroupDrivers(groupId));
+ }
+
+ if (deviceId != 0) {
+ Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
+ result.retainAll(driversManager.getDeviceDrivers(deviceId));
+ }
+ return driversManager.getDrivers(result);
+
+ }
+
+ @POST
+ public Response add(Driver entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getDriversManager().addDriver(entity);
+ Context.getDataManager().linkDriver(getUserId(), entity.getId());
+ Context.getDriversManager().refreshUserDrivers();
+ return Response.ok(entity).build();
+ }
+
+ @Path("{id}")
+ @PUT
+ public Response update(Driver entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getId());
+ Context.getDriversManager().updateDriver(entity);
+ return Response.ok(entity).build();
+ }
+
+ @Path("{id}")
+ @DELETE
+ public Response remove(@PathParam("id") long id) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkDriver(getUserId(), id);
+ Context.getDriversManager().removeDriver(id);
+ return Response.noContent().build();
+ }
+
+}
diff --git a/src/org/traccar/api/resource/GroupDriverResource.java b/src/org/traccar/api/resource/GroupDriverResource.java
new file mode 100644
index 000000000..76fc2892c
--- /dev/null
+++ b/src/org/traccar/api/resource/GroupDriverResource.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.api.resource;
+
+import java.sql.SQLException;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.traccar.Context;
+import org.traccar.api.BaseResource;
+import org.traccar.model.GroupDriver;
+
+@Path("groups/drivers")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class GroupDriverResource extends BaseResource {
+
+ @POST
+ public Response add(GroupDriver entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkGroup(getUserId(), entity.getGroupId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getDriverId());
+ Context.getDataManager().linkGroupDriver(entity.getGroupId(), entity.getDriverId());
+ Context.getDriversManager().refresh();
+ return Response.ok(entity).build();
+ }
+
+ @DELETE
+ public Response remove(GroupDriver entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkGroup(getUserId(), entity.getGroupId());
+ Context.getPermissionsManager().checkDriver(getUserId(), entity.getDriverId());
+ Context.getDataManager().unlinkGroupDriver(entity.getGroupId(), entity.getDriverId());
+ Context.getDriversManager().refresh();
+ return Response.noContent().build();
+ }
+
+}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index dd65289e4..1c2a66bcf 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -44,11 +44,15 @@ import org.traccar.model.CalendarPermission;
import org.traccar.model.Attribute;
import org.traccar.model.Device;
import org.traccar.model.DeviceAttribute;
+import org.traccar.model.DeviceDriver;
import org.traccar.model.DevicePermission;
+import org.traccar.model.Driver;
+import org.traccar.model.DriverPermission;
import org.traccar.model.Event;
import org.traccar.model.Geofence;
import org.traccar.model.Group;
import org.traccar.model.GroupAttribute;
+import org.traccar.model.GroupDriver;
import org.traccar.model.GroupGeofence;
import org.traccar.model.GroupPermission;
import org.traccar.model.Notification;
@@ -638,4 +642,84 @@ public class DataManager {
.executeUpdate();
}
+ public Collection<Driver> getDrivers() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectDrivers"))
+ .executeQuery(Driver.class);
+ }
+
+ public void addDriver(Driver driver) throws SQLException {
+ driver.setId(QueryBuilder.create(dataSource, getQuery("database.insertDriver"), true)
+ .setObject(driver)
+ .executeUpdate());
+ }
+
+ public void updateDriver(Driver driver) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.updateDriver"))
+ .setObject(driver)
+ .executeUpdate();
+ }
+
+ public void removeDriver(long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.deleteDriver"))
+ .setLong("id", driverId)
+ .executeUpdate();
+ }
+
+ public Collection<DriverPermission> getDriverPermissions() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectDriverPermissions"))
+ .executeQuery(DriverPermission.class);
+ }
+
+ public void linkDriver(long userId, long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkDriver"))
+ .setLong("userId", userId)
+ .setLong("driverId", driverId)
+ .executeUpdate();
+ }
+
+ public void unlinkDriver(long userId, long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkDriver"))
+ .setLong("userId", userId)
+ .setLong("driverId", driverId)
+ .executeUpdate();
+ }
+
+ public Collection<GroupDriver> getGroupDrivers() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectGroupDrivers"))
+ .executeQuery(GroupDriver.class);
+ }
+
+ public void linkGroupDriver(long groupId, long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkGroupDriver"))
+ .setLong("groupId", groupId)
+ .setLong("driverId", driverId)
+ .executeUpdate();
+ }
+
+ public void unlinkGroupDriver(long groupId, long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkGroupDriver"))
+ .setLong("groupId", groupId)
+ .setLong("driverId", driverId)
+ .executeUpdate();
+ }
+
+ public Collection<DeviceDriver> getDeviceDrivers() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectDeviceDrivers"))
+ .executeQuery(DeviceDriver.class);
+ }
+
+ public void linkDeviceDriver(long deviceId, long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkDeviceDriver"))
+ .setLong("deviceId", deviceId)
+ .setLong("driverId", driverId)
+ .executeUpdate();
+ }
+
+ public void unlinkDeviceDriver(long deviceId, long driverId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkDeviceDriver"))
+ .setLong("deviceId", deviceId)
+ .setLong("driverId", driverId)
+ .executeUpdate();
+ }
+
}
diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java
new file mode 100644
index 000000000..e89d59311
--- /dev/null
+++ b/src/org/traccar/database/DriversManager.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.database;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.traccar.Context;
+import org.traccar.helper.Log;
+import org.traccar.model.Device;
+import org.traccar.model.DeviceDriver;
+import org.traccar.model.Driver;
+import org.traccar.model.DriverPermission;
+import org.traccar.model.GroupDriver;
+
+public class DriversManager {
+
+ private final DataManager dataManager;
+
+ private final Map<Long, Driver> drivers = new ConcurrentHashMap<>();
+ private final Map<String, Driver> driversByUniqueId = new ConcurrentHashMap<>();
+ private final Map<Long, Set<Long>> deviceDrivers = new ConcurrentHashMap<>();
+ private final Map<Long, Set<Long>> deviceDriversWithGroups = new ConcurrentHashMap<>();
+ private final Map<Long, Set<Long>> groupDrivers = new ConcurrentHashMap<>();
+ private final Map<Long, Set<Long>> userDrivers = new ConcurrentHashMap<>();
+
+ public DriversManager(DataManager dataManager) {
+ this.dataManager = dataManager;
+ refreshDrivers();
+ }
+
+ public Set<Long> getUserDrivers(long userId) {
+ if (!userDrivers.containsKey(userId)) {
+ userDrivers.put(userId, new HashSet<Long>());
+ }
+ return userDrivers.get(userId);
+ }
+
+ public Set<Long> getGroupDrivers(long groupId) {
+ if (!groupDrivers.containsKey(groupId)) {
+ groupDrivers.put(groupId, new HashSet<Long>());
+ }
+ return groupDrivers.get(groupId);
+ }
+
+ public Set<Long> getDeviceDrivers(long deviceId) {
+ return getDeviceDrivers(deviceDrivers, deviceId);
+ }
+
+ public Set<Long> getAllDeviceDrivers(long deviceId) {
+ return getDeviceDrivers(deviceDriversWithGroups, deviceId);
+ }
+
+ private Set<Long> getDeviceDrivers(Map<Long, Set<Long>> deviceDrivers, long deviceId) {
+ if (!deviceDrivers.containsKey(deviceId)) {
+ deviceDrivers.put(deviceId, new HashSet<Long>());
+ }
+ return deviceDrivers.get(deviceId);
+ }
+
+ public final void refreshDrivers() {
+ if (dataManager != null) {
+ try {
+ drivers.clear();
+ driversByUniqueId.clear();
+ for (Driver driver : dataManager.getDrivers()) {
+ drivers.put(driver.getId(), driver);
+ driversByUniqueId.put(driver.getUniqueId(), driver);
+ }
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ refreshUserDrivers();
+ refresh();
+ }
+
+ public final void refreshUserDrivers() {
+ if (dataManager != null) {
+ try {
+ userDrivers.clear();
+ for (DriverPermission driverPermission : dataManager.getDriverPermissions()) {
+ getUserDrivers(driverPermission.getUserId()).add(driverPermission.getDriverId());
+ }
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ }
+
+ public final void refresh() {
+ if (dataManager != null) {
+ try {
+
+ Collection<GroupDriver> databaseGroupDrivers = dataManager.getGroupDrivers();
+
+ groupDrivers.clear();
+ for (GroupDriver groupDriver : databaseGroupDrivers) {
+ getGroupDrivers(groupDriver.getGroupId()).add(groupDriver.getDriverId());
+ }
+
+ Collection<DeviceDriver> databaseDeviceDrivers = dataManager.getDeviceDrivers();
+ Collection<Device> allDevices = Context.getDeviceManager().getAllDevices();
+
+ deviceDrivers.clear();
+ deviceDriversWithGroups.clear();
+
+ for (DeviceDriver deviceAttribute : databaseDeviceDrivers) {
+ getDeviceDrivers(deviceAttribute.getDeviceId())
+ .add(deviceAttribute.getDriverId());
+ getAllDeviceDrivers(deviceAttribute.getDeviceId())
+ .add(deviceAttribute.getDriverId());
+ }
+
+ for (Device device : allDevices) {
+ long groupId = device.getGroupId();
+ while (groupId != 0) {
+ getAllDeviceDrivers(device.getId()).addAll(getGroupDrivers(groupId));
+ if (Context.getDeviceManager().getGroupById(groupId) != null) {
+ groupId = Context.getDeviceManager().getGroupById(groupId).getGroupId();
+ } else {
+ groupId = 0;
+ }
+ }
+ }
+
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ }
+
+ public void addDriver(Driver driver) throws SQLException {
+ dataManager.addDriver(driver);
+ drivers.put(driver.getId(), driver);
+ driversByUniqueId.put(driver.getUniqueId(), driver);
+ }
+
+ public void updateDriver(Driver driver) throws SQLException {
+ dataManager.updateDriver(driver);
+ Driver cachedDriver = drivers.get(driver.getId());
+ cachedDriver.setName(driver.getName());
+ if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) {
+ driversByUniqueId.remove(cachedDriver.getUniqueId());
+ cachedDriver.setUniqueId(driver.getUniqueId());
+ driversByUniqueId.put(cachedDriver.getUniqueId(), cachedDriver);
+ }
+ cachedDriver.setAttributes(driver.getAttributes());
+ }
+
+ public void removeDriver(long driverId) throws SQLException {
+ dataManager.removeDriver(driverId);
+ if (drivers.containsKey(driverId)) {
+ String driverUniqueId = drivers.get(driverId).getUniqueId();
+ drivers.remove(driverId);
+ driversByUniqueId.remove(driverUniqueId);
+ }
+ refreshUserDrivers();
+ refresh();
+ }
+
+ public boolean checkDriver(long userId, long driverId) {
+ return getUserDrivers(userId).contains(driverId);
+ }
+
+ public Driver getDriver(long id) {
+ return drivers.get(id);
+ }
+
+ public Driver getDriverByUniqueId(String uniqueId) {
+ return driversByUniqueId.get(uniqueId);
+ }
+
+ public final Collection<Driver> getDrivers(Set<Long> driverIds) {
+ Collection<Driver> result = new LinkedList<>();
+ for (long driverId : driverIds) {
+ result.add(getDriver(driverId));
+ }
+ return result;
+ }
+
+ public final Set<Long> getAllDrivers() {
+ return drivers.keySet();
+ }
+
+ public final Set<Long> getManagedDrivers(long userId) {
+ Set<Long> drivers = new HashSet<>();
+ drivers.addAll(getUserDrivers(userId));
+ for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) {
+ drivers.addAll(getUserDrivers(managedUserId));
+ }
+ return drivers;
+ }
+}
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 9a82efd48..82ca6af49 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -322,6 +322,19 @@ public class PermissionsManager {
}
}
+ public void checkDriver(long userId, long driverId) throws SecurityException {
+ if (!Context.getDriversManager().checkDriver(userId, driverId) && !isAdmin(userId)) {
+ checkManager(userId);
+ for (long managedUserId : getUserPermissions(userId)) {
+ if (Context.getDriversManager().checkDriver(managedUserId, driverId)) {
+ return;
+ }
+ }
+ throw new SecurityException("Driver access denied");
+ }
+ }
+
+
public void checkCalendar(long userId, long calendarId) throws SecurityException {
if (!Context.getCalendarManager().checkCalendar(userId, calendarId) && !isAdmin(userId)) {
checkManager(userId);
diff --git a/src/org/traccar/events/DriverEventHandler.java b/src/org/traccar/events/DriverEventHandler.java
new file mode 100644
index 000000000..eb5f2a301
--- /dev/null
+++ b/src/org/traccar/events/DriverEventHandler.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.events;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.traccar.BaseEventHandler;
+import org.traccar.Context;
+import org.traccar.model.Event;
+import org.traccar.model.Position;
+
+public class DriverEventHandler extends BaseEventHandler {
+
+ @Override
+ protected Collection<Event> analyzePosition(Position position) {
+ if (!Context.getIdentityManager().isLatestPosition(position)) {
+ return null;
+ }
+ String driverUniqueId = position.getString(Position.KEY_DRIVER_UNIQUE_ID);
+ if (driverUniqueId != null) {
+ String oldDriverUniqueId = null;
+ Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId());
+ if (lastPosition != null) {
+ oldDriverUniqueId = lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID);
+ }
+ if (!driverUniqueId.equals(oldDriverUniqueId)) {
+ Event event = new Event(Event.TYPE_DRIVER_CHANGED, position.getDeviceId(), position.getId());
+ event.set(Position.KEY_DRIVER_UNIQUE_ID, driverUniqueId);
+ return Collections.singleton(event);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/model/DeviceDriver.java b/src/org/traccar/model/DeviceDriver.java
new file mode 100644
index 000000000..2008aaddf
--- /dev/null
+++ b/src/org/traccar/model/DeviceDriver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.model;
+
+public class DeviceDriver {
+
+ private long deviceId;
+
+ public long getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(long deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ private long driverId;
+
+ public long getDriverId() {
+ return driverId;
+ }
+
+ public void setDriverId(long driverId) {
+ this.driverId = driverId;
+ }
+
+}
diff --git a/src/org/traccar/model/Driver.java b/src/org/traccar/model/Driver.java
new file mode 100644
index 000000000..7a51d9151
--- /dev/null
+++ b/src/org/traccar/model/Driver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.model;
+
+public class Driver extends Extensible {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ private String uniqueId;
+
+ public String getUniqueId() {
+ return uniqueId;
+ }
+
+ public void setUniqueId(String uniqueId) {
+ this.uniqueId = uniqueId;
+ }
+}
diff --git a/src/org/traccar/model/DriverPermission.java b/src/org/traccar/model/DriverPermission.java
new file mode 100644
index 000000000..cdbcc4a50
--- /dev/null
+++ b/src/org/traccar/model/DriverPermission.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.model;
+
+public class DriverPermission {
+
+ private long userId;
+
+ public long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(long userId) {
+ this.userId = userId;
+ }
+
+ private long driverId;
+
+ public long getDriverId() {
+ return driverId;
+ }
+
+ public void setDriverId(long driverId) {
+ this.driverId = driverId;
+ }
+}
diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java
index 6a24d91c6..2d836abeb 100644
--- a/src/org/traccar/model/Event.java
+++ b/src/org/traccar/model/Event.java
@@ -61,6 +61,8 @@ public class Event extends Message {
public static final String TYPE_TEXT_MESSAGE = "textMessage";
+ public static final String TYPE_DRIVER_CHANGED = "driverChanged";
+
private Date serverTime;
public Date getServerTime() {
diff --git a/src/org/traccar/model/GroupDriver.java b/src/org/traccar/model/GroupDriver.java
new file mode 100644
index 000000000..91b205923
--- /dev/null
+++ b/src/org/traccar/model/GroupDriver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.model;
+
+public class GroupDriver {
+
+ private long groupId;
+
+ public long getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(long groupId) {
+ this.groupId = groupId;
+ }
+
+ private long driverId;
+
+ public long getDriverId() {
+ return driverId;
+ }
+
+ public void setDriverId(long driverId) {
+ this.driverId = driverId;
+ }
+
+}
diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java
index 5835310ae..9e7bac932 100644
--- a/src/org/traccar/model/Position.java
+++ b/src/org/traccar/model/Position.java
@@ -49,7 +49,6 @@ public class Position extends Message {
public static final String KEY_FUEL_LEVEL = "fuel"; // liters
public static final String KEY_FUEL_CONSUMPTION = "fuelConsumption"; // liters/hour
- public static final String KEY_RFID = "rfid";
public static final String KEY_VERSION_FW = "versionFw";
public static final String KEY_VERSION_HW = "versionHw";
public static final String KEY_TYPE = "type";
@@ -81,6 +80,8 @@ public class Position extends Message {
public static final String KEY_RESULT = "result";
+ public static final String KEY_DRIVER_UNIQUE_ID = "driverUniqueId";
+
// Start with 1 not 0
public static final String PREFIX_TEMP = "temp";
public static final String PREFIX_ADC = "adc";
diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java
index 96337ecaa..a30023fdc 100644
--- a/src/org/traccar/notification/NotificationFormatter.java
+++ b/src/org/traccar/notification/NotificationFormatter.java
@@ -30,6 +30,7 @@ import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.Position;
+import org.traccar.model.User;
import org.traccar.reports.ReportUtils;
public final class NotificationFormatter {
@@ -38,9 +39,11 @@ public final class NotificationFormatter {
}
public static VelocityContext prepareContext(long userId, Event event, Position position) {
+ User user = Context.getPermissionsManager().getUser(userId);
Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId());
VelocityContext velocityContext = new VelocityContext();
+ velocityContext.put("user", user);
velocityContext.put("device", device);
velocityContext.put("event", event);
if (position != null) {
@@ -50,6 +53,10 @@ public final class NotificationFormatter {
if (event.getGeofenceId() != 0) {
velocityContext.put("geofence", Context.getGeofenceManager().getGeofence(event.getGeofenceId()));
}
+ String driverUniqueId = event.getString(Position.KEY_DRIVER_UNIQUE_ID);
+ if (driverUniqueId != null) {
+ velocityContext.put("driver", Context.getDriversManager().getDriverByUniqueId(driverUniqueId));
+ }
velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url"));
velocityContext.put("dateTool", new DateTool());
velocityContext.put("numberTool", new NumberTool());
diff --git a/src/org/traccar/processing/CopyAttributesHandler.java b/src/org/traccar/processing/CopyAttributesHandler.java
index 3a96ca98d..9fbcfa73f 100644
--- a/src/org/traccar/processing/CopyAttributesHandler.java
+++ b/src/org/traccar/processing/CopyAttributesHandler.java
@@ -32,9 +32,14 @@ public class CopyAttributesHandler extends BaseDataHandler {
@Override
protected Position handlePosition(Position position) {
String attributesString = Context.getDeviceManager().lookupAttributeString(
- position.getDeviceId(), "processing.copyAttributes", null, true);
+ position.getDeviceId(), "processing.copyAttributes", "", true);
Position last = getLastPosition(position.getDeviceId());
- if (attributesString != null && last != null) {
+ if (attributesString.isEmpty()) {
+ attributesString = Position.KEY_DRIVER_UNIQUE_ID;
+ } else {
+ attributesString += "," + Position.KEY_DRIVER_UNIQUE_ID;
+ }
+ if (last != null) {
for (String attribute : attributesString.split("[ ,]")) {
if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) {
position.getAttributes().put(attribute, last.getAttributes().get(attribute));
diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java
index eb8d77011..6f63d0c17 100644
--- a/src/org/traccar/protocol/AplicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java
@@ -263,7 +263,8 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
}
if ((selector & 0x0200) != 0) {
- position.set(Position.KEY_RFID, (((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID,
+ String.valueOf(((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt());
}
if ((selector & 0x0400) != 0) {
diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java
index ea6aa7b30..8d86cd2be 100644
--- a/src/org/traccar/protocol/AstraProtocolDecoder.java
+++ b/src/org/traccar/protocol/AstraProtocolDecoder.java
@@ -105,7 +105,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // geofence events
if (BitUtil.check(status, 8)) {
- position.set(Position.KEY_RFID, buf.readBytes(7).toString(StandardCharsets.US_ASCII));
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readBytes(7).toString(StandardCharsets.US_ASCII));
position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000);
position.set(Position.KEY_HOURS, buf.readUnsignedShort());
}
diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java
index 79b3c36cc..23cb67e15 100644
--- a/src/org/traccar/protocol/AtrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java
@@ -327,7 +327,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_OUTPUT, buf.readUnsignedByte());
position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.001);
- position.set("driver", readString(buf));
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, readString(buf));
position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1);
position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1);
diff --git a/src/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/org/traccar/protocol/FifotrackProtocolDecoder.java
index f8f4fb078..304f6a2c3 100644
--- a/src/org/traccar/protocol/FifotrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/FifotrackProtocolDecoder.java
@@ -110,7 +110,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16));
}
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
if (parser.hasNext()) {
String[] sensors = parser.next().split("\\|");
diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java
index a3062c942..140d3300a 100644
--- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java
@@ -644,7 +644,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
decodeLocation(position, parser);
diff --git a/src/org/traccar/protocol/GnxProtocolDecoder.java b/src/org/traccar/protocol/GnxProtocolDecoder.java
index 070d394e8..2274ec164 100644
--- a/src/org/traccar/protocol/GnxProtocolDecoder.java
+++ b/src/org/traccar/protocol/GnxProtocolDecoder.java
@@ -102,7 +102,7 @@ public class GnxProtocolDecoder extends BaseProtocolDecoder {
position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
if (type.equals("MIF")) {
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
}
return position;
diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java
index f5ba3cff7..a9a72b110 100644
--- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java
@@ -258,7 +258,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
String rfid = parser.next();
if (alarm.equals("rfid")) {
- position.set(Position.KEY_RFID, rfid);
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid);
}
String utcHours = parser.next();
diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java
index 15a384cc0..994e2d983 100644
--- a/src/org/traccar/protocol/MegastekProtocolDecoder.java
+++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java
@@ -327,7 +327,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
}
}
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
String battery = parser.next();
if (battery != null) {
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 44e01d5e0..dbbf61f71 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -253,7 +253,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
if (parser.hasNext()) {
- position.set(Position.KEY_RFID, parser.nextHexInt(0));
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt(0)));
}
return position;
@@ -370,7 +370,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
if (rfid != 0) {
String card = String.format("%010d", rfid);
position.set("card" + (i + 1), card);
- position.set(Position.KEY_RFID, card);
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, card);
}
}
}
diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
index 38ecde519..711697fc4 100644
--- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -201,7 +201,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
if (eventData != null && !eventData.isEmpty()) {
switch (event) {
case 37:
- position.set(Position.KEY_RFID, eventData);
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, eventData);
break;
default:
position.set("eventData", eventData);
diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java
index 49987ce57..6d82e4a4b 100644
--- a/src/org/traccar/protocol/MxtProtocolDecoder.java
+++ b/src/org/traccar/protocol/MxtProtocolDecoder.java
@@ -159,7 +159,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder {
}
if (BitUtil.check(infoGroups, 7)) {
- position.set(Position.KEY_RFID, buf.readUnsignedInt());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedInt()));
}
buf.readerIndex(buf.writerIndex() - 3);
diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java
index 15f6f40b8..6f8513c41 100644
--- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java
+++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java
@@ -128,6 +128,9 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder {
case "batt":
position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value));
break;
+ case "driverUniqueId":
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, value);
+ break;
default:
try {
position.set(entry.getKey(), Double.parseDouble(value));
diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java
index b1851f8ca..e12bbdf28 100644
--- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java
@@ -129,7 +129,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder {
}
position.set(Position.KEY_ODOMETER, parser.nextInt(0));
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
if (parser.hasNext()) {
int value = parser.nextHexInt(0);
diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java
index e90dde455..38f6980f6 100644
--- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java
+++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java
@@ -196,7 +196,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder {
if (rfid.matches("0+")) {
rfid = data[data.length - 2];
}
- position.set(Position.KEY_RFID, rfid);
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid);
}
return position;
diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java
index c81e83aab..26817a5c8 100644
--- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Stl060ProtocolDecoder.java
@@ -104,7 +104,7 @@ public class Stl060ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1);
position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1);
position.set(Position.KEY_INPUT, parser.nextInt(0));
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
position.set(Position.KEY_ODOMETER, parser.nextInt(0));
position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0));
position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0));
diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
index c8c2e4002..15c5b8e80 100644
--- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
+++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
@@ -123,7 +123,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1);
break;
case 78:
- position.set(Position.KEY_RFID, readValue(buf, length, false));
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(readValue(buf, length, false)));
break;
case 182:
position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1);
diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java
index c10523117..b8458dd52 100644
--- a/src/org/traccar/protocol/TmgProtocolDecoder.java
+++ b/src/org/traccar/protocol/TmgProtocolDecoder.java
@@ -144,7 +144,7 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_ADC + 1, parser.nextDouble(0));
position.set(Position.PREFIX_ADC + 2, parser.nextDouble(0));
position.set(Position.KEY_VERSION_FW, parser.next());
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
return position;
}
diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java
index 1b22eeb75..31a3d2cfe 100644
--- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java
+++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java
@@ -308,7 +308,8 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
break;
case DATA_RFID:
- position.set(Position.KEY_RFID, buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII));
+ position.set(Position.KEY_DRIVER_UNIQUE_ID,
+ buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII));
position.set("authorized", buf.readUnsignedByte() != 0);
break;
diff --git a/src/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/org/traccar/protocol/VisiontekProtocolDecoder.java
index 636a3d640..f32c9fbfe 100644
--- a/src/org/traccar/protocol/VisiontekProtocolDecoder.java
+++ b/src/org/traccar/protocol/VisiontekProtocolDecoder.java
@@ -130,7 +130,7 @@ public class VisiontekProtocolDecoder extends BaseProtocolDecoder {
position.setValid(parser.next().equals("A"));
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
return position;
}
diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java
index 82098413b..4eb3b9b8e 100644
--- a/src/org/traccar/protocol/WialonProtocolDecoder.java
+++ b/src/org/traccar/protocol/WialonProtocolDecoder.java
@@ -109,7 +109,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
}
}
- position.set(Position.KEY_RFID, parser.next());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
if (parser.hasNext()) {
String[] values = parser.next().split(",");
diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java
index 71c567c29..bc58d28df 100644
--- a/src/org/traccar/reports/ReportUtils.java
+++ b/src/org/traccar/reports/ReportUtils.java
@@ -26,6 +26,7 @@ import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.TransformerFactory;
import org.traccar.Context;
+import org.traccar.model.Driver;
import org.traccar.model.Position;
import org.traccar.reports.model.BaseReport;
import org.traccar.reports.model.StopReport;
@@ -101,6 +102,25 @@ public final class ReportUtils {
return 0;
}
+ public static String findDriver(Position firstPosition, Position lastPosition) {
+ if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) {
+ return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID);
+ } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) {
+ return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID);
+ }
+ return null;
+ }
+
+ public static String findDriverName(String driverUniqueId) {
+ if (driverUniqueId != null && Context.getDriversManager() != null) {
+ Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId);
+ if (driver != null) {
+ return driver.getName();
+ }
+ }
+ return null;
+ }
+
public static org.jxls.common.Context initializeContext(long userId) {
org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext();
jxlsContext.putVar("distanceUnit", getDistanceUnit(userId));
@@ -176,6 +196,9 @@ public final class ReportUtils {
trip.setMaxSpeed(speedMax);
trip.setSpentFuel(calculateFuel(startTrip, endTrip));
+ trip.setDriverUniqueId(findDriver(startTrip, endTrip));
+ trip.setDriverName(findDriverName(trip.getDriverUniqueId()));
+
return trip;
}
diff --git a/src/org/traccar/reports/model/TripReport.java b/src/org/traccar/reports/model/TripReport.java
index efe556f79..42a4240b7 100644
--- a/src/org/traccar/reports/model/TripReport.java
+++ b/src/org/traccar/reports/model/TripReport.java
@@ -145,4 +145,24 @@ public class TripReport extends BaseReport {
public void setDuration(long duration) {
this.duration = duration;
}
+
+ private String driverUniqueId;
+
+ public String getDriverUniqueId() {
+ return driverUniqueId;
+ }
+
+ public void setDriverUniqueId(String driverUniqueId) {
+ this.driverUniqueId = driverUniqueId;
+ }
+
+ private String driverName;
+
+ public String getDriverName() {
+ return driverName;
+ }
+
+ public void setDriverName(String driverName) {
+ this.driverName = driverName;
+ }
}
diff --git a/templates/export/trips.xlsx b/templates/export/trips.xlsx
index 0e0ab4494..4a6734850 100644
--- a/templates/export/trips.xlsx
+++ b/templates/export/trips.xlsx
Binary files differ
diff --git a/templates/mail/driverChanged.vm b/templates/mail/driverChanged.vm
new file mode 100644
index 000000000..ba1e68661
--- /dev/null
+++ b/templates/mail/driverChanged.vm
@@ -0,0 +1,10 @@
+#set($subject = "$device.name: driver has changed")
+<!DOCTYPE html>
+<html>
+<body>
+Device: $device.name<br>
+Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone)<br>
+Point: <a href="$webUrl?eventId=$event.id">#{if}($position.address)$position.address#{else}$position.latitude&deg;, $position.longitude&deg;#{end}</a><br>
+Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end}
+</body>
+</html>
diff --git a/templates/sms/driverChanged.vm b/templates/sms/driverChanged.vm
new file mode 100644
index 000000000..50849df7c
--- /dev/null
+++ b/templates/sms/driverChanged.vm
@@ -0,0 +1,6 @@
+#if($driver)
+#set($driverName = $driver.name)
+#else
+#set($driverName = $event.getString("driverUniqueId"))
+#end
+Driver $driverName has changed in $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone)
diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java
index 3b801c6eb..cb9cdf759 100644
--- a/test/org/traccar/ProtocolTest.java
+++ b/test/org/traccar/ProtocolTest.java
@@ -245,6 +245,10 @@ public class ProtocolTest extends BaseTest {
Assert.assertTrue(attributes.get(Position.KEY_ARCHIVE) instanceof Boolean);
}
+ if (attributes.containsKey(Position.KEY_DRIVER_UNIQUE_ID)) {
+ Assert.assertTrue(attributes.get(Position.KEY_DRIVER_UNIQUE_ID) instanceof String);
+ }
+
if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) {
for (CellTower cellTower : position.getNetwork().getCellTowers()) {
checkInteger(cellTower.getMobileCountryCode(), 0, 999);
diff --git a/tools/test-generator.py b/tools/test-generator.py
index 9e9cf892e..41ec5a2fa 100755
--- a/tools/test-generator.py
+++ b/tools/test-generator.py
@@ -12,6 +12,7 @@ server = 'localhost:5055'
period = 1
step = 0.001
device_speed = 40
+driver_id = '123456'
waypoints = [
(40.722412, -74.006288),
@@ -34,7 +35,7 @@ for i in range(0, len(waypoints)):
lon = lon1 + (lon2 - lon1) * j / count
points.append((lat, lon))
-def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel):
+def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel, driverUniqueId):
params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('bearing', course), ('speed', speed))
if alarm:
params = params + (('alarm', 'sos'),)
@@ -46,6 +47,8 @@ def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel):
params = params + (('rpm', rpm),)
if fuel:
params = params + (('fuel', fuel),)
+ if driverUniqueId:
+ params = params + (('driverUniqueId', driverUniqueId),)
conn.request('GET', '?' + urllib.urlencode(params))
conn.getresponse().read()
@@ -71,6 +74,7 @@ while True:
accuracy = 100 if (index % 10) == 0 else 0
rpm = random.randint(500, 4000)
fuel = random.randint(0, 80)
- send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, alarm, ignition, accuracy, rpm, fuel)
+ driverUniqueId = driver_id if (index % len(points)) == 0 else False
+ send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, alarm, ignition, accuracy, rpm, fuel, driverUniqueId)
time.sleep(period)
index += 1