homebridge-risco-platform
Version:
RiscoAlarm Plugin Platform for Homebridge
631 lines (607 loc) • 38.2 kB
JavaScript
'use strict';
//const fs = require('fs');
const risco = require('./Risco');
const riscoAccessory = require('./RiscoAccessories');
var pjson = require('./package.json');
let Manufacturer = 'Gawindx';
const pluginName = 'homebridge-risco-platform';
const platformName = 'RiscoAlarm';
let hap;
let Service, Characteristic, UUIDGen;
const JSONreplacer = () => {
const visited = new WeakSet();
return (key, value) => {
if (typeof value === 'object' && value !== null) {
if (visited.has(value)) {
return;
}
visited.add(value);
}
return value;
};
};
class RiscoPanelPlatform {
constructor(log, config, api) {
//Types of Custom Detector
this.Custom_Types = [ 'Detector',
'Door',
'Window',
'Contact Sensor',
'Vibrate Sensor',
'Smoke Sensor'
];
//Service Associated to Custom Types
this.Custom_Types_Services = {
'Detector': Service.MotionSensor,
'Door': Service.Door,
'Window': Service.Window,
'Contact Sensor': Service.ContactSensor,
'Vibrate Sensor': Service.MotionSensor,
'Smoke Sensor': Service.SmokeSensor
};
//Classes Associated to Custom Types
this.Custom_Types_Classes = {
'Detector': 'RiscoCPDetectors',
'Door': 'RiscoCPCDoor',
'Window': 'RiscoCPCWindow',
'Contact Sensor': 'RiscoCPCContactSensor',
'Vibrate Sensor': 'RiscoCPCVibrateSensor',
'Smoke Sensor': 'RiscoCPCSmokeSensor'
}
//Types Of Combined Accessoies
this.Combined_Types = [ 'Combined_GarageDoor',
'Combined_Door',
'Combined_Window'
];
//Service Associated to Combined Types
this.Combined_Types_Services = {
'Combined_GarageDoor': Service.GarageDoorOpener,
'Combined_Door': Service.Door,
'Combined_Window': Service.Window
};
//Classes Associated to Combined Types
this.Combined_Types_Classes = {
'Combined_GarageDoor': 'RiscoCPCombGarageDoor',
'Combined_Door': 'RiscoCPCombDoor',
'Combined_Window': 'RiscoCPCombWindows'
}
this.accessories = [];
this.log = log;
this.config = config;
this.api = api;
this.DiscoveredAccessories = {};
this.Devices = [];
this.DiscoveryFinished = false;
this.hasCachedAccessory = false;
if (!api || !config) return;
if (!config.riscoUsername || !config.riscoPassword || !config.riscoSiteId || !config.riscoPIN) {
this.log.error('Insufficient credentials in config.json:');
if (!config.riscoUsername) { this.log.error('riscoUsername'); }
if (!config.riscoPassword) { this.log.error('riscoPassword'); }
if (!config.riscoSiteId) { this.log.error('riscoSiteId'); }
if (!config.riscoPIN) { this.log.error('riscoPIN'); }
return;
}
this.RiscoPanel = new risco.RiscoPanelSession(this.config, this.log, this.api);
this.log.info('RiscoPanelPlatform finished initializing!');
//Monitor Change on Config File (future usage)
//MAke Accessory more dynamic without reload homebridge
/*fs.watchFile(api.user.configPath(), (curr, prev) => {
if (curr.mtime !== prev.mtime) {
this.log.debug("Configuration File Modified");
}
});*/
api.on('didFinishLaunching', () => {
this.log.info('RiscoPanelPlatform Initial Discovery Phase');
setTimeout( async () => {
this.log.info('Accessories Init Phase Started');
await this.DiscoverAccessoriesFromRiscoCloud()
.catch( e => {
this.log.error('Error on Discovery Phase : %s',e);
});
this.log.debug('Discovered Accessories:\n%s', JSON.stringify(this.DiscoveredAccessories, JSONreplacer(), 4));
this.log.info('PreConf Phase Started');
try {
if (Object.keys(this.DiscoveredAccessories).length != 0) {
for (var DeviceFamily in this.DiscoveredAccessories) {
this.PreConfigureAccessories(DeviceFamily);
}
this.DiscoveryFinished = true;
}
} catch (err) {
this.log.error('Error on PreConf Phase: %s', err);
}
this.log.debug('PreConfigured Accessories:\n%s', JSON.stringify(this.DiscoveredAccessories, JSONreplacer(), 4));
this.log.info('PreConf Phase Ended');
this.log.info('Create Accessory Phase Started');
this.log.debug('Devices:\n%s', JSON.stringify(this.Devices, JSONreplacer(), 4));
try {
if (Object.keys(this.DiscoveredAccessories).length != 0) {
if (this.hasCachedAccessory) {
await new Promise(r => setTimeout(r, 5000));
}
for (var DiscoveredAcc in this.Devices) {
this.addAccessory(this.Devices[DiscoveredAcc]);
}
this.RiscoPanel.Ready = true;
}
} catch (err) {
this.log.error('Error on Create Accessory Phase :\n%s' + err);
}
this.log.info('Accessories Init Phase Ended');
//prune Unused accessories
if (this.RiscoPanel.Ready) {
for (const accessory of this.accessories) {
if ((accessory.context.todelete !== undefined) && (accessory.context.todelete === true)) {
this._removeAccessory(accessory);
}
}
}
}, 5000);
});
}
configureAccessory(accessory) {
var self = this;
this.hasCachedAccessory = true;
accessory.on('identify', function accidentify() {
this.log.debug('%s identified!', accessory.displayName);
//avoid warning on maxEventListener
accessory.removeListener('identify', accidentify);
});
if (this.DiscoveryFinished) {
var KeepAccessory = false;
this.log.info('Restoring or Set Removing accessory %s', accessory.displayName);
this.Devices.filter(new_device => ((new_device.context.longName == accessory.context.longName) && (new_device.context.Required == true)))
.map(new_device => {
self.log.debug('Device to reconfigure:\n%s',JSON.stringify(new_device, JSONreplacer(), 4));
self._addOrConfigure(accessory, new_device, accessory.context.accessorytype, false);
KeepAccessory = true;
});
this.accessories.push(accessory);
this.api.updatePlatformAccessories([accessory]);
if (!(KeepAccessory)) {
this.log.debug('Set to Remove accessory %s', accessory.displayName);
accessory.context.todelete = true;
}
} else {
setTimeout(this.configureAccessory.bind(this, accessory), 1000);
}
}
addAccessory(DiscoveredAcc) {
let uuid = UUIDGen.generate(DiscoveredAcc.context.longName);
let accessory = new this.api.platformAccessory(DiscoveredAcc.context.name, uuid);
accessory.context = DiscoveredAcc.context;
if ((this.accessories.filter(device => (device.UUID == uuid))).length == 0) {
this.log.debug('PreConfigured Accessories To configure:\n%s', JSON.stringify(DiscoveredAcc, JSONreplacer(), 4));
this.log.info('Adding new accessory with Name: %s, Id: %s, type: %s', DiscoveredAcc.context.name, DiscoveredAcc.context.Id, DiscoveredAcc.context.accessorytype);
this._addOrConfigure(accessory, DiscoveredAcc, DiscoveredAcc.context.accessorytype, true);
this.accessories.push(accessory);
this.api.registerPlatformAccessories(pluginName, platformName, [accessory]);
}
}
_addOrConfigure(accessory, object, type, add) {
if (type !== object.context.accessorytype) {
this.log.debug('Accessory: %s Modified Since Last Run', object.context.name);
add = true;
if (this.Custom_Types.includes(type)) {
accessory.removeService(accessory.getService(this.Custom_Types_Services[type]));
} else if (this.Combined_Types.includes(type)) {
accessory.removeService(accessory.getService(this.Combined_Types_Services[type]));
}
accessory.context.accessorytype = type = object.context.accessorytype;
}
if ((add) || (accessory.getService(Service.AccessoryInformation) === undefined)) {
this.log.debug('AddOrConfigure Accessory: %s', object.context.name);
accessory.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Name, object.context.name)
.setCharacteristic(Characteristic.Identify, object.context.name)
.setCharacteristic(Characteristic.Manufacturer, Manufacturer)
.setCharacteristic(Characteristic.Model, object.context.longName)
.setCharacteristic(Characteristic.SerialNumber, pjson.version)
.setCharacteristic(Characteristic.FirmwareRevision, pjson.version);
}
if ((accessory.getService(Service.AccessoryInformation).getCharacteristic(Characteristic.SerialNumber).value) != pjson.version) {
//do some stuff on update accessory from older version of plugin
accessory.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.SerialNumber, pjson.version)
.setCharacteristic(Characteristic.FirmwareRevision, pjson.version);
}
switch (type) {
case 'System':
case 'Partitions':
if (add) {
accessory.addService(Service.SecuritySystem, accessory.context.name);
if (this.config['OccupancyPreventArming'] || true) {
accessory.addService(Service.OccupancySensor, `Occupancy ${accessory.displayName}`, `occupancy_${accessory.context.name}`);
}
} else {
this.log.info('Configuring accessory %s', accessory.displayName);
if (object.Occupancy) {
if (accessory.getService(Service.OccupancySensor) == undefined ){
this.log.debug('Occupancy Service not already defined on accessory %s', accessory.displayName);
this.log.error('Occupancy Service not already defined on accessory %s', accessory.displayName);
accessory.addService(Service.OccupancySensor, `Occupancy ${accessory.displayName}`, `occupancy_${accessory.context.name}`);
}
} else if (!(this.config['OccupancyPreventArming'] || true )) {
if (accessory.getService(Service.OccupancySensor) != undefined ){
this.log.debug('Occupancy Service Defined but not needed on accessory %s', accessory.displayName);
this.log.error('Occupancy Service Defined but not needed on accessory %s', accessory.displayName);
accessory.removeService(Service.OccupancySensor);
}
}
}
new riscoAccessory.RiscoCPPartitions(this.log, object, this.api, accessory);
break;
case 'Groups':
if (add) {
accessory.addService(Service.SecuritySystem, accessory.context.name);
} else {
this.log.info('Configuring accessory %s_%s', accessory.displayName, type);
}
new riscoAccessory.RiscoCPGroups(this.log, object, this.api, accessory);
break;
case 'Outputs':
if (add) {
accessory.addService(Service.Switch, accessory.context.name);
} else {
this.log.info('Configuring accessory %s_%s', accessory.displayName, type);
}
new riscoAccessory.RiscoCPOutputs(this.log, object, this.api, accessory);
break;
default:
if (this.Custom_Types.includes(type)) {
if (add) {
this.log.info('Add or Modifying accessory %s', accessory.displayName);
for (var AccTypes in this.Custom_Types_Services) {
if ((AccTypes != type) && (accessory.getService(this.Custom_Types_Services[AccTypes]) !== undefined)) {
this.log.debug('Service %s already defined on accessory %s', AccTypes, accessory.displayName);
this.log.debug('This service is not required anymore ; remove it');
accessory.removeService(accessory.getService(this.Custom_Types_Services[AccTypes]));
}
}
if (accessory.getService(this.Custom_Types_Services[type]) === undefined ) {
this.log.debug('Service %s not already defined on accessory %s', type, accessory.displayName);
accessory.addService(this.Custom_Types_Services[type], accessory.context.name);
//remove also ExcludeSwitch because he became first Service
if (accessory.getService(`Exclude ${accessory.displayName}`) !== undefined ) {
this.log.debug('Service Exclude already defined on accessory %s', accessory.displayName);
this.log.debug('Remove it to avoid he became first Service');
accessory.removeService(accessory.getService(`Exclude ${accessory.displayName}`));
}
}
if (accessory.getService(Service.Switch) === undefined ) {
this.log.debug('Service Exclude not already defined on accessory %s', accessory.displayName);
accessory.addService(Service.Switch, `Exclude ${accessory.displayName}`, `exclude_${accessory.context.name}`);
}
} else {
this.log.info('Configuring accessory %s',accessory.displayName);
if (accessory.getService(Service.Switch) === undefined ) {
this.log.debug('Service Exclude not already defined on accessory %s', accessory.displayName);
accessory.addService(Service.Switch, `Exclude ${accessory.displayName}`, `exclude_${accessory.context.name}`);
}
}
new riscoAccessory[this.Custom_Types_Classes[type]](this.log, object, this.api, accessory);
} else if (this.Combined_Types.includes(type)) {
if (add) {
this.log.info('Add or Modifying Combined accessory %s', accessory.displayName);
for (var AccTypes in this.Combined_Types_Services) {
if ((AccTypes != type) && (accessory.getService(this.Combined_Types_Services[AccTypes]) !== undefined)) {
this.log.debug('Service %s already defined on accessory %s', this.Combined_Types_Services[AccTypes], accessory.displayName);
this.log.debug('This service is not required anymore ; remove it');
accessory.removeService(accessory.getService(this.Combined_Types_Services[AccTypes]));
}
}
if (accessory.getService(this.Combined_Types_Services[type]) === undefined ) {
this.log.debug('Service %s not already defined on accessory %s', type, accessory.displayName);
accessory.addService(this.Combined_Types_Services[type], accessory.context.name);
//remove also ExcludeSwitch because he became first Service
if (accessory.getService(`Exclude ${accessory.displayName}`) !== undefined ) {
this.log.debug('Service Exclude already defined on accessory %s', accessory.displayName);
this.log.debug('Remove it to avoid he became first Service');
accessory.removeService(accessory.getService(`Exclude ${accessory.displayName}`));
}
}
if (accessory.getService(Service.Switch) === undefined ) {
this.log.debug('Service Exclude not already defined on accessory %s', accessory.displayName);
accessory.addService(Service.Switch, `Exclude ${accessory.displayName}`, `exclude_${accessory.context.name}`);
}
} else {
this.log.info('Configuring Combined accessory %s',accessory.displayName);
if (accessory.getService(Service.Switch) === undefined ) {
this.log.debug('Service Exclude not already defined on accessory %s', accessory.displayName);
accessory.addService(Service.Switch, `Exclude ${accessory.displayName}`, `exclude_${accessory.context.name}`);
}
}
new riscoAccessory[this.Combined_Types_Classes[type]](this.log, object, this.api, accessory);
}
break;
};
}
_removeAccessory(accessory) {
this.log.info('Removing accessory %s', accessory.displayName);
this.api.unregisterPlatformAccessories(pluginName, platformName, [accessory]);
}
async DiscoverAccessoriesFromRiscoCloud() {
this.log.info('Discovering Phase Started');
try{
let PanelDatas = await this.RiscoPanel.getCPStates();
if (((this.config['Partition'] || 'none') != 'none') && (PanelDatas.Partitions !== undefined)) {
this.log.debug('Discovering Partitions');
this.DiscoveredAccessories.Partitions = await this.RiscoPanel.DiscoverParts(PanelDatas.Partitions);
}
if (((this.config['Groups'] || 'none') != 'none') && (PanelDatas.Partitions !== undefined)) {
this.log.debug('Discovering Groups');
this.DiscoveredAccessories.Groups = await this.RiscoPanel.DiscoverGroups(PanelDatas.Partitions);
}
if ((this.config['Combined'] || 'none') != 'none') {
this.log.debug('Checks if the configuration is correct and consistent for the combined accessories');
//Check if all Combined Configuration are valid
var CombinedConf = {};
for (var Comb in this.config['Combined']) {
if (!((this.Combined_Types).includes(`Combined_${Comb}`))) {
continue;
}
const CombAccessories = this.config['Combined'][Comb];
var ValidComb = [];
for (var CombAcc in CombAccessories) {
if (!(isNaN(CombAccessories[CombAcc].In) || isNaN(CombAccessories[CombAcc].Out) || (!CombAccessories[CombAcc].In) || (!CombAccessories[CombAcc].Out))) {
ValidComb.push(CombAccessories[CombAcc]);
}
}
this.log.debug('Found %s Valid(s) Combined Definition in Combined Type: "%s"', Object.keys(ValidComb).length, Comb);
var self = this
CombinedConf[Comb] = ValidComb;
}
this.config['Combined'] = CombinedConf;
//now, check if all required Input/Output are defined
var TempOutConf = (this.config['Outputs'] || 'none');
var TempDetConf = (this.config['Detectors'] || 'none');
if ((TempOutConf != 'all') || (TempDetConf != 'all')) {
this.log.debug('The configuration may be not consistent for the combined accessories');
this.log.debug('Let\'s change it!');
var CombId = 0;
for (var Comb in this.config['Combined']) {
for (var CombAcc in this.config['Combined'][Comb]) {
CombId++;
this.log.debug('Found Valid Combined Device type: "%s". Assigned Id: %s', Comb, CombId);
const TempIn = this.config['Combined'][Comb][CombAcc].In;
const TempOut = this.config['Combined'][Comb][CombAcc].Out;
this.log.debug('This Combined Device require input Id: %s and Output Id: %s', TempIn, TempOut);
if (TempDetConf != "all") {
const Required_Detectors = TempDetConf.split(',').map( (item) => {
return parseInt(item, 10);
});
if (Required_Detectors.includes(Number(TempIn)) !== false) {
this.log.debug('Input Id: %s is already required. Do Nothing!', TempIn);
} else {
this.log.debug('Input Id: %s is not already required. Adding Them!', TempIn);
if (TempDetConf != "none") {
TempDetConf = TempDetConf.concat(',', `${TempIn}`);
} else {
TempDetConf = `${TempIn}`;
}
}
} else {
this.log.debug('All Inputs Id are already required. Do Nothing!');
}
if (TempOutConf != "all") {
const Required_Outputs = TempOutConf.split(',').map( (item) => {
return parseInt(item, 10);
});
if (Required_Outputs.includes(Number(TempOut)) !== false) {
this.log.debug('Output Id: %s is already required. Do Nothing!', TempOut);
} else {
this.log.debug('Output Id: %s is not already required. Adding Them!', TempOut);
if (TempOutConf != "none") {
TempOutConf = TempOutConf.concat(',', `${TempOut}`);
} else {
TempOutConf = `${TempOut}`;
}
}
} else {
this.log.debug('All Outputs Id are already required. Do Nothing!');
}
}
}
this.config['Detectors'] = TempDetConf;
this.config['Outputs'] = TempOutConf;
this.log.debug('New Configurations:\nDetectors: %s\nOutputs: %s', TempDetConf, TempOutConf);
} else {
this.log.debug('The configuration is consistent for the combined accessories');
}
}
if (((this.config['Outputs'] || 'none') != 'none') && (PanelDatas.Outputs !== undefined)){
this.log.debug('Discovering Outputs');
this.DiscoveredAccessories.Outputs = await this.RiscoPanel.DiscoverOutputs(PanelDatas.Outputs);
}
if (((this.config['Detectors'] || 'none') != 'none') && (PanelDatas.Detectors !== undefined)){
this.log.debug('Discovering Detectors');
this.DiscoveredAccessories.Detectors = await this.RiscoPanel.DiscoverDetectors(PanelDatas.Detectors);
}
/*if (((this.config['Cameras'] || 'none') != 'none') && (PanelDatas.Cameras !== undefined)) {
this.log.debug('Discovering Cameras');
this.DiscoveredAccessories.Cameras = await this.RiscoPanel.DiscoverCameras();
}*/
if (((this.config['Combined'] || 'none') != 'none') && (this.DiscoveredAccessories.Detectors !== undefined) && (this.DiscoveredAccessories.Outputs !== undefined)) {
this.log.debug('Combined accessories input/output cannot be used as simple accessories. Remove Them from required accessories');
var Combined_Datas = {};
var CombId = 0;
for (var Comb in this.config['Combined']) {
for (var CombAcc in this.config['Combined'][Comb]) {
const CombInId = this.config['Combined'][Comb][CombAcc].In;
const CombOutId = this.config['Combined'][Comb][CombAcc].Out;
CombId++;
const Detector_Data = Object.values(JSON.parse(JSON.stringify(this.DiscoveredAccessories.Detectors)))
.filter(detector => (detector.Id == CombInId));
const Output_Data = Object.values(JSON.parse(JSON.stringify(this.DiscoveredAccessories.Outputs)))
.filter(output => (output.Id == CombOutId));
var Combined_Data = {
Id: CombId,
accessorytype: `Combined_${Comb}`,
InId: Detector_Data[0].Id,
OutId: Output_Data[0].Id,
Bypassed: Detector_Data[0].Bypassed,
Partition: Detector_Data[0].Partition,
name: Detector_Data[0].name,
longName: `comb_${CombId}_${((Detector_Data[0].name).toLowerCase()).normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/ /g, '_')}`,
InState: Detector_Data[0].State,
OnAlarm: Detector_Data[0].OnAlarm,
OutType: Output_Data[0].Type,
OutState: Output_Data[0].State,
Required: true
};
this.DiscoveredAccessories.Detectors[Detector_Data[0].Id].accessorytype = `${Comb}`;
this.DiscoveredAccessories.Detectors[Detector_Data[0].Id].Required = false;
this.DiscoveredAccessories.Outputs[Output_Data[0].Id].Required = false;
Combined_Datas[CombId] = Combined_Data;
}
}
this.DiscoveredAccessories.Combineds = Combined_Datas;
this.log.info('Creation of %s Combined Accessories', Object.keys(Combined_Datas).length);
}
//fallback to system mode if no DiscoveredAccessories
if ((Object.keys(this.DiscoveredAccessories).length == 0 ) && (PanelDatas.Partitions !== undefined)) {
this.log.debug('Fallback to system mode');
this.config['Partition'] = 'system';
this.RiscoPanel.Partition = 'system'
this.DiscoveredAccessories.Partitions = await this.RiscoPanel.DiscoverParts(PanelDatas.Partitions);
}
if (((this.config['Custom'] || 'none') != 'none') && (this.DiscoveredAccessories.Detectors !== undefined)) {
this.log.info('Apply Custom Configuration');
for (var Custom_Type in this.Custom_Types) {
this.log('Modify Detectors to %s', this.Custom_Types[Custom_Type]);
if ((this.config['Custom'][this.Custom_Types[Custom_Type]] || 'none') != 'none') {
if (this.config['Custom'][this.Custom_Types[Custom_Type]] == 'all') {
for (var Detector in this.DiscoveredAccessories.Detectors) {
this.DiscoveredAccessories.Detectors[Detector].accessorytype = this.Custom_Types[Custom_Type];
}
} else if (this.config['Custom'][this.Custom_Types[Custom_Type]] != (this.config['Custom'][this.Custom_Types[Custom_Type]].split(',')) || ( parseInt(this.config['Custom'][this.Custom_Types[Custom_Type]]) != NaN )) {
const Modified_Detectors = this.config['Custom'][this.Custom_Types[Custom_Type]].split(',').map(function(item) {
return parseInt(item, 10);
});
this.log.debug('Modified Detectors:\n%s', JSON.stringify(Modified_Detectors, JSONreplacer(), 4));
for (var Id_Detector in Modified_Detectors) {
this.log.debug('Detector Name/Id: %s/%s Modified to %s', this.DiscoveredAccessories.Detectors[Modified_Detectors[Id_Detector]].name, this.DiscoveredAccessories.Detectors[Modified_Detectors[Id_Detector]].Id, this.Custom_Types[Custom_Type]);
this.DiscoveredAccessories.Detectors[Modified_Detectors[Id_Detector]].accessorytype = this.Custom_Types[Custom_Type];
}
}
}
}
}
this.RiscoPanel.DiscoveredAccessories = this.DiscoveredAccessories;
this.log.info('Discovering Phase Ended');
if (Object.keys(this.DiscoveredAccessories).length == 0) {
return Promise.reject('No Accessory Discovered');
}
return Promise.resolve();
} catch (err) {
this.log.error('Error on Discovery Phase:\n%s', err);
this.RiscoPanel.DiscoveredAccessories = this.DiscoveredAccessories;
this.log.info('Discovering Phase Ended');
return Promise.reject();
}
}
PreConfigureAccessories(DeviceFamily) {
switch (DeviceFamily) {
case 'Partitions':
this.log.info('PreConf Accessory => Add Partitions');
if (this.DiscoveredAccessories.Partitions.type == 'system') {
this.log.info('PreConf Accessory => Configuration for System: %s', this.DiscoveredAccessories.Partitions[0].name);
var PartConfig = {
context: this.DiscoveredAccessories.Partitions[0],
RiscoSession: this.RiscoPanel,
polling: this.config['polling'],
pollInterval: this.config['pollInterval'],
OccupancyPreventArming: ((this.DiscoveredAccessories.Detectors != undefined) ? (this.config['OccupancyPreventArming'] || true) : false)
};
this.Devices.push(PartConfig);
} else {
for (var PartsId in this.DiscoveredAccessories.Partitions) {
if (PartsId != 'type') {
if (this.DiscoveredAccessories.Partitions[PartsId].Required == true) {
this.log.info('PreConf Accessory => Configuration for Partitions Id : %s and labeled "%s"', this.DiscoveredAccessories.Partitions[PartsId].Id, this.DiscoveredAccessories.Partitions[PartsId].name);
var PartConfig = {
context: this.DiscoveredAccessories.Partitions[PartsId],
RiscoSession: this.RiscoPanel,
polling: this.config['polling'],
pollInterval: this.config['pollInterval'],
OccupancyPreventArming: ((this.DiscoveredAccessories.Detectors != undefined) ? (this.config['OccupancyPreventArming'] || true) : false)
};
this.Devices.push(PartConfig);
}
}
}
}
break;
case 'Groups':
this.log.info('Add Accessory => Add Groups');
for (var GroupsId in this.DiscoveredAccessories.Groups) {
if (GroupsId != 'type') {
if (this.DiscoveredAccessories.Groups[GroupsId].Required == true) {
this.log.info('PreConf Accessory => Configuration for Groups Id : %s and labeled "%s"', this.DiscoveredAccessories.Groups[GroupsId].Id, this.DiscoveredAccessories.Groups[GroupsId].name);
var GroupConfig = {
context: this.DiscoveredAccessories.Groups[GroupsId],
RiscoSession: this.RiscoPanel,
polling: this.config['polling'],
pollInterval: this.config['pollInterval']
};
this.Devices.push(GroupConfig);
}
}
}
break;
case 'Outputs':
this.log.info('Add Accessory => Add Outputs');
for (var OutputId in this.DiscoveredAccessories.Outputs) {
if (this.DiscoveredAccessories.Outputs[OutputId].Required == true) {
this.log.info('PreConf Accessory => Configuration for Outputs Id : %s and labeled "%s"', this.DiscoveredAccessories.Outputs[OutputId].Id, this.DiscoveredAccessories.Outputs[OutputId].name);
var OutputConfig = {
context: this.DiscoveredAccessories.Outputs[OutputId],
RiscoSession: this.RiscoPanel,
polling: this.config['polling'],
pollInterval: this.config['pollInterval']
};
this.Devices.push(OutputConfig);
}
}
break;
case 'Detectors':
this.log.info('Add Accessory => Add Detectors');
for (var DetectorId in this.DiscoveredAccessories.Detectors) {
if (this.DiscoveredAccessories.Detectors[DetectorId].Required == true) {
this.log.info('PreConf Accessory => Configuration for Detectors Id : %s and labeled "%s"', this.DiscoveredAccessories.Detectors[DetectorId].Id, this.DiscoveredAccessories.Detectors[DetectorId].name);
var DetectorConfig = {
context: this.DiscoveredAccessories.Detectors[DetectorId],
RiscoSession: this.RiscoPanel,
polling: this.config['polling'],
pollInterval: this.config['pollInterval']
};
this.Devices.push(DetectorConfig);
}
}
break;
case 'Combineds':
this.log.info('Add Accessory => Add Combined');
for (var CombinedId in this.DiscoveredAccessories.Combineds) {
if (this.DiscoveredAccessories.Combineds[CombinedId].Required == true) {
this.log.info('PreConf Accessory => Configuration for Combined Id : %s and labeled "%s"', this.DiscoveredAccessories.Combineds[CombinedId].Id, this.DiscoveredAccessories.Combineds[CombinedId].name);
var CombinedConfig = {
context: this.DiscoveredAccessories.Combineds[CombinedId],
RiscoSession: this.RiscoPanel,
polling: this.config['polling'],
pollInterval: this.config['pollInterval']
};
this.Devices.push(CombinedConfig);
}
}
break;
};
}
}
module.exports = (api) => {
hap = api.hap;
Service = api.hap.Service;
Characteristic = api.hap.Characteristic;
UUIDGen = api.hap.uuid;
api.registerPlatform(pluginName, platformName, RiscoPanelPlatform);
};