I am connecting to a serial device over the internet, using an ethernet to serial device. I am communicating with it via a small node.js app. The following code gets back the information I need:
var net = require('net');
var zone1 = 'AgABBgAJ';
var zone2 = 'AgACBgAK';
var zone3 = 'AgACBfAZ';
var zone4 = 'AgACBaAW';
var zone5 = 'AgACBsAV';
var client = new net.Socket();
client.connect(10006, '10.0.1.217', function() {
console.log('Connected');
client.write(Buffer.from(zone1, 'base64').toString('ascii')+'\n');
});
client.on('data', function(data) {
var data_array = new Uint8Array(data);
console.log(data_array);
var decoded = [];
decoded['zone'] = data_array[16];
decoded['power'] = data_array[18] == 128 ? 'On' : data_array[18] == 0 ? 'Off' : data_array[18] == 192 ? 'Muted' : 'Unknown';
decoded['input'] = data_array[22] + 1;
decoded['vol'] = data_array[23] - 196;
decoded['mute'] = data_array[18] == 192 ? 'On' : 'Off';
decoded['state'] = (data_array[18] == 128) || (data_array[18] == 192) ? true : false;
console.log('-- Zone: ' + decoded['zone']);
console.log('-- Power: ' + decoded['power']);
console.log('-- Input: ' + decoded['input']);
console.log('-- Volume: ' + decoded['vol']);
console.log('-- Mute: ' + decoded['mute']);
client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});
What I need to do now is write the other commands (zone2,zone3,zone4,zone5) and get the data back from them as well.
Is there a way to loop through an array of commands and output the data after each command?
Thanks!
EDIT: Here is the output from the app
Connected
Uint8Array [
2, 0, 0, 6, 0, 63, 0, 0,
0, 0, 0, 0, 0, 71, 2, 0,
1, 5, 0, 0, 0, 0, 0, 222,
8, 8, 0, 246
]
-- Zone: 1
-- Power: Off
-- Input: 1
-- Volume: 26
-- Mute: Off
Connection closed
You can create yourself a little state machine where you put the zones in an array and keep a variable that points to the next index in that array to process. Then, after you finish processing the data
event for a zone, you send the command for the next zone until you have no more items in the array.
const net = require('net');
const zones = [
'AgABBgAJ',
'AgACBgAK',
'AgACBfAZ',
'AgACBaAW',
'AgACBsAV'
];
let zoneIndex = 0;
const client = new net.Socket();
function sendNextZone() {
if (zoneIndex < zones.length) {
client.write(Buffer.from(zones[zoneIndex++], 'base64').toString('ascii')+'\n');
} else {
// no more zones to send, so we're done
client.destroy();
}
}
client.connect(10006, '10.0.1.217', function() {
console.log('Connected');
sendNextZone();
});
client.on('data', function(data) {
let data_array = new Uint8Array(data);
console.log(data_array);
let decoded = [];
decoded['zone'] = data_array[16];
decoded['power'] = data_array[18] == 128 ? 'On' : data_array[18] == 0 ? 'Off' : data_array[18] == 192 ? 'Muted' : 'Unknown';
decoded['input'] = data_array[22] + 1;
decoded['vol'] = data_array[23] - 196;
decoded['mute'] = data_array[18] == 192 ? 'On' : 'Off';
decoded['state'] = (data_array[18] == 128) || (data_array[18] == 192) ? true : false;
console.log('-- Zone: ' + decoded['zone']);
console.log('-- Power: ' + decoded['power']);
console.log('-- Input: ' + decoded['input']);
console.log('-- Volume: ' + decoded['vol']);
console.log('-- Mute: ' + decoded['mute']);
// done processing this zone, send the command for the next one
sendNextZone();
});
client.on('close', function() {
console.log('Connection closed');
});
client.on('error', function(err) {
console.log(err);
});
Note: There is no complete guarantee with a TCP socket that you will get all the data you want in one data
event - it is possible, particularly with larger data sets or slower networks that the data might be split between multiple data
events. If that were the case, you would need a buffer so you could buffer data until you had a "full" set of data that you could then process.