Skip to content

Commit

Permalink
Use readline module for reading "cec-client" output
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafostar committed Mar 23, 2020
1 parent 69c9ed9 commit 25e2c4a
Showing 1 changed file with 149 additions and 142 deletions.
291 changes: 149 additions & 142 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { exec, spawn } = require('child_process');
const { EventEmitter } = require('events');
const readline = require('readline');
const debug = require('debug');
const keymap = require('./keymap');

Expand Down Expand Up @@ -169,8 +170,10 @@ module.exports = class Client
{ stdio: ['pipe', 'pipe', 'ignore'] });

this.client.stdin.setEncoding('utf8');
this.client.stdout.once('data', () => ctl_debug('cec-client background process started'));
this.client.stdout.on('data', (data) => this._parseClientOutput(String(data)));

this.client.stdout.once('data', () =>
ctl_debug('cec-client background process started')
);
this.client.once('close', (code) =>
{
this.client = null;
Expand All @@ -179,187 +182,191 @@ module.exports = class Client
if(this.doneInit && this.enabled) this._createClient();
else if(this.enabled) this.cec.emit('error', new Error(`App cec-client exited with code: ${code}`));
});

const rl = readline.createInterface({
input: this.client.stdout,
crlfDelay: Infinity
});

rl.on('line', this._parseClientOutput);
rl.once('close', () => rl.removeListener('line', this._parseClientOutput));
}

_parseClientOutput(data)
_parseClientOutput(line)
{
var lines = data.split('\n');
lines.forEach(line =>
{
if(line.length < 5) return;
if(line.length < 5) return;

if(!line.startsWith(`power status:`))
client_debug(line);
if(!line.startsWith(`power status:`))
client_debug(line);

if(!this.doneInit)
if(!this.doneInit)
{
if(this.myDevice && line.includes('waiting for input'))
{
if(this.myDevice && line.includes('waiting for input'))
{
this.doneInit = true;
ctl_debug('cec-client init successful');
this.cec.emit('ready', this.devices);
}

return;
this.doneInit = true;
ctl_debug('cec-client init successful');
this.cec.emit('ready', this.devices);
}

if(line.startsWith(`power status:`))
{
var logicalAddress = this.devices[this.controlledDevice].logicalAddress;
var value = this._getLineValue(line);
return;
}

if(this.devices[this.controlledDevice].powerStatus !== value)
{
this.devices[this.controlledDevice].powerStatus = value;
ctl_debug(`Updated dev${logicalAddress} powerStatus using stdout to: ${value}`);
}
if(line.startsWith(`power status:`))
{
var logicalAddress = this.devices[this.controlledDevice].logicalAddress;
var value = this._getLineValue(line);

this.cec.emit(`${logicalAddress}:powerStatus`, value);
if(this.devices[this.controlledDevice].powerStatus !== value)
{
this.devices[this.controlledDevice].powerStatus = value;
ctl_debug(`Updated dev${logicalAddress} powerStatus using stdout to: ${value}`);
}
else if(this.devices.hasOwnProperty('dev0') && line.startsWith('TRAFFIC:'))

this.cec.emit(`${logicalAddress}:powerStatus`, value);
}
else if(this.devices.hasOwnProperty('dev0') && line.startsWith('TRAFFIC:'))
{
if(line.includes('>>'))
{
if(line.includes('>>'))
{
var destAddress = this.devices[this.myDevice].logicalAddress;
var value = this._getLineValue(line).toUpperCase();
var destAddress = this.devices[this.myDevice].logicalAddress;
var value = this._getLineValue(line).toUpperCase();

if(line.includes(`>> 0${destAddress}:44:`))
{
var keyName = keymap.getName(value);
if(line.includes(`>> 0${destAddress}:44:`))
{
var keyName = keymap.getName(value);

this.cec.emit('keypress', keyName);
this.cec.emit('keypress', keyName);

if(!this.keyReleaseTimeout)
this.cec.emit('keydown', keyName);
}
else if(line.includes(`>> 0${destAddress}:8b:`))
{
if(this.keyReleaseTimeout)
clearTimeout(this.keyReleaseTimeout);
if(!this.keyReleaseTimeout)
this.cec.emit('keydown', keyName);
}
else if(line.includes(`>> 0${destAddress}:8b:`))
{
if(this.keyReleaseTimeout)
clearTimeout(this.keyReleaseTimeout);

this.keyReleaseTimeout = setTimeout(() =>
{
this.cec.emit('keyup', keymap.getName(value));
this.keyReleaseTimeout = null;
}, 600);
}
else if(line.includes('>> 0f:36'))
this.keyReleaseTimeout = setTimeout(() =>
{
ctl_debug('Received standby request on broadcast');
ctl_debug('Checking devices powerStatus....');
this.cec.emit('keyup', keymap.getName(value));
this.keyReleaseTimeout = null;
}, 600);
}
else if(line.includes('>> 0f:36'))
{
ctl_debug('Received standby request on broadcast');
ctl_debug('Checking devices powerStatus....');

this._checkDevicesStatus(null, 'standby');
}
else if(line.includes('f:84:'))
this._checkDevicesStatus(null, 'standby');
}
else if(line.includes('f:84:'))
{
var logicalAddress = line.substring(line.indexOf('>> ') + 3, line.indexOf('f:84:'));
if(logicalAddress && logicalAddress.length === 1)
{
var logicalAddress = line.substring(line.indexOf('>> ') + 3, line.indexOf('f:84:'));
if(logicalAddress && logicalAddress.length === 1)
{
ctl_debug('Received report address request on broadcast');
var lineCmd = line.split('>> ')[1];

if(
this.devices.hasOwnProperty('dev' + logicalAddress)
&& this.devices['dev' + logicalAddress].address === 'f.f.f.f'
&& lineCmd.endsWith(`:0${logicalAddress}`)
) {
var addArr = lineCmd.substring(
lineCmd.indexOf('f:84:') + 5, lineCmd.indexOf(`:0${logicalAddress}`)
).split(':');

if(addArr.length === 2)
{
var newAddr = addArr[0].charAt(0) + '.' + addArr[0].charAt(1) +
'.' + addArr[1].charAt(0) + '.' + addArr[1].charAt(1);
ctl_debug('Received report address request on broadcast');
var lineCmd = line.split('>> ')[1];

if(
this.devices.hasOwnProperty('dev' + logicalAddress)
&& this.devices['dev' + logicalAddress].address === 'f.f.f.f'
&& lineCmd.endsWith(`:0${logicalAddress}`)
) {
var addArr = lineCmd.substring(
lineCmd.indexOf('f:84:') + 5, lineCmd.indexOf(`:0${logicalAddress}`)
).split(':');

if(addArr.length === 2)
{
var newAddr = addArr[0].charAt(0) + '.' + addArr[0].charAt(1) +
'.' + addArr[1].charAt(0) + '.' + addArr[1].charAt(1);

this.devices['dev' + logicalAddress].address = newAddr;
ctl_debug(`Updated dev${logicalAddress} address to: ${newAddr}`);
}
this.devices['dev' + logicalAddress].address = newAddr;
ctl_debug(`Updated dev${logicalAddress} address to: ${newAddr}`);
}

if(line.includes(`>> ${logicalAddress}f:84:`))
this._checkDevicesStatus(`dev${logicalAddress}`);
}
}
else if(line.includes('f:82:'))
{
var addArr = line.substring(line.indexOf('f:82:') + 5).split(':');
if(addArr.length === 2)
{
var detAddr = addArr[0].charAt(0) + '.' + addArr[0].charAt(1) +
'.' + addArr[1].charAt(0) + '.' + addArr[1].charAt(1);

for(var key in this.devices)
{
if(
typeof this.devices[key] === 'object'
&& this.devices[key].hasOwnProperty('activeSource')
&& this.devices[key].hasOwnProperty('address')
) {
if(
this.devices[key].address !== detAddr
&& this.devices[key].activeSource === 'yes'
) {
this.devices[key].activeSource = 'no';
ctl_debug(`Changed ${key} activeSource to: no`);
}
else if(
this.devices[key].address === detAddr
&& this.devices[key].activeSource === 'no'
) {
this.devices[key].activeSource = 'yes';
ctl_debug(`Changed ${key} activeSource to: yes`);
}
}
}
}
if(line.includes(`>> ${logicalAddress}f:84:`))
this._checkDevicesStatus(`dev${logicalAddress}`);
}
}
else if(line.includes('<<') && !this.togglingPower)
else if(line.includes('f:82:'))
{
var srcAddress = this.devices[this.myDevice].logicalAddress;
var destAddress = this.devices[this.controlledDevice].logicalAddress;

if(line.includes(`<< ${srcAddress}0:04`))
var addArr = line.substring(line.indexOf('f:82:') + 5).split(':');
if(addArr.length === 2)
{
var detAddr = addArr[0].charAt(0) + '.' + addArr[0].charAt(1) +
'.' + addArr[1].charAt(0) + '.' + addArr[1].charAt(1);

for(var key in this.devices)
{
if(
typeof this.devices[key] === 'object'
&& this.devices[key].hasOwnProperty('activeSource')
&& this.devices[key].activeSource === 'yes'
&& this.devices[key].hasOwnProperty('address')
) {
this.devices[key].activeSource = 'no';
ctl_debug(`Changed ${key} activeSource to: no`);
break;
if(
this.devices[key].address !== detAddr
&& this.devices[key].activeSource === 'yes'
) {
this.devices[key].activeSource = 'no';
ctl_debug(`Changed ${key} activeSource to: no`);
}
else if(
this.devices[key].address === detAddr
&& this.devices[key].activeSource === 'no'
) {
this.devices[key].activeSource = 'yes';
ctl_debug(`Changed ${key} activeSource to: yes`);
}
}
}

if(this.devices[this.myDevice].activeSource !== 'yes')
ctl_debug(`Updated dev${srcAddress} activeSource using stdout to: yes`);

this.devices[this.myDevice].activeSource = 'yes';
this.cec.emit(`${srcAddress}:activeSource`, 'yes');
}
else if(line.includes(`<< ${srcAddress}0:9d`))
{
if(this.devices[this.myDevice].activeSource !== 'no')
ctl_debug(`Updated dev${srcAddress} activeSource using stdout to: no`);
}
}
else if(line.includes('<<') && !this.togglingPower)
{
var srcAddress = this.devices[this.myDevice].logicalAddress;
var destAddress = this.devices[this.controlledDevice].logicalAddress;

this.devices[this.myDevice].activeSource = 'no';
this.cec.emit(`${srcAddress}:activeSource`, 'no');
}
else if(line.includes(`<< ${srcAddress}${destAddress}:44`))
if(line.includes(`<< ${srcAddress}0:04`))
{
for(var key in this.devices)
{
var value = this._getLineValue(line).toUpperCase();
var keyName = keymap.getName(value);

ctl_debug(`Send "${keyName}" key to dev${destAddress}`);
this.cec.emit('sendKey', keyName);
if(
typeof this.devices[key] === 'object'
&& this.devices[key].hasOwnProperty('activeSource')
&& this.devices[key].activeSource === 'yes'
) {
this.devices[key].activeSource = 'no';
ctl_debug(`Changed ${key} activeSource to: no`);
break;
}
}

if(this.devices[this.myDevice].activeSource !== 'yes')
ctl_debug(`Updated dev${srcAddress} activeSource using stdout to: yes`);

this.devices[this.myDevice].activeSource = 'yes';
this.cec.emit(`${srcAddress}:activeSource`, 'yes');
}
else if(line.includes(`<< ${srcAddress}0:9d`))
{
if(this.devices[this.myDevice].activeSource !== 'no')
ctl_debug(`Updated dev${srcAddress} activeSource using stdout to: no`);

this.devices[this.myDevice].activeSource = 'no';
this.cec.emit(`${srcAddress}:activeSource`, 'no');
}
else if(line.includes(`<< ${srcAddress}${destAddress}:44`))
{
var value = this._getLineValue(line).toUpperCase();
var keyName = keymap.getName(value);

ctl_debug(`Send "${keyName}" key to dev${destAddress}`);
this.cec.emit('sendKey', keyName);
}
}
});
}
}

_getLineValue(line)
Expand Down

0 comments on commit 25e2c4a

Please sign in to comment.