Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Enable Control Accessory #111

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ This project provides a bridge which 'exposes' your devices in a way that you ca
* motion sensors
* security presence detectors
* trigger events
* enable events
* contact sensors
* smoke Sensor
* temperature sensors
Expand Down Expand Up @@ -93,7 +94,7 @@ You must register devices by hand in a config file, however to make this easier

The platform definition in the `config.json` file contains an `accessories` array, which defines the available accessories using the following keys:

* `type`: (required) type of the accessory. The valid values are "light", "switch", "dimmer", "shutter", "motion", "security", "trigger" and "contact".
* `type`: (required) type of the accessory. The valid values are "light", "switch", "dimmer", "shutter", "motion", "security", "trigger", enablecontrol" and "contact".
* `name`: (required) name of the accessory (e.g. "Living Room Light", "Bedroom Light", "Living Room Curtain" etc.)
* `network`: (optional, defaults to `client_network`) C-Bus network address of the device
* `application`: (optional, defaults to `client_application`) The C-Bus Application address of the device
Expand All @@ -102,7 +103,7 @@ The platform definition in the `config.json` file contains an `accessories` arra
* `activeDuration`: (optional) only used by the switch accessory, indicating a timeout period, after which the switch will automatically switch off. This allows a HomeKit switch accessory to be used to generate a *Bell Press* event.
* `rampDuration`: (optional, maximum 17 minutes) only used by the dimmer accessory, indicating the ramp up/down time when dimming.
* `enabled`: (optional, default: true) set to false to inhibit the accessory from loading.
* `action`: (required by the trigger accessory) sets the action selector to be triggered.
* `action`: (required by the trigger and enablecontrol accessories) sets the action selector to be triggered/enabled.

(NB. Durations can be specified in days, hours, minutes, seconds or milliseconds. (eg.: "2 days", "2.5h", "5s", "100 ms", etc. ) For more information on allowable formats, please see the [ms library](https://github.com/zeit/ms))

Expand Down Expand Up @@ -155,6 +156,8 @@ The platform definition in the `config.json` file contains an `accessories` arra

{ "type": "trigger", "application": 202, "id": 0, "action": 1, "name": "recall preset 2" },

{ "type": "enablecontrol", "application": 203, "id": 0, "action": 1, "name": "enable sensor" },

{ "type": "temperature", "id": 245, "application": 228, "channel": 1, "name": "Living Room Temperature" },

{ "type": "contact","id": 5, "name": "Bedroom Window" },
Expand Down Expand Up @@ -217,6 +220,9 @@ npm run test-coverage
````

## Changes Since 0.5.0

* 0.6.6 adds support for `enablecontrol` accessory

* 0.6.5: adds support for `contact` accessory

* 0.6.4: adds support for `trigger` accessory
Expand Down
62 changes: 62 additions & 0 deletions accessories/enable-accessory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict';

let Service;
let Characteristic;
let CBusAccessory;
let uuid;

const chalk = require('chalk');

const ms = require('ms');

const cbusUtils = require('../lib/cbus-utils.js');

const FILE_ID = cbusUtils.extractIdentifierFromFileName(__filename);

module.exports = function (_service, _characteristic, _accessory, _uuid) {
Service = _service;
Characteristic = _characteristic;
CBusAccessory = _accessory;
uuid = _uuid;

return CBusEnableAccessory;
};

function CBusEnableAccessory(platform, accessoryData) {
// initialize the parent
CBusAccessory.call(this, platform, accessoryData);

try {
this.action = cbusUtils.integerise(accessoryData.action);
} catch (err) {
throw new Error(`action value '${accessoryData.action}' for accessory '${this.name} is not an integer`);
}

// register the on-off service
this.service = this.addService(new Service.Switch(this.name));
this.service.getCharacteristic(Characteristic.On)
.on('set', this.setEnable.bind(this));
}

CBusEnableAccessory.prototype.setEnable = function (enable, callback, context) {
if (context === `event`) {
// context helps us avoid a never-ending loop
callback();
} else {
console.assert((enable === 1) || (enable === 0) || (enable === true) || (enable === false));
if (enable) {
this.client.enableAction(this.netId, this.action, () => {
this.timeout = setTimeout(() => {
this.service.getCharacteristic(Characteristic.On).setValue(0);
}, 500);
});
}
callback();
}
};

CBusEnableAccessory.prototype.processClientData = function (err, message) {
if (!err) {
console.assert(typeof message.level !== `undefined`, `message.level must be defined`);
}
};
9 changes: 6 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ module.exports = function (homebridge) {
const CBusFanAccessory = require('./accessories/fan-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusSwitchAccessory = require('./accessories/switch-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusTriggerAccessory = require('./accessories/trigger-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusSmokeAccessory = require('./accessories/smoke-sensor-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusEnableAccessory = require('./accessories/enable-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusSmokeAccessory = require('./accessories/smoke-sensor-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusContactAccessory = require('./accessories/contact-accessory.js')(Service, Characteristic, CBusAccessory, uuid);
const CBusTemperatureAccessory = require('./accessories/temperature-accessory.js')(Service, Characteristic, CBusAccessory, uuid);

Expand All @@ -49,7 +50,8 @@ module.exports = function (homebridge) {
cbusUtils.fixInheritance(CBusFanAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusSwitchAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusTriggerAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusSmokeAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusEnableAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusSmokeAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusContactAccessory, CBusAccessory);
cbusUtils.fixInheritance(CBusTemperatureAccessory, CBusAccessory);

Expand All @@ -66,7 +68,8 @@ module.exports = function (homebridge) {
fan: CBusFanAccessory,
switch: CBusSwitchAccessory,
trigger: CBusTriggerAccessory,
smoke: CBusSmokeAccessory,
enablecontrol: CBusEnableAccessory,
smoke: CBusSmokeAccessory,
contact: CBusContactAccessory,
temperature: CBusTemperatureAccessory,
};
Expand Down
8 changes: 7 additions & 1 deletion lib/cgate-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ CBusClient.prototype.triggerAction = function (netId, action, callback) {
const cmd = this._buildSetCommandString(netId, 'trigger', action);
this._sendMessage(cmd, callback);
};
CBusClient.prototype.enableAction = function (netId, action, callback) {
const cmd = this._buildSetCommandString(netId, 'enable', action);
this._sendMessage(cmd, callback);
};

CBusClient.prototype.receiveSecurityStatus = function (netId, callback) {
const cmd = this._buildGetCommandString(netId, 'zonestate');
Expand Down Expand Up @@ -269,7 +273,7 @@ CBusClient.prototype._buildGetCommandString = function (netId, command, comment)
};

CBusClient.prototype._buildSetCommandString = function (netId, command, level, duration, comment, data) {
console.assert(command.match(/^(on|off|ramp|trigger|data)$/), `command not one of on|off|ramp|trigger|data`);
console.assert(command.match(/^(on|off|ramp|trigger|enable|data)$/), `command not one of on|off|ramp|trigger|enable|data`);

let message;

Expand All @@ -279,6 +283,8 @@ CBusClient.prototype._buildSetCommandString = function (netId, command, level, d
message = `off ${netId}`;
} else if (command === 'trigger') {
message = `trigger event ${netId} ${level}`;
} else if (command === 'enable') {
message = `enable set ${netId} ${level}`;
} else if (command === 'ramp') {
console.assert(level <= 100, `level ${level} not in range 0..100`);
message = `ramp ${netId} ${level}%`;
Expand Down
15 changes: 15 additions & 0 deletions test/cgate-client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,21 @@ const TEST_DESCRIPTORS = [
matched: true,
processed: true
}
},
{
name: `[110] enableEvent`,
clientAction: function () {
gClient.enableAction(CBusNetId.parse(`//EXAMPLE/254/203/1`), 0);
},
fromClient: `[110] enable set //EXAMPLE/254/203/1 0`,
fromServer: `[110] 200 OK: //EXAMPLE/254/203/1`,
expected: {
type: `response`,
commandId: 110,
code: 200,
matched: true,
processed: true
}
}
];

Expand Down