packet-decoder
Version:
SenRa Packet Decoder For IOT devices
303 lines (286 loc) • 10.1 kB
JavaScript
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
};