I have PLC (like a microcontroller) which is publishing data over MQTT.
I am currently receiving the data from the PLC with a script (JS) that subscribes to the same topic that the PLC is publishing to. The data is coming in as a buffer, which is cool, but I’d like to put the data into a structure so that it’s easier to use. Here is my JavaScript:
const mqtt = require('mqtt')
const client = mqtt.connect('mqtt://127.0.0.1')
client.on('connect', function () {
client.subscribe('potatoes', function (err) {
if (!err) {
client.publish('potatoes', 'If you get this message, you’re subscribed')
}
})
})
client.on('message', function (topic, message) {
console.log(message)
}
The data that the PLC is sending as bytes originates as a structure. The PLC: --first, converts the structure to an array of bytes --second, publishes the array of bytes over MQTT Note: The data that I’m actually sending has multiple structs which contain arrays of structures and so forth, but for simplicity’s sake, let’s assume it’s just sending this:
Struct Member | Type | Length In Bytes from MQTT |
---|---|---|
Running | Boolean | 2 |
Faulted | Boolean | 2 |
InPosition | Boolean | 2 |
ActualPosition | Long Real (64bit float) | 8 |
TargetPosition | Long Real (64bit float) | 8 |
Mode | Integer (16bit signed integer) | 2 |
SubMode | Unsigned Short Integer (8bits) | 2 |
(Don’t ask me why the Booleans use 16 bits (2-bytes), but they do.)
The question is, how can I put that data into a structure so that it looks the same as the data structure in the PLC. As an example, I’d like to be able to attach the boolean 'myStruct.Faulted' to a red indicator on my web page so that a user can see the status of a motor, for example.
I've managed to make a function that takes in a buffer and returns a struct:
function bufferToStruct(buffer) {
const struct = {};
struct.Running = buffer[0] !== 0;
struct.Faulted = buffer[2] !== 0;
//and so on for each member
return struct;
}
but this is quite a tedious process for large, complicated structs. I was hoping that I could have a 'for each' loop to go through each member in the struct and copy the data from the buffer (provided that the function knew the byte size of each member of the struct)
Any ideas?
Note, the ideal may have been to get the PLC to convert the data to JSON and send it over MQTT as JSON so that it comes with the structure at the outset, but unfortunately, the PLC is very limited with what it can do which makes this not particularly easy.
Maybe making an data struct to hold the length and looping through it can help with the hardcoding:
results will give output of an object based on the structMember and the position of the buffer based on the summation of the past length,
output: