import { assert } from 'console' // TODO: put it in a dedicated class export class UplinkEventAdapter { /** * Allow the transformation of JSon object coming from Chirpstack to GeoJSON * Allow to write to mongo * The constructor doesn't do anything except initialization variables * @param {object} gatewayMap gateway map (i.e stations) */ constructor (gatewayMap) { this.GWMap = gatewayMap } /** * * @param {object} jsChirpEvent decoded from the protobuf * @returns ${Array} of geoJSON object */ getGeoJSONFeatures (jsChirpEvent) { // get location to check if the gateway is registered const gwEuid = jsChirpEvent.rxInfo[0].gatewayId if (!(gwEuid in this.GWMap)) { application.logger.error(`Unknown gateway ${gwEuid}.`) return null } const lat = this.GWMap[gwEuid].lat const lon = this.GWMap[gwEuid].lon // read measures const nsTimeMs = jsChirpEvent.rxInfo[0].nsTime.seconds * 1000 + jsChirpEvent.rxInfo[0].nsTime.nanos / 1000 const gatewayId = jsChirpEvent.rxInfo[0].gatewayId const observationDatetime = new Date(nsTimeMs) // create the geoJson, Kano require one feature per sensor const geoJSONArray = [] for (const key in jsChirpEvent.object.fields) { const geoJSON = { type: 'Feature', geometry: { type: 'Point', coordinates: [lon, lat] }, properties: { euid: jsChirpEvent.deviceInfo.devEui, name: jsChirpEvent.deviceInfo.deviceName, app_id: jsChirpEvent.deviceInfo.applicationId, app_name: jsChirpEvent.deviceInfo.applicationName, tenant_id: jsChirpEvent.deviceInfo.tenantId, tenant_name: jsChirpEvent.deviceInfo.tenantName, gw_euid: gatewayId }, time: observationDatetime } geoJSON.properties[key] = this.getKindValue(jsChirpEvent.object.fields[key]) geoJSONArray.push(geoJSON) } return geoJSONArray } /** * extract value from Value message (cf protobug struct.proto from google) * @param {*} protoMessage * @returns */ getKindValue (protoMessage) { const properties = Object.getOwnPropertyNames(protoMessage) assert(properties.length === 1) const kind = properties[0] switch (kind) { case 'numberValue': case 'stringValue': case 'boolValue': case 'nullValue': return protoMessage[kind] case 'structValue': case 'listValue': application.logger.warn('Not currently supported') assert(false) break default: application.logger.warn('Unsupported type:' + kind) assert(false) } return null } }