import historyAPI from '@/api/historyApi.js'
import api from '@/api'
import moment from 'moment'
import { formatSeconds, formatDatetimeWithSeconds } from '@/utils/dates.js'
import normalizePositionEntity from './entities/position-entity'
import createSensorConfigEntity from '@/services/entities/sensor-config.js'
import { getFormattedAddress } from '@/utils/address'
import { normalizeObject } from '@/utils/object.js'
import normalizeTripHistoryStep from '@/services/entities/trip-history-step.js'
import { splitOperation } from '@/utils/promise.js'
import { isMomentToday } from '@/utils/dates.js'
import APIUrls, {
APIV3RequestDatetimeFormat,
APIV2RequestDatetimeFormat,
} from '@/config/simpliciti-apis.js'
import sensorsService from './sensors-service'
const R = require('ramda')
export default {
getVehicleHistoryFromDate,
getVehicleHistoryStepsFromDate,
normalizeVehicleHistoryPositions,
}
/**
* Used by Diagnostic module to fetch vehicle overview information about the trip history for a particular date.
*
* @param {Number} vehicleId
* @param {Date|Moment} date
* @returns {Object} Overview information about the trip history
*/
export async function getVehicleHistoryFromDate(vehicleId, date, options = {}) {
return await historyAPI.getVehicleHistoryInfosFromAPIV2(
vehicleId,
date,
options
)
}
/**
* @warn unused
* @param {*} vehicleId
* @param {*} date
* @version APIV2
* @returns
*/
export async function getVehicleHistoryStepsFromDate(vehicleId, date) {
let formattedDateFrom = moment(date)
.hour(0)
.minute(0)
.seconds(0)
.format(APIV2RequestDatetimeFormat)
let formattedDateTo = moment(date)
.hour(23)
.minute(59)
.seconds(59)
.format(APIV2RequestDatetimeFormat)
let response = (
await api.v2.post(
`${APIUrls.APIV2_HISTORIQUE_TRONCONS_DETAILS}?vehicule_id=${vehicleId}&dateheure_debut=${formattedDateFrom}&dateheure_fin=${formattedDateTo}&linestring=true`
)
).data
let historySteps = []
if (response instanceof Array && response.length >= 1) {
historySteps = response[0].troncons && response[0].troncons
}
return historySteps.map(normalizeTripHistoryStep)
}
/**
* Used by Diagnostic module
*
* @todo Use properties[positions][]= to reduce size of nested objects (It doesn't work with arrays like tor/ana)
* @param {*} vehicleId
* @param {*} date
* @param {*} options
* @version APIV3
* @returns
*/
export async function getVehiclePositions(
vehicleId,
startDatetime,
endDatetime
) {
if (moment(startDatetime).day() == moment(endDatetime).day()) {
return fetchHandler(startDatetime, endDatetime)
} else {
let arr = await splitOperation({
sequential: false,
generateSubsets() {
return [
{
startDatetime: moment(startDatetime),
endDatetime: moment(startDatetime).hour(23).minute(59).second(59),
},
{
startDatetime: moment(endDatetime).hour(0).minute(0).second(0),
endDatetime: moment(endDatetime),
},
]
},
async handleSubset(subset) {
console.log('getVehiclePositions::splitOperation::handleSubset', {
subset,
})
return fetchHandler(subset.startDatetime, subset.endDatetime)
},
})
console.log('getVehiclePositions::splitOperation', {
arr,
})
return arr.reduce((a, v) => {
a = [...a, ...v]
return a
}, [])
}
async function fetchHandler(startDatetime, endDatetime) {
let data = []
startDatetime = moment(startDatetime).format(APIV3RequestDatetimeFormat)
endDatetime = moment(endDatetime).format(APIV3RequestDatetimeFormat)
data = (
await api.v3.get(APIUrls.APIV3_GET_POSITIONS, {
vehicleIds: [vehicleId],
startDatetime,
endDatetime,
groups: ['sensor_details', 'can'],
properties: ['positions', 'vehicleRegistrationPlate', 'vehicleName'],
})
).data
data = data.length > 0 ? data[0] : { positions: [] }
data = data.positions.map((item) =>
normalizePositionEntity(item, {
vehicleId,
datetimeInputFormat: 'YYYY-MM-DDTHH:mm:ss[Z]',
})
)
data = data.filter((item) => {
return !!item.lng && !!item.lat
})
return data
}
}
/**
* Used by Diagnostic module
* @todo Remove when unused
*
* @param {*} vehicleId
* @param {*} datetime
* @version APIV2
* @returns
*/
export async function getVehicleHistoryPositionDetailsFromDateLegacy(
vehicleId,
datetime
) {
datetime = datetime._isAMomentObject ? datetime : moment(new Date(datetime))
datetime = datetime.format(APIV2RequestDatetimeFormat)
let items = (
await api.v2.get(
`${APIUrls.APIV2_POSITIONS_GPS}?vehicule_id=${vehicleId}&dateheure_debut=${datetime}&dateheure_fin=${datetime}&groups=infos_complementaires,capteurs,capteurs_details,can,localisation_adresse`
)
).data
if (items instanceof Array && items.length > 0) {
let item = items[0]
let headers = R.omit(['positions'], item)
item = {
...headers,
...(item.positions.length > 0 ? item.positions[0] : {}),
}
return normalizePositionEntity(item)
} else {
return null
}
}
/**
* Unused
* @param {Array} positions
* @param {String} vehicleId
* @returns
*/
export function normalizeVehicleHistoryPositions(positions, vehicleId) {
return (positions || []).map((item) => {
return {
lat: item.latitude,
lng: item.longitude,
datetime: item.datetime,
timestamp: moment(item.datetime)._d.getTime(),
vehicleId,
}
})
}
/***
* Used by Diagnostic module
* @version APIV3
* Will compare two positions using APIV3_POSITIONS_CUMULATION
*/
export async function analyzeHistorySegment(
vehicleId,
datetimeFrom,
datetimeTo
) {
let res = await api.v3.get(APIUrls.APIV3_POSITIONS_CUMULATION, {
vehicleId,
startDatetime: moment(datetimeFrom).format(APIV3RequestDatetimeFormat),
endDatetime: moment(datetimeTo).format(APIV3RequestDatetimeFormat),
})
return res.data instanceof Array && res.data.length > 0
? normalizeAnalyzeHistorySegment(res.data[0])
: null
}
/**
* Used by Diagnostic module
* @todo Refactor/Move into entity "diagnostic-analysis-entity"
* @param {*} response
* @returns
*/
export function normalizeAnalyzeHistorySegment(response) {
//response key --> normalized key
let normalizedTable = {
vehicleId: 'vehicleId',
clientId: 'clientId',
vehicleCategoryId: 'vehicleCategoryId',
vehicleName: 'vehicleName',
clientName: 'clientName',
vehicleRegistrationPlate: 'vehicleRegistrationPlate',
vehicleCategoryName: 'vehicleCategoryName',
startDatetime: {
key: 'startDatetime',
transformKey: 'startDatetimeFormatted',
transform: (v) =>
formatDatetimeWithSeconds(v, {
inputFormat: APIV3RequestDatetimeFormat,
}),
},
endDatetime: {
key: 'endDatetime',
transformKey: 'endDatetimeFormatted',
transform: (v) =>
formatDatetimeWithSeconds(v, {
inputFormat: APIV3RequestDatetimeFormat,
}),
},
duration: {
key: 'duration',
transformKey: 'durationFormatted',
transform: (v) => formatSeconds(v),
},
effectiveDuration: {
key: 'effectiveDuration',
transformKey: 'effectiveDurationFormatted',
transform: (v) => formatSeconds(v),
},
distance: {
key: 'distance',
transformKey: 'distanceFormatted',
transform: (v) => `${(v / 1000).toFixed(2)} Km`,
},
speed: {
key: 'speed',
transformKey: 'speedFormatted',
transform: (v) => `${v} Km/h`,
},
totalCo2: 'totalCo2',
averageCo2: 'averageCo2',
totalConsumption: 'totalConsumption',
averageConsumption: {
key: 'averageConsumption',
/*
transformKey: 'averageConsumptionPerc',
transform: (v, rawData) => {
return (
(rawData.averageConsumption / rawData.referenceConsumption) *
100
).toFixed(0)
},
*/
},
referenceConsumption: 'referenceConsumption',
averageEngineSpeed: 'averageEngineSpeed',
startAddress: {
key: 'startAddress',
transformKey: 'startAddressFormatted',
transform: (v, rawData = {}) =>
getFormattedAddress(rawData, {
streetNumber: '',
streetName: 'startAddress',
zipCode: 'startZipCode',
city: 'startCity',
}),
},
startZipCode: 'startZipCode',
startCity: 'startCity',
startLongitude: 'startLongitude',
startLatitude: 'startLatitude',
endAddress: {
key: 'endAddress',
transformKey: 'endAddressFormatted',
transform: (v, rawData = {}) =>
getFormattedAddress(rawData, {
streetNumber: '',
streetName: 'endAddress',
zipCode: 'endZipCode',
city: 'endCity',
}),
},
endZipCode: 'endZipCode',
endCity: 'endCity',
endLongitude: 'endLongitude',
endLatitude: 'endLatitude',
}
return normalizeObject(response, normalizedTable)
}
/**
*
* Used by Location module (Trip history details - table) to load positions and sensors configuration
*
* @param {*} vehicleId
* @param {*} date
* @returns {Array}
*/
export async function getVehicleSensorsConfiguration(vehicleId) {
/* const t = (d, h = 0, m = 0, s = 0) =>
moment(d).hour(h).minute(m).second(s).format(APIV2RequestDatetimeFormat) */
const startDatetime = moment()
.startOf('day')
.format(APIV3RequestDatetimeFormat)
const endDatetime = moment().endOf('day').format(APIV3RequestDatetimeFormat)
let res = await sensorsService.getSensors(
vehicleId,
startDatetime,
endDatetime,
{ sensors: true }
)
if (res) {
return {
id: res?.configurationId || -1,
name: res?.configurationName || 'Default',
sensors: (res?.sensors || []).map(createSensorConfigEntity),
}
} else {
return {}
}
}
Source