UNPKG

packet-decoder

Version:

SenRa Packet Decoder For IOT devices

303 lines (286 loc) 10.1 kB
const {DATE} = require('../Constants'); const ClusterLineChart = ({data, unchangedDevices}) => { const chart = { label: 'Traffic Status', data: [], labels: [] }; const points = {}; let occupancyCount = 0; const deviceOccupancyMap = {}; if (!data) return chart; for (const devEui in unchangedDevices) { switch (unchangedDevices[devEui].payload.car_status) { case 'CAR_PARKED': { occupancyCount++; break; } case 'CAR_ENTERING': { occupancyCount++; break; } } } data.forEach((record) => { const date = new Date(record.txtime); const time = date.getHours().toString().padStart(2, '0') + ":" + date.getMinutes().toString().padStart(2, '0'); switch (record.pdu.payload.car_status) { case 'NO_CAR': { if (deviceOccupancyMap[record.devEui] === undefined) { deviceOccupancyMap[record.devEui] = false; // occupancyCount--; } else if (deviceOccupancyMap[record.devEui]) { deviceOccupancyMap[record.devEui] = false; occupancyCount--; points[time] = {x: date, y: occupancyCount}; } break; } case 'CAR_LEAVING': { if (deviceOccupancyMap[record.devEui] === undefined) { deviceOccupancyMap[record.devEui] = false; // occupancyCount--; } else if (deviceOccupancyMap[record.devEui]) { deviceOccupancyMap[record.devEui] = false; occupancyCount--; points[time] = {x: date, y: occupancyCount}; } break; } case 'CAR_PARKED': { if (deviceOccupancyMap[record.devEui] === undefined) { deviceOccupancyMap[record.devEui] = true; occupancyCount++; points[time] = {x: date, y: occupancyCount}; } else if (!deviceOccupancyMap[record.devEui]) { deviceOccupancyMap[record.devEui] = true; occupancyCount++; points[time] = {x: date, y: occupancyCount}; } break; } case 'CAR_ENTERING': { if (deviceOccupancyMap[record.devEui] === undefined) { deviceOccupancyMap[record.devEui] = true; occupancyCount++; points[time] = {x: date, y: occupancyCount}; } else if (!deviceOccupancyMap[record.devEui]) { deviceOccupancyMap[record.devEui] = true; occupancyCount++; points[time] = {x: date, y: occupancyCount}; } break; } } }); for (const point in points) { chart.data.push(points[point]); } return chart; }; const ClusterMetaData = ({cluster, deviceData}) => { let metaData = [ { name: 'Total Parking', style: 'color:#000000', styleNg: {color: '#00000'}, label: '20', url: '/icons/SmartParking/ClusterMetaData/total.png' }, { name: 'Occupied', style: 'color:#fc5e5e', styleNg: {color: '#fc5e5e'}, label: '8', url: '/icons/SmartParking/ClusterMetaData/occupied.png' }, { name: 'Vacant', style: 'color:#81b040', styleNg: {color: '#81b040'}, label: '8', url: '/icons/SmartParking/ClusterMetaData/vacant.png' }, { name: 'Offline', style: 'color:#b7b7b7', styleNg: {color: '#b7b7b7'}, label: '4', url: '/icons/SmartParking/ClusterMetaData/notWorking.png' } ]; if (deviceData) { let totalParking = 0; let occupied = 0; let empty = 0; let notWorking = 0; deviceData.forEach(device => { totalParking++; if (device.packet.pdu && device.packet.pdu.payload) { switch (device.packet.pdu.payload.car_status) { case 'UNINITIALIZED': { notWorking++; break; } case 'NO_CAR': { empty++; break; } case 'CAR_LEAVING': { empty++; break; } case 'CAR_PARKED': { occupied++; break; } case 'CAR_ENTERING': { occupied++; break; } } } else { notWorking++; } }); metaData[0].label = totalParking; metaData[1].label = occupied; metaData[2].label = empty; metaData[3].label = notWorking; if (empty) { cluster.icon = '/icons/SmartParking/cluster-empty.png'; } else { cluster.icon = '/icons/SmartParking/cluster-full.png'; } } return metaData; }; const DeviceCardData = ({device, data}) => { data.url = '/icons/SmartParking/device-offline.png'; if (!(device.packet.pdu && device.packet.pdu.payload)) { data.online = false; device.card = data; return; } data.battery = device.packet.pdu.payload.battery_status; switch (device.packet.pdu.payload.car_status) { case 'CAR_PARKED': case 'CAR_ENTERING': { data.status = 'Occupied'; data.url = '/icons/SmartParking/device-occupied.png'; break; } case 'NO_CAR': case 'CAR_LEAVING': { data.status = 'Vacant'; data.url = '/icons/SmartParking/device-empty.png'; break; } default: { data.status = 'Offline'; data.url = '/icons/SmartParking/device-offline.png'; } } device.card = data; }; const ClusterHistoricDataYearly = (deviceData) => { const yearlyMap = {}; let status; for (const deviceId in deviceData) { status = null; const packets = deviceData[deviceId]; packets.forEach(packet => { const date = packet.txtime; if (!yearlyMap[DATE.MONTHS[date.getMonth()]]) { yearlyMap[DATE.MONTHS[date.getMonth()]] = 0; } switch (packet.pdu.payload.car_status) { case 'CAR_PARKED': case 'CAR_ENTERING': { if (status === 'NO_CAR' || status === 'CAR_LEAVING') { yearlyMap[DATE.MONTHS[date.getMonth()]]++; } break; } } status = packet.pdu.payload.car_status; }); } const chart = []; for (const month in yearlyMap) { chart.push({x: month, y: yearlyMap[month]}); } return chart; }; const ClusterHistoricDataMonthly = (deviceData) => { const monthlyMap = {}; let status; let firstDay = null; for (const deviceId in deviceData) { status = null; const packets = deviceData[deviceId]; packets.forEach(packet => { const date = packet.txtime; const firstDay = new Date(`${date.getMonth() + 1}-01-${date.getFullYear()}`); const offset = firstDay.getDay() - 1; const week = Math.floor((date.getDate() + offset) / 7); if (!monthlyMap[week]) { monthlyMap[week] = {}; } if (!monthlyMap[week][DATE.DAYS[date.getDay()]]) { monthlyMap[week][DATE.DAYS[date.getDay()]] = 0; } switch (packet.pdu.payload.car_status) { case 'CAR_PARKED': case 'CAR_ENTERING': { if (status === 'NO_CAR' || status === 'CAR_LEAVING') { monthlyMap[week][DATE.DAYS[date.getDay()]]++; } break; } } status = packet.pdu.payload.car_status; }); } const chart = {}; for (const week in monthlyMap) { chart[week] = []; for (const day in monthlyMap[week]) { chart[week].push({x: day, y: monthlyMap[week][day]}); } } return chart; }; const DeviceHistoricData = (deviceData) => { let status; const deviceStatus = []; deviceData.forEach(packet => { const date = packet.txtime; switch (packet.pdu.payload.car_status) { case 'CAR_PARKED': case 'CAR_ENTERING': { if (status !== 'CAR_PARKED' && status !== 'CAR_ENTERING') { deviceStatus.push({from: date, to: null}); } break; } case 'NO_CAR': case 'CAR_LEAVING': { if (status === 'CAR_PARKED' || status === 'CAR_ENTERING') { deviceStatus[deviceStatus.length - 1].to = date; } break; } } status = packet.pdu.payload.car_status; }); return deviceStatus; }; module.exports = { ClusterLineChart, ClusterMetaData, DeviceCardData, ClusterHistoricDataYearly, ClusterHistoricDataMonthly, DeviceHistoricData };