I have a quite complex question (at least from my perspective). I am a beginner in node .js but I have a difficult task.
I need to create UDP server where I will be able to send a packet. The packet must be parsed and converted based on specifications that I have. After that It should be converted to json format and sent through the UDP server to REST API. The JSON format should look like this or at least this structure this API accepts.
I have a specific gatewayID of the API which I cant post here but I will give an example: 1000000000000003, then I have also APIUrl which will be for example this: api.com/api. I tried many codes and I have even tried ChatGPT but I still can’t figure out how to process the data correctly so the restAPI will accept them. If I add the json structure as fixed package it works and I am able to send it but I am unable to make the correct processing of data and I am not even sure how to send them to the UDP server so that it accepts and converts them correctly. I was told that the data will be received in hex I think and it should read it analyze it, process it, transfer it to json and send it to API. I am really hopeless since I have no idea how else I could do it. I have been programming in node js. for a week so please consider it that I am complete beginner. Thank you for understanding and for any help. I will be very grateful.
Structure of json data which API accepts (gatewayID of packet is different for each packet and different from API gatewayID):
{
"gatewayId": "1111111111111112",
"devices": [
{
"id": "EDCVIRTUAL06",
"packetId": 12,
"deviceType": 6,
"energyFence": 73,
"voltageFence": 12.5,
"voltageSource": 25,
"voltageBattery": 14.2,
"voltageFenceLowTreshold": 7800,
"powerOutput": 50,
"voltageGround": 2.54,
"impedance": 0,
"faults": 0,
"state": 2,
"signal": 0,
"vFenAvg": 65535,
"vFenMin": 65535,
"vFenMax": 65535,
"impMin": 65535,
"impMax": 65535,
"latitude": 48.88539020710477,
"longitude": 16.051812954246998
}
]
}
There is the specification for the data and for parsing the data:



I tried this and many other versions. I think there is also a problem when I send the data from console because I don’t really know how to send them.
How I tried to send data:
echo 0200000000000000000000C2020C00130232002C010000FFFFFFFF31302E303030313138 | ncat -u 127.0.0.1 12345
My current code:
const dgram = require('dgram');
const axios = require('axios');
const udpServer = dgram.createSocket('udp4');
const udpPort = 12345;
const restApiGatewayId = '1000000000000003';
const udpServerHost = "127.0.0.1";
udpServer.on('message', (message, remote) => {
const packet = message;
const packetGatewayId = packet.slice(2, 10).toString('hex');
const devEui = packet.readBigUInt64LE(1);
const cmdCompleteLog = packet.readUInt8(9);
const packetId = packet.readUInt32BE(10);
const voltageFence = packet.readUInt8(14) / 100;
const batteryVoltage = packet.readUInt8(15) / 100;
const voltageGround = packet.readUInt8(16) / 10;
const alarmLevelFor = packet.readUInt8(17) / 100;
const extSourceVoltage = packet.readUInt8(18) / 100;
const state = (packet[19] & 0b00000001) !== 0 ? 'ON' : 'OFF';
const power = (packet[19] & 0b00000010) !== 0 ? 'HIGH' : 'LOW';
const energy = packet.readUInt8(20);
const impedance = packet.readUInt16LE(21);
const gpsLat = packet.readUInt32LE(23) * 100000;
const gpsLon = packet.readUInt32LE(27) * 100000;
const gpsAccur = packet.readUInt8(31);
const accelerometerMotion = packet.readUInt8(32);
const txPeriod = packet.readUInt8(33);
const alarmField = {
alarmLoopLowResist: (packet[34] & 0b00000001) !== 0,
alarmLoopLowVoltage: (packet[34] & 0b00000010) !== 0,
alarmLowBattery: (packet[34] & 0b00000100) !== 0,
alarmGround: (packet[34] & 0b00001000) !== 0,
alarmLowBattBeep: (packet[34] & 0b00010000) !== 0,
alarmTransformerError: (packet[34] & 0b00100000) !== 0,
};
const voltageOnFenceAvg = packet.readUInt8(35) / 100;
const voltageOnFenceMax = packet.readUInt8(36) / 100;
const voltageOnFenceMin = packet.readUInt8(37) / 100;
const impedanceMax = packet.readUInt16LE(38);
const impedanceMin = packet.readUInt16LE(40);
const cellularSignal = packet.readUInt8(42);
const analyzedPacket = {
gatewayId: packetGatewayId,
devices: [
{
id: devEui.toString(),
packetId: packetId.toString(),
deviceType: '06',
energyFence: energy.toString(),
voltageFence: voltageFence.toString(),
voltageSource: extSourceVoltage.toString(),
voltageBattery: batteryVoltage.toString(),
voltageFenceLowTreshold: voltageOnFenceMin.toString(),
powerOutput: power === 'HIGH' ? '32' : '00',
voltageGround: voltageGround.toString(),
impedance: impedance.toString(),
faults: '00',
state: state.toString(),
signal: cellularSignal.toString(),
vFenAvg: voltageOnFenceAvg.toString(),
vFenMin: voltageOnFenceMin.toString(),
vFenMax: voltageOnFenceMax.toString(),
impMin: impedanceMin.toString(),
impMax: impedanceMax.toString(),
latitude: gpsLat.toString(),
longitude: gpsLon.toString()
}
]
};
const apiUrl = 'api.com/api';
axios.post(apiUrl, {
packet: analyzedPacket,
gateway: restApiGatewayId
})
.then(response => {
console.log('Packet send to API');
})
.catch(error => {
console.error(error);
});
});
udpServer.bind(udpPort, udpServerHost, () => {
console.log(`UDP listens on address ${udpServerHost}:${udpPort}`);
});