fleetmap-reports 1.0.856 → 1.0.858

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/lang/frFR.json CHANGED
@@ -169,6 +169,7 @@
169
169
  "digital_ports1": "Ports numériques 1",
170
170
  "digital_ports2": "Portes numériques 2",
171
171
  "temperature": "Température",
172
+ "temperature2": "Température 2",
172
173
  "select_vehicles": "sélectionner des véhicules",
173
174
  "select_vehicles_placeholder": "Véhicules",
174
175
  "select_geofences": "sélectionner les balises",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.856",
3
+ "version": "1.0.858",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -16,6 +16,7 @@
16
16
  "@turf/point-to-line-distance": "^6.5.0",
17
17
  "axios": "^0.22.0",
18
18
  "axios-cookiejar-support": "^1.0.1",
19
+ "country-reverse-geocoding": "^0.2.2",
19
20
  "docx": "^7.3.0",
20
21
  "file-saver": "^2.0.5",
21
22
  "fleetmap-partners": "^1.0.126",
@@ -203,6 +203,7 @@ async function exportLocationReportToPDF (userData, reportData) {
203
203
 
204
204
  if (userData.includeTemperature) {
205
205
  headers.push(translations.report.temperature)
206
+ headers.push(translations.report.temperature2 || 'Temperature 2')
206
207
  }
207
208
 
208
209
  if (positionsData) {
@@ -254,7 +255,8 @@ async function exportLocationReportToPDF (userData, reportData) {
254
255
  ]
255
256
 
256
257
  if (userData.includeTemperature) {
257
- temp.push(getTempValue(a))
258
+ temp.push(getTempValue(a, 'temp1'))
259
+ temp.push(getTempValue(a, 'temp2'))
258
260
  }
259
261
 
260
262
  if (userData.includeDigitalPorts) {
@@ -300,11 +302,8 @@ async function exportLocationReportToPDF (userData, reportData) {
300
302
  }
301
303
  }
302
304
 
303
- function getTempValue (row) {
304
- return (row.attributes && (
305
- (row.attributes.temp1 !== 175 && row.attributes.temp1) ||
306
- (row.attributes.temp2 !== 175 && row.attributes.temp2)
307
- )) || ''
305
+ function getTempValue (row, sensor) {
306
+ return (row.attributes[sensor] !== 175 && row.attributes[sensor]) || ''
308
307
  }
309
308
 
310
309
  function getDigitalPort1Label (row, translations, dAttributes) {
@@ -397,7 +396,8 @@ function exportLocationReportToExcel (userData, reportData) {
397
396
  speed: Math.round(a.speed * 1.85200),
398
397
  ignition: a.attributes.ignition ? translations.report.ignitionOn : translations.report.ignitionOff,
399
398
  driver: userData.byDriver ? d.driver.name : getDriverName(a.attributes.driverUniqueId, a.fixTime, userData),
400
- temperature: getTempValue(a),
399
+ temperature: getTempValue(a, 'temp1'),
400
+ temperature2: getTempValue(a, 'temp2'),
401
401
  digitalport1: getDigitalPortValue(a, 1, translations, d.device.attributes),
402
402
  digitalport2: getDigitalPortValue(a, 2, translations, d.device.attributes),
403
403
  latitude: a.latitude,
@@ -15,6 +15,7 @@ const booleanPointInPolygon = require('@turf/boolean-point-in-polygon')
15
15
  const automaticReports = require('./automaticReports')
16
16
  const { default: axios } = require('axios')
17
17
  const { getDriverName, getDriverData } = require('./util/driver')
18
+ const crg = require('country-reverse-geocoding').country_reverse_geocoding()
18
19
 
19
20
  const fileName = 'SpeedingReport'
20
21
  const eventTypes = ['deviceOverspeed']
@@ -136,7 +137,7 @@ async function getEvents (traccarInstance, from, to, devices, userData, deviceCo
136
137
 
137
138
  const events = []
138
139
  if (userData.roadSpeedLimits) {
139
- const hereResults = await getHereEvents(devices, routes, userData.maxSpeedThreshold, userData.minimumIdleMinutes)
140
+ const hereResults = await getRoadSpeedLimits(devices, routes, userData.maxSpeedThreshold, userData.minimumIdleMinutes)
140
141
  console.log('got', hereResults.length, 'from here')
141
142
  events.push(...hereResults)
142
143
  } else if (!userData.useVehicleSpeedLimit && userData.customSpeed) {
@@ -298,6 +299,76 @@ async function getCustomSpeedLimitEvents (devices, routes, customSpeed) {
298
299
  return events
299
300
  }
300
301
 
302
+ async function getRoadSpeedLimits(devices, routes, threshold, minimumMinutes = 0) {
303
+ const position = routes[0]
304
+ const country = crg.get_country(position.latitude, position.longitude)
305
+ const config = {
306
+ CHL: getOSMSpeedingEvents
307
+ }
308
+ const method = config[country && country.code] || getHereEvents
309
+ return method(devices, routes, threshold, minimumMinutes)
310
+ }
311
+
312
+ async function getOSMSpeedingEvents(devices, routes, threshold, minimumMinutes = 0) {
313
+ const chunk = 1000
314
+ const events = []
315
+ for (const d of devices) {
316
+ const route = routes.filter(r => r.deviceId === d.id)
317
+ const results = []
318
+ for (let i = 0; i < route.length; i += chunk) {
319
+ const apiKey = process.env.geoapifyKey
320
+ const slice = route.slice(i, i + chunk)
321
+ const { features } = await axios.post(`https://api.geoapify.com/v1/mapmatching?apiKey=${apiKey}`, {
322
+ mode: 'drive',
323
+ waypoints: slice.map(p => ({
324
+ timestamp: p.fixTime,
325
+ bearing: p.bearing,
326
+ location: [p.longitude, p.latitude]
327
+ }))
328
+ }).then(r => r.data)
329
+
330
+ const { properties } = features[0]
331
+ for (const wp of properties.waypoints) {
332
+ const leg = properties.legs[wp.leg_index]
333
+ if (!leg) {
334
+ console.log('ignoring legs (count):', properties.legs.count, wp.leg_index)
335
+ continue
336
+ }
337
+ const step = leg.steps[wp.step_index]
338
+ const position = route[wp.original_index + i]
339
+ if (!step) {
340
+ console.log('ignoring', wp.step_index, wp.leg_index, properties.legs[0].steps[wp.step_index], properties.legs[0].steps.length)
341
+ continue
342
+ }
343
+ if (wp.match_type !== 'unmatched' && step.speed_limit < position.speed * 1.852) {
344
+ results.push({ ...wp, ...step, ...position })
345
+ }
346
+ }
347
+ }
348
+ const reduced = results.reduce((acc, cur, idx, src) => {
349
+ cur.overSpeeding = cur.speed * 1.852 > cur.speed_limit + (threshold || 0)
350
+ const last = acc.length && acc.slice(-1)[0]
351
+ if (cur.overSpeeding && last && src[idx - 1].overSpeeding && last.speed_limit === cur.speed_limit) {
352
+ last.eventTime = new Date(cur.fixTime) - new Date(last.fixTime)
353
+ last.attributes.maxSpeed = Math.max(last.attributes.maxSpeed, cur.speed)
354
+ last.distance = distance.default(point([cur.longitude, cur.latitude]), point([last.longitude, last.latitude]))
355
+ } else if (cur.overSpeeding) {
356
+ cur.positionId = cur && cur.id
357
+ cur.roadSpeedLimit = cur.speed_limit
358
+ cur.deviceId = d.id
359
+ cur.attributes = { speedLimit: cur.speed_limit, speed: cur.speed, maxSpeed: cur.speed }
360
+ cur.eventTime = 0
361
+ cur.distance = 0
362
+ cur.position = {...cur}
363
+ acc.push(cur)
364
+ }
365
+ return acc
366
+ }, [])
367
+ events.push(...reduced)
368
+ }
369
+ return events.filter(e => e.eventTime >= minimumMinutes * 60 * 1000)
370
+ }
371
+
301
372
  async function getHereEvents (devices, routes, threshold, minimumMinutes = 0) {
302
373
  try {
303
374
  console.log('PROCESS_HERE_EVENTS', process.env.PROCESS_HERE_EVENTS)
@@ -3,11 +3,11 @@ 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, 1, 17, 0, 0, 0, 0)),
7
- new Date(Date.UTC(2022, 1, 17, 23, 59, 59, 0)),
6
+ new Date(Date.UTC(2023, 9, 4, 0, 0, 0, 0)),
7
+ new Date(Date.UTC(2023, 9, 4, 23, 59, 59, 0)),
8
8
  userData)
9
9
 
10
- const device = data[0].devices.find(d => d.device.id === 22326)
10
+ const device = data[0].devices[0]
11
11
  const totalDistance = device && device.alerts.reduce((a, b) => a + b.distance, 0)
12
12
  const totalEventTime = device && device.alerts.reduce((a, b) => a + b.eventTime, 0)
13
13
  return { device, totalDistance, totalEventTime }
@@ -20,7 +20,7 @@ describe('speeding tests', function () {
20
20
  const userData = await report.getUserData()
21
21
  userData.roadSpeedLimits = true
22
22
  const { device } = await getSpeedingReport(report, userData)
23
- assert.equal(device.alerts.length, 104) // Total Alerts
23
+ assert.equal(device.alerts.length, 9) // Total Alerts
24
24
  console.log(device.alerts)
25
25
 
26
26
  userData.minimumIdleMinutes = 1