Skip to content

Commit

Permalink
Added some basic debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafostar committed Jul 25, 2019
1 parent 9dec1cd commit 97bca27
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
101 changes: 82 additions & 19 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 debug = require('debug')('cec-controller');
const getKeyName = require('./keymap');

module.exports = class Client
Expand All @@ -17,8 +18,9 @@ module.exports = class Client
this.controlledDevice = 'dev0';
this.sourceNumber = 0;
this.keyReleaseTimeout = null;
this.togglingPower = false;

this.cec = new EventEmitter()
this.cec = new EventEmitter();
this.myDevice = null;
this.devices = {};

Expand All @@ -29,25 +31,42 @@ module.exports = class Client

_scanDevices()
{
debug('Performing initial devices scan...');

exec(`echo scan | cec-client -s -t ${this.type} -o ${this.osdString} -d 1`,
{ maxBuffer: 5 * 1024 * 1024, windowsHide: true }, (error, stdout, stderr) =>
{
if(error) return this.cec.emit('error', new Error('App cec-client had an error!'));
if(error)
{
debug(error);
return this.cec.emit('error', new Error('App cec-client had an error!'));
}

debug('Devices scan finished successfully');
this.devices = this._parseScanOutput(String(stdout));

const scannedKeys = Object.keys(this.devices);
if(scannedKeys.length === 0)
return this.cec.emit('error', new Error('CEC scan did not find any devices!'));
{
const scanErr = new Error('CEC scan did not find any devices!');
debug(scanErr);
return this.cec.emit('error', scanErr);
}

this.myDevice = this._getMyDevice(this.devices);
if(!this.myDevice)
return this.cec.emit('error', new Error(`Could not obtain this CEC adapter info!`));
{
const myDeviceErr = new Error(`Could not obtain this CEC adapter info!`);
debug(myDeviceErr);
return this.cec.emit('error', myDeviceErr);
}

for(var deviceId in this.devices)
this.devices[deviceId] = { ...this.devices[deviceId], ...this._getDeviceFunctions(deviceId) };

this.devices = { ...this.devices, ...this._getGlobalFunctions() };
debug('Finished controller object assembly');
debug(this.devices);

this._createClient();
});
Expand Down Expand Up @@ -108,10 +127,12 @@ module.exports = class Client

if(currObj.hasOwnProperty('osdString') && currObj.osdString === this.osdString)
{
debug(`Detected this device as: ${key}`);
return key;
}
}

debug('Could not detect this device!');
return null;
}

Expand All @@ -123,9 +144,12 @@ module.exports = class Client
{ stdio: ['pipe', 'pipe', 'ignore'] });

this.client.stdin.setEncoding('utf8');
this.client.stdout.once('data', () => debug('cec-client background process started'));
this.client.stdout.on('data', (data) => this._parseClientOutput(String(data)));
this.client.once('close', (code) =>
{
debug(`cec-client exited with code: ${code}`);

if(this.doneInit) this._createClient();
else this.cec.emit('error', new Error(`App cec-client exited with code: ${code}`));
});
Expand All @@ -138,18 +162,24 @@ module.exports = class Client
if(this.myDevice && line.includes('waiting for input'))
{
this.doneInit = true;
debug('cec-client init successful');
this.cec.emit('ready', this.devices);
}

return;
}

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

this.devices[this.controlledDevice].powerStatus = value;
if(this.devices[this.controlledDevice].powerStatus !== value)
{
debug(`Updated dev${logicalAddress} powerStatus using stdout to: ${value}`);
this.devices[this.controlledDevice].powerStatus = value;
}

this.cec.emit(`${logicalAddress}:powerStatus`, value);
}
else if(line.startsWith('TRAFFIC:') && line.includes('>>'))
Expand Down Expand Up @@ -178,18 +208,19 @@ module.exports = class Client
}
else if(line.startsWith('TRAFFIC:') && line.includes('<<'))
{
var logicalAddress = this.devices[this.myDevice].logicalAddress;
var srcAddress = this.devices[this.myDevice].logicalAddress;

if(line.includes(`<< ${srcAddress}0:04`))
{
debug(`Updated dev${srcAddress} activeSource using stdout to: yes`);
this.devices[this.myDevice].activeSource = 'yes';
this.cec.emit(`${logicalAddress}:activeSource`, 'yes');
this.cec.emit(`${srcAddress}:activeSource`, 'yes');
}
else if(line.includes(`<< ${srcAddress}0:9d`))
{
debug(`Updated dev${srcAddress} activeSource using stdout to: no`);
this.devices[this.myDevice].activeSource = 'no';
this.cec.emit(`${logicalAddress}:activeSource`, 'no');
this.cec.emit(`${srcAddress}:activeSource`, 'no');
}
}
}
Expand Down Expand Up @@ -246,8 +277,14 @@ module.exports = class Client
if(!action || typeof action !== 'string') resolve(null);
else
{
if(!logicalAddress) this.client.stdin.write(action);
else this.client.stdin.write(`${action} ${logicalAddress}`);
var cmd = '';
if(logicalAddress) cmd = `${action} ${logicalAddress}`;
else cmd = action;

if(!this.togglingPower)
debug(`Running command: ${cmd}`);

this.client.stdin.write(cmd);

this.client.stdout.once('data', () => resolve(true));
}
Expand All @@ -263,7 +300,11 @@ module.exports = class Client
this.getStatus(deviceId).then(value =>
{
if(value === null) resolve(null);
else if(value === powerStatus) resolve(powerStatus);
else if(value === powerStatus)
{
debug(`${deviceId} powerStatus is already in desired state`);
resolve(powerStatus);
}
else
{
this.command(powerStatus, this.devices[deviceId].logicalAddress);
Expand All @@ -279,12 +320,23 @@ module.exports = class Client
return waitPower();

clearTimeout(actionTimeout);

if(timedOut) resolve(null);
else resolve(powerStatus);
this.togglingPower = false;

if(timedOut)
{
debug(`${deviceId} powerStatus change timed out!`);
resolve(null);
}
else
{
debug(`${deviceId} powerStatus changed to: ${powerStatus}`);
resolve(powerStatus);
}
});
}

debug(`Waiting for ${deviceId} powerStatus change to: ${powerStatus}`);
this.togglingPower = true;
waitPower();
}
});
Expand All @@ -305,14 +357,16 @@ module.exports = class Client

var statusTimeout = setTimeout(() =>
{
this.devices[this.myDevice].activeSource = 'Unknown';
debug(`dev${logicalAddress} activeSource change timed out!`);
this.devices[this.myDevice].activeSource = null;
this.cec.emit(`${logicalAddress}:activeSource`, null);
}, 3000);
}, 5000);

this.command(action, null);
this.cec.once(`${logicalAddress}:activeSource`, (value) =>
{
clearTimeout(statusTimeout);
debug(`dev${logicalAddress} activeSource changed to: ${value}`);
resolve(value);
});
}
Expand All @@ -329,14 +383,23 @@ module.exports = class Client

var statusTimeout = setTimeout(() =>
{
this.devices[deviceId].powerStatus = 'Unknown';
if(!this.togglingPower)
{
debug(`dev${logicalAddress} getStatus timed out!`);
this.devices[deviceId].powerStatus = null;
}

this.cec.emit(`${logicalAddress}:powerStatus`, null);
}, 3000);
}, 5000);

this.command(`pow ${logicalAddress}`);
this.cec.once(`${logicalAddress}:powerStatus`, (value) =>
{
clearTimeout(statusTimeout);

if(!this.togglingPower)
debug(`dev${logicalAddress} powerStatus is: ${value}`);

resolve(value);
});
});
Expand Down
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@
"bugs": {
"url": "https://github.com/Rafostar/cec-controller/issues"
},
"homepage": "https://github.com/Rafostar/cec-controller#readme"
"homepage": "https://github.com/Rafostar/cec-controller#readme",
"dependencies": {
"debug": "^4.1.1"
}
}
4 changes: 2 additions & 2 deletions test/power.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ function test(obj)

writeLine('');
console.log('--- TV Power Test ---');
writeLine('Turning OFF in 15 sec...');
setTimeout(() => powerOff(ctl), 15000);
writeLine('Turning OFF in 30 sec...');
setTimeout(() => powerOff(ctl), 30000);
}

async function powerOff(ctl)
Expand Down

0 comments on commit 97bca27

Please sign in to comment.