Node.js TCP пишет несколько команд - PullRequest
0 голосов
/ 11 апреля 2020

Я подключаюсь к последовательному устройству через inte rnet, используя ethe rnet к последовательному устройству. Я общаюсь с ним через небольшое приложение node.js. Следующий код возвращает нужную мне информацию:

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');
});

Теперь мне нужно написать другие команды (zone2, zone3, zone4, zone5) и также получить от них данные.

Есть ли способ l oop через массив команд и выводить данные после каждой команды?

Спасибо!

РЕДАКТИРОВАТЬ: Вот вывод из приложения

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

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Вы можете создать себе небольшой конечный автомат, в котором вы помещаете зоны в массив и сохраняете переменную, которая указывает на следующий индекс в этом массиве для обработки. Затем, после завершения sh обработки события data для зоны, вы отправляете команду для следующей зоны, пока у вас больше нет элементов в массиве.

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);
});

Примечание: С сокетом TCP нет полной гарантии, что вы получите все необходимые данные в одном событии data - это возможно, особенно в случае больших наборов данных или в более медленных сетях, что данные могут быть разделены между несколькими событиями data. Если бы это было так, вам понадобился бы буфер, чтобы вы могли буферизовать данные, пока у вас не будет «полного» набора данных, который вы затем сможете обработать.

0 голосов
/ 11 апреля 2020

Я бы использовал Array или Set для ваших зон.

const zones = [
  'AgABBgAJ',
  'AgACBgAK',
  'AgACBfAZ',
  'AgACBaAW',
  'AgACBsAV'
];

Затем вы можете легко выполнить l oop:

for (const zone of zones) {
  client.write(Buffer.from(zone, 'base64').toString('ascii') + '\n');
  // etc.
}

Однако, вероятно, вам нужно больше делать здесь. Я бы порекомендовал создать небольшой клиентский класс, который может обернуть ваши команды и получение статуса. Я предполагаю, что вы хотите получить ответ перед запросом следующей зоны, а не запускать и забывать. Выезд асинхронный / ожидание .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...