Skip to content

Commit

Permalink
[IMPROVE] Verify strictly the value of the service and characteristic…
Browse files Browse the repository at this point in the history
…s elements on the config.json.
  • Loading branch information
Patineboot committed Jun 29, 2022
1 parent 5db5318 commit 63c9398
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,5 +301,5 @@ I am tired of updating my command to only fit his CMD4 anymore.
1. Install

```bash
sudo npm -g install ./runnable-platform/
sudo npm --location=global install ./runnable-platform/
```
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"private": false,
"displayName": "Homebridge RunnablePlatform",
"name": "homebridge-runnable-platform",
"version": "0.9.7",
"version": "0.9.8",
"description": "RunnablePlatform provide connections using your Custom-Command command between infrared devices and Homebridge.",
"license": "CC BY-NC-ND 4.0",
"repository": {
Expand Down
6 changes: 3 additions & 3 deletions src/Lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ export class Lock {
* Wait on the release if anyone has acquired it already.
*/
acquire() {
return new Promise((resolve) => {
return new Promise((resolve, _reject) => {

const notifier = () => {
if (!this.#acquired) {
this.#acquired = true;
this.#eventEmitter.removeListener('released', notifier);
return resolve();
return resolve('dummy');
}
}

if (!this.#acquired) {
this.#acquired = true;
return resolve();
return resolve('dummy');
}
this.#eventEmitter.on('released', notifier);
});
Expand Down
24 changes: 9 additions & 15 deletions src/RunnableAccessory.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,17 @@ export class RunnableAccessory {
constructor(accessoryConfig) {
LOG.debug(`Enter ${this.constructor.name}: ${accessoryConfig} -> name: ${accessoryConfig.name}`);

try {
this.#lock = new Lock();
this.#lock = new Lock();

this.#accessoryConfig = accessoryConfig;
this.#accessoryConfig = accessoryConfig;

const comm = Communicator.getInstance();
comm.on('message', (message) => {
if (message.name !== this.name) {
return;
}
this.updateCharacteristic(message.characteristic, message.value);
});
}
catch (error) {
LOG.info(`${this.constructor.name}: ${accessoryConfig} -> name: ${accessoryConfig.name}`);
throw error;
}
const comm = Communicator.getInstance();
comm.on('message', (message) => {
if (message.name !== this.name) {
return;
}
this.updateCharacteristic(message.characteristic, message.value);
});
}

/**
Expand Down
91 changes: 70 additions & 21 deletions src/RunnablePlatform.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,15 @@ export class RunnablePlatform {
}
});

// verify the my 'platform' element on the config.json file.
if (!this.#verifyElement(CONFIG)) {
// verify the RunnablePlatform platform element of the platforms element on the config.json file.
try {
this.#verifyConfig(CONFIG);
}
catch (error) {
this.#skeletonMode = true;
LOG.warn('Missing the mandatory element[s] of RunnablePlatform.');
LOG.warn('Add the mandatory elements of RunnablePlatform to the Config of Homebridge.');
LOG.error('RunnablePlatform found the incorrected element on the config.json file.');
LOG.error(error);
LOG.error("Correct your description of the RunnablePlatform platform element.");
return;
}

Expand Down Expand Up @@ -198,43 +202,88 @@ export class RunnablePlatform {
Communicator.getInstance().connect();
}


/**
* @param {import("homebridge").PlatformConfig} config
* @returns {boolean}
* @returns {boolean} true if config is corrected.
* @throws {Error} occur if config is invalid.
*/
#verifyConfig(config) {
const platResult = this.#verifyPlatform(config);

let accResult = false;
for (let configAccessory of config.accessories) {
accResult = this.#verifyAccessory(configAccessory);
}

return platResult && accResult;
}

/**
* @param {import("homebridge").PlatformConfig} configPlatform
* @returns {boolean} always true.
* @throws {Error} occur if configPlatform is invalid.
*/
#verifyElement(config) {
#verifyPlatform(configPlatform) {
// the platform element must have the these elements on config file.
if (!('run' in config &&
'time' in config &&
'accessories' in config)) {
LOG.error("missing the 'run', 'time', or 'accessories' elements in the platform element on the config file.");
return false;
if (!('run' in configPlatform &&
'time' in configPlatform &&
'accessories' in configPlatform)) {
throw new Error(
"missing the 'run', 'time', or 'accessories' elements in the platform element on the config file."
);
}

LOG.info(`${PLATFORM_NAME} element has them on config.json`);
LOG.info(' name: ' + config.name);
LOG.info(' run: ' + config.run);
LOG.info(' time(ms): ' + config.time);
LOG.info(' accessories length: ' + config.accessories.length);
LOG.info(' name: ' + configPlatform.name);
LOG.info(' run: ' + configPlatform.run);
LOG.info(' time(ms): ' + configPlatform.time);
LOG.info(' accessories length: ' + configPlatform.accessories.length);

// an element of the 'accessories' array must have the these elements on config file.
const corrects = config.accessories
const corrects = configPlatform.accessories
.filter((/** @type {any} */ acc) => 'name' in acc)
.filter((/** @type {any} */ acc) => 'service' in acc)
.filter((/** @type {any} */ acc) => 'characteristics' in acc);

if (corrects.length != config.accessories.length) {
LOG.error("missing the 'name', 'service', or 'characteristics' element on the config file.");
return false;
if (corrects.length != configPlatform.accessories.length) {
throw new Error(
"missing the 'name', 'service', or 'characteristics' element on the config file."
);
}

return true;
}

/**
* @param {any} configAccessory
* @returns {boolean} always true
* @throws {Error} occur if configAccessory is invalid.
*/
#verifyAccessory(configAccessory) {
const serviceResult = configAccessory.service in HAPI.hap.Service;
if (!serviceResult) {
throw new Error(
`Found the incorrected service name on the config file: "${configAccessory.service}"`
);
}

let charaResult = false;
for (let characteristic of configAccessory.characteristics) {
charaResult = characteristic in HAPI.hap.Characteristic;
if (!charaResult) {
throw new Error(
`Found the incorrected characteristic name on the config file: "${characteristic}"`
);
}
}
return serviceResult && charaResult;
}

#startServices() {
// start the services of the accessories described on the config file.
for (let configAccessory of CONFIG.accessories) {



// create the device accessory from the config
const runnable = new RunnableAccessory(configAccessory);
let accessory = this.#findAccessory(configAccessory.name);
Expand Down

0 comments on commit 63c9398

Please sign in to comment.