fleetmap-reports 1.0.489 → 1.0.491
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.test.js +11 -14
- package/src/speeding-report.js +54 -50
package/package.json
CHANGED
package/src/index.test.js
CHANGED
|
@@ -3,15 +3,13 @@ const assert = require('assert')
|
|
|
3
3
|
|
|
4
4
|
async function getSpeedingReport (report, userData) {
|
|
5
5
|
const data = await report.speedingReport(
|
|
6
|
-
new Date(Date.UTC(2022,
|
|
7
|
-
new Date(Date.UTC(2022,
|
|
6
|
+
new Date(Date.UTC(2022, 1, 17, 0, 0, 0, 0)),
|
|
7
|
+
new Date(Date.UTC(2022, 1, 17, 23, 59, 59, 0)),
|
|
8
8
|
userData)
|
|
9
9
|
assert.equal(data.length, 1)
|
|
10
|
-
const device = data[0].devices
|
|
11
|
-
console.log(device)
|
|
10
|
+
const device = data[0].devices.find(d => d.device.id === 22326)
|
|
12
11
|
const totalDistance = device.alerts.reduce((a, b) => a + b.distance, 0)
|
|
13
12
|
const totalEventTime = device.alerts.reduce((a, b) => a + b.eventTime, 0)
|
|
14
|
-
console.log(device.alerts)
|
|
15
13
|
return { device, totalDistance, totalEventTime }
|
|
16
14
|
}
|
|
17
15
|
|
|
@@ -23,10 +21,9 @@ describe('Test_Reports', function () {
|
|
|
23
21
|
const userData = await report.getUserData()
|
|
24
22
|
userData.roadSpeedLimits = true
|
|
25
23
|
const { device, totalDistance, totalEventTime } = await getSpeedingReport(report, userData)
|
|
26
|
-
assert.equal(device.alerts.length,
|
|
27
|
-
|
|
28
|
-
assert.equal(
|
|
29
|
-
assert.equal(totalEventTime, 3009000) // Total Duration
|
|
24
|
+
assert.equal(device.alerts.length, 104) // Total Alerts
|
|
25
|
+
assert.equal(totalDistance, 36.6525856031222) // Total Kms
|
|
26
|
+
assert.equal(totalEventTime, 1524000) // Total Duration
|
|
30
27
|
}, 200000)
|
|
31
28
|
// eslint-disable-next-line no-undef
|
|
32
29
|
it('Speeding with custom speed', async () => {
|
|
@@ -36,9 +33,9 @@ describe('Test_Reports', function () {
|
|
|
36
33
|
userData.useVehicleSpeedLimit = false
|
|
37
34
|
userData.customSpeed = 100
|
|
38
35
|
const { device, totalDistance, totalEventTime } = await getSpeedingReport(report, userData)
|
|
39
|
-
assert.equal(device.alerts.length,
|
|
40
|
-
assert.equal(totalDistance,
|
|
41
|
-
assert.equal(totalEventTime,
|
|
36
|
+
assert.equal(device.alerts.length, 13) // Total Alerts
|
|
37
|
+
assert.equal(totalDistance, 46.64576895855739) // Total Kms
|
|
38
|
+
assert.equal(totalEventTime, 1402000) // Total Duration
|
|
42
39
|
}, 20000)
|
|
43
40
|
// eslint-disable-next-line no-undef
|
|
44
41
|
it('Trip by device', async () => {
|
|
@@ -261,7 +258,7 @@ describe('Test_Reports', function () {
|
|
|
261
258
|
assert.equal(data.length, 1)
|
|
262
259
|
const device = data[0].devices.find(d => d.device.id === 22326)
|
|
263
260
|
assert.equal(device.summary[0].startOdometer, 122502742.59)
|
|
264
|
-
assert.equal(device.summary[0].distance,
|
|
261
|
+
assert.equal(device.summary[0].distance, 1427444.4699999243)
|
|
265
262
|
assert.equal(device.summary[0].startTime, '2022-01-01T13:35:47.000+0000')
|
|
266
263
|
assert.equal(device.summary[0].endTime, '2022-01-31T17:36:27.000+0000')
|
|
267
264
|
}, 40000)
|
|
@@ -289,7 +286,7 @@ describe('Test_Reports', function () {
|
|
|
289
286
|
assert.equal(data.length, 1)
|
|
290
287
|
const device = data[0].devices.find(d => d.device.id === 22326)
|
|
291
288
|
assert.equal(device.summary[5].startOdometer, 122923290.95)
|
|
292
|
-
assert.equal(device.summary[5].distance,
|
|
289
|
+
assert.equal(device.summary[5].distance, 77033.18999999762)
|
|
293
290
|
assert.equal(device.summary[5].startTime, '2022-01-06T18:35:36.000+0000')
|
|
294
291
|
assert.equal(device.summary[5].endTime, '2022-01-06T19:54:27.000+0000')
|
|
295
292
|
}, 90000)
|
package/src/speeding-report.js
CHANGED
|
@@ -68,6 +68,10 @@ async function createSpeedingReportByGroup (from, to, userData, traccarInstance)
|
|
|
68
68
|
return reportData
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
function processServerSide () {
|
|
72
|
+
return (process.env.PROCESS_HERE_EVENTS && process.env.PROCESS_HERE_EVENTS === 'server')
|
|
73
|
+
}
|
|
74
|
+
|
|
71
75
|
async function createSpeedingReportByDevice (from, to, userData, traccarInstance) {
|
|
72
76
|
const devices = devicesToProcess(userData)
|
|
73
77
|
|
|
@@ -81,6 +85,10 @@ async function createSpeedingReportByDevice (from, to, userData, traccarInstance
|
|
|
81
85
|
let deviceCount = 0
|
|
82
86
|
for (const slice of sliced) {
|
|
83
87
|
const { routes, events } = await getEvents(traccarInstance, from, to, slice, userData, deviceCount, devices.length, slice.length)
|
|
88
|
+
if (processServerSide()) {
|
|
89
|
+
console.log('LOADING_MESSAGE:' + slice[0].name)
|
|
90
|
+
console.log(`PROGRESS_PERC:${deviceCount / devices.length * 100}`)
|
|
91
|
+
}
|
|
84
92
|
if (events.length > 0) {
|
|
85
93
|
const devicesProcessed = await processDevices(from, to, slice, events, routes, userData)
|
|
86
94
|
allData.devices.push(...devicesProcessed)
|
|
@@ -111,8 +119,8 @@ async function createSpeedingReportByDriver (from, to, userData, traccarInstance
|
|
|
111
119
|
}
|
|
112
120
|
|
|
113
121
|
async function getEvents (traccarInstance, from, to, devices, userData, deviceCount, totalDevices, sliceSize) {
|
|
114
|
-
if (
|
|
115
|
-
const url =
|
|
122
|
+
if (processServerSide()) {
|
|
123
|
+
const url = `https://${process.env.SERVER_HOST}/reports/speeding-report/getEvents`
|
|
116
124
|
return axios.post(url, { from, to, devices, userData, deviceCount, totalDevices, sliceSize }, { withCredentials: true }).then(d => d.data)
|
|
117
125
|
} else {
|
|
118
126
|
const geofencesFeatures = userData.geofences.filter(g => g.area.startsWith('POLYGON') &&
|
|
@@ -225,10 +233,9 @@ async function processDevices (from, to, devices, events, routes, userData) {
|
|
|
225
233
|
async function findEventsPosition (from, to, devices, events, routes, userData) {
|
|
226
234
|
for (const d of devices) {
|
|
227
235
|
const deviceEvents = events.filter(e => e.deviceId === d.id && e.positionId)
|
|
236
|
+
console.log(d.name, deviceEvents.length)
|
|
228
237
|
if (deviceEvents.length > 0) {
|
|
229
|
-
deviceEvents.sort((a, b) => new Date(a.position.fixTime) - new Date(b.position.fixTime))
|
|
230
238
|
const positions = routes.filter(p => p.deviceId === d.id)
|
|
231
|
-
|
|
232
239
|
for (const a of deviceEvents) {
|
|
233
240
|
const pIndex = positions.findIndex(p => p.id === a.positionId)
|
|
234
241
|
if (pIndex > 0) {
|
|
@@ -250,10 +257,9 @@ async function findEventsPosition (from, to, devices, events, routes, userData)
|
|
|
250
257
|
a.driver = (driver && driver.name) || a.position.attributes.driverUniqueId
|
|
251
258
|
}
|
|
252
259
|
a.deviceName = d.name
|
|
253
|
-
|
|
254
|
-
return pIndex
|
|
255
260
|
}
|
|
256
261
|
}
|
|
262
|
+
deviceEvents.sort((a, b) => new Date(a.position.fixTime) - new Date(b.position.fixTime))
|
|
257
263
|
}
|
|
258
264
|
}
|
|
259
265
|
}
|
|
@@ -271,6 +277,7 @@ async function getCustomSpeedLimitEvents (devices, routes, customSpeed) {
|
|
|
271
277
|
if (position.speed > maxSpeed && !eventIsActive) {
|
|
272
278
|
const event = {
|
|
273
279
|
positionId: position && position.id,
|
|
280
|
+
position,
|
|
274
281
|
deviceId: d.id,
|
|
275
282
|
attributes: {
|
|
276
283
|
speedLimit: maxSpeed,
|
|
@@ -291,52 +298,47 @@ async function getCustomSpeedLimitEvents (devices, routes, customSpeed) {
|
|
|
291
298
|
async function getHereEvents (devices, routes, threshold) {
|
|
292
299
|
try {
|
|
293
300
|
console.log('env', process.env.PROCESS_HERE_EVENTS)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
cur.attributes = { speedLimit: cur.speedLimit, speed: cur.currentSpeedKmh / 1.85200, maxSpeed: cur.position.speed }
|
|
320
|
-
cur.eventTime = 0
|
|
321
|
-
cur.distance = 0
|
|
322
|
-
acc.push(cur)
|
|
323
|
-
}
|
|
324
|
-
return acc
|
|
325
|
-
}, [])
|
|
326
|
-
if (!reduced.length) {
|
|
327
|
-
console.log('empty array after filter on device', d.name)
|
|
328
|
-
resolve()
|
|
301
|
+
console.log('here speed limit events')
|
|
302
|
+
const events = []
|
|
303
|
+
const promises = devices.map(d => new Promise((resolve) => {
|
|
304
|
+
const positions = routes.filter(p => p.deviceId === d.id)
|
|
305
|
+
if (!positions.length) {
|
|
306
|
+
console.log('no positions on device', d.name)
|
|
307
|
+
resolve()
|
|
308
|
+
}
|
|
309
|
+
here.routeMatch(positions).then(results => {
|
|
310
|
+
const reduced = results.reduce((acc, cur, idx, src) => {
|
|
311
|
+
cur.overSpeeding = cur.currentSpeedKmh > parseInt(cur.speedLimit) + (threshold || 0)
|
|
312
|
+
const last = acc.length && acc.slice(-1)[0]
|
|
313
|
+
cur.position = positions.find(p => new Date(p.fixTime).getTime() === cur.timestamp)
|
|
314
|
+
if (cur.overSpeeding && last && src[idx - 1].overSpeeding && last.speedLimit === cur.speedLimit) {
|
|
315
|
+
last.eventTime = cur.timestamp - last.timestamp
|
|
316
|
+
last.attributes.maxSpeed = Math.max(last.attributes.maxSpeed, cur.position.speed)
|
|
317
|
+
last.distance = distance.default(point([cur.position.longitude, cur.position.latitude]), point([last.position.longitude, last.position.latitude]))
|
|
318
|
+
} else if (cur.overSpeeding) {
|
|
319
|
+
cur.positionId = cur.position && cur.position.id
|
|
320
|
+
cur.roadSpeedLimit = cur.speedLimit
|
|
321
|
+
cur.deviceId = d.id
|
|
322
|
+
cur.attributes = { speedLimit: cur.speedLimit, speed: cur.currentSpeedKmh / 1.85200, maxSpeed: cur.position.speed }
|
|
323
|
+
cur.eventTime = 0
|
|
324
|
+
cur.distance = 0
|
|
325
|
+
acc.push(cur)
|
|
329
326
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
console.
|
|
327
|
+
return acc
|
|
328
|
+
}, [])
|
|
329
|
+
if (!reduced.length) {
|
|
330
|
+
console.log('empty array after filter on device', d.name)
|
|
334
331
|
resolve()
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
332
|
+
}
|
|
333
|
+
events.push(...reduced)
|
|
334
|
+
resolve()
|
|
335
|
+
}).catch(e => {
|
|
336
|
+
console.error('error on route match, moving on', e)
|
|
337
|
+
resolve()
|
|
338
|
+
})
|
|
339
|
+
}))
|
|
340
|
+
await Promise.all(promises)
|
|
341
|
+
return events
|
|
340
342
|
} catch (e) {
|
|
341
343
|
console.error(e)
|
|
342
344
|
}
|
|
@@ -348,6 +350,7 @@ function calculateEventData (positions, pIndex, alert, device, geofence, userDat
|
|
|
348
350
|
let dist = 0
|
|
349
351
|
while (pIndex + 1 < positions.length) {
|
|
350
352
|
pIndex++
|
|
353
|
+
console.log(pIndex)
|
|
351
354
|
dist += distance.default(point([endEventPosition.longitude, endEventPosition.latitude]),
|
|
352
355
|
point([positions[pIndex].longitude, positions[pIndex].latitude]))
|
|
353
356
|
endEventPosition = positions[pIndex]
|
|
@@ -355,6 +358,7 @@ function calculateEventData (positions, pIndex, alert, device, geofence, userDat
|
|
|
355
358
|
alert.eventTime = new Date(endEventPosition.fixTime) - new Date(alert.position.fixTime)
|
|
356
359
|
alert.attributes.maxSpeed = maxSpeed
|
|
357
360
|
alert.distance = dist
|
|
361
|
+
console.log(alert)
|
|
358
362
|
break
|
|
359
363
|
} else {
|
|
360
364
|
if (maxSpeed < endEventPosition.speed) {
|