homebridge-sepsadsecurity
Version:
Publish your sepsad security system as an homekit accessory
962 lines (815 loc) • 33.8 kB
JavaScript
var Service, Characteristic, Accessory, UUIDGen;
var SepsadSecurityAPI = require('./sepsadSecurityAPI.js').SepsadSecurityAPI;
const SepsadSecurityTools = require('./sepsadSecurityTools.js');
const SepsadSecurityConst = require('./sepsadSecurityConst');
function mySepsadSecurityPlatform(log, config, api) {
if (!config) {
log('No configuration found for homebridge-sepsadsecurity');
return;
}
this.api = api;
this.log = log;
this.login = config['login'];
this.password = config['password'];
this.refreshTimer = SepsadSecurityTools.checkParameter(config['refreshTimer'], 30, 600, 180);
this.refreshTimerDuringOperation = SepsadSecurityTools.checkParameter(
config['refreshTimerDuringOperation'],
2,
15,
5
);
this.maxWaitTimeForOperation = SepsadSecurityTools.checkParameter(
config['maxWaitTimeForOperation'],
30,
90,
20
);
this.originSession = config['originSession'] ? config['originSession'] : 'SEPSAD';
this.allowActivation = SepsadSecurityTools.checkBoolParameter(config['allowActivation'], false);
this.cleanCache = config['cleanCache'];
this.foundAccessories = [];
this.sepsadSecurityAPI = new SepsadSecurityAPI(log, this);
this.loaded = false;
this.tempLoaded = false;
this._confirmedAccessories = [];
this._confirmedServices = [];
this.api
.on(
'shutdown',
function () {
this.end();
}.bind(this)
)
.on(
'didFinishLaunching',
function () {
this.log('DidFinishLaunching');
if (this.cleanCache) {
this.log('WARNING - Removing Accessories');
this.api.unregisterPlatformAccessories(
'homebridge-sepsadsecurity',
'SepsadSecurity',
this.foundAccessories
);
this.foundAccessories = [];
}
this.discoverSecuritySystem();
}.bind(this)
);
}
module.exports = function (homebridge) {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
Accessory = homebridge.platformAccessory;
UUIDGen = homebridge.hap.uuid;
HomebridgeAPI = homebridge;
homebridge.registerPlatform(
'homebridge-sepsadsecurity',
'SepsadSecurity',
mySepsadSecurityPlatform,
true
);
};
mySepsadSecurityPlatform.prototype = {
configureAccessory: function (accessory) {
this.log.debug(accessory.displayName, 'Got cached Accessory ' + accessory.UUID);
this.foundAccessories.push(accessory);
},
end() {
this.log('INFO - shutdown');
if (this.timerID) {
clearInterval(this.timerID);
this.timerID = undefined;
}
// disconnecting ?
},
//Cleaning methods
cleanPlatform: function () {
this.cleanAccessories();
this.cleanServices();
},
cleanAccessories: function () {
//cleaning accessories
let accstoRemove = [];
for (let acc of this.foundAccessories) {
if (!this._confirmedAccessories.find((x) => x.UUID == acc.UUID)) {
accstoRemove.push(acc);
this.log('WARNING - Accessory will be Removed ' + acc.UUID + '/' + acc.displayName);
}
}
if (accstoRemove.length > 0)
this.api.unregisterPlatformAccessories(
'homebridge-sepsadsecurity',
'SepsadSecurity',
accstoRemove
);
},
cleanServices: function () {
//cleaning services
for (let acc of this.foundAccessories) {
let servicestoRemove = [];
for (let serv of acc.services) {
if (
serv.subtype !== undefined &&
!this._confirmedServices.find((x) => x.UUID == serv.UUID && x.subtype == serv.subtype)
) {
servicestoRemove.push(serv);
}
}
for (let servToDel of servicestoRemove) {
this.log(
'WARNING - Service Removed' +
servToDel.UUID +
'/' +
servToDel.subtype +
'/' +
servToDel.displayName
);
acc.removeService(servToDel);
}
}
},
discoverSecuritySystem: function () {
this.sepsadSecurityAPI.on('securitySystemRefreshError', () => {
if (this.timerID == undefined) {
this.log('ERROR - securitySystemRefreshError - will retry in 1 minute');
setTimeout(() => {
this.sepsadSecurityAPI.getSecuritySystem();
}, 60000);
}
});
this.sepsadSecurityAPI.on('securitySystemRefreshed', () => {
this.log.debug('INFO - securitySystemRefreshed event');
this.log.debug(
'INFO - SecuritySystem : ' + JSON.stringify(this.sepsadSecurityAPI.securitySystem)
);
if (!this.loaded) {
this.loadSecuritySystem();
} else {
this.updateSecuritySystem();
}
});
this.sepsadSecurityAPI.on('securitySystemTemperatureRefreshError', () => {
if (this.timerID == undefined) {
this.log('ERROR - securitySystemTemperatureRefreshError - will retry in 1 minute');
setTimeout(() => {
this.sepsadSecurityAPI.getSecuritySystem();
}, 60000);
}
});
this.sepsadSecurityAPI.on('securitySystemTemperatureRefreshed', () => {
this.log.debug('INFO - securitySystemTemperatureRefreshed event');
this.log.debug(
'INFO - securitySystemTemperature : ' +
JSON.stringify(this.sepsadSecurityAPI.securitySystem.temperatureInfo)
);
if (!this.tempLoaded) {
this.createTemperatureSensorsAccessories();
} else {
this.updateTemperature();
}
});
this.sepsadSecurityAPI.getSecuritySystem();
},
createSecuritySystemAccessory() {
if (this.sepsadSecurityAPI.securitySystem.security) {
let securitySystemName = this.sepsadSecurityAPI.securitySystem.name;
let securitySystemModel = this.sepsadSecurityAPI.securitySystem.model;
let securitySystemSeriaNumber = this.sepsadSecurityAPI.securitySystem.id;
this.log('INFO - Discovered SecuritySystem : ' + securitySystemName);
let uuid = UUIDGen.generate(securitySystemName + securitySystemSeriaNumber);
let mySecuritySystemAccessory = this.foundAccessories.find((x) => x.UUID == uuid);
if (!mySecuritySystemAccessory) {
mySecuritySystemAccessory = new Accessory(securitySystemName, uuid);
mySecuritySystemAccessory.name = securitySystemName;
mySecuritySystemAccessory.model = securitySystemModel;
mySecuritySystemAccessory.manufacturer = 'Sepsad/EPS';
mySecuritySystemAccessory.serialNumber = securitySystemSeriaNumber;
mySecuritySystemAccessory.securitySystemID = securitySystemSeriaNumber;
mySecuritySystemAccessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, mySecuritySystemAccessory.manufacturer)
.setCharacteristic(Characteristic.Model, mySecuritySystemAccessory.model)
.setCharacteristic(Characteristic.SerialNumber, mySecuritySystemAccessory.serialNumber);
this.api.registerPlatformAccessories('homebridge-sepsadsecurity', 'SepsadSecurity', [
mySecuritySystemAccessory,
]);
this.foundAccessories.push(mySecuritySystemAccessory);
}
mySecuritySystemAccessory.securitySystemID = securitySystemSeriaNumber;
mySecuritySystemAccessory.name = securitySystemName;
let HKSecurityService = mySecuritySystemAccessory.getServiceByUUIDAndSubType(
securitySystemName,
'SecuritySystemService' + securitySystemName
);
if (!HKSecurityService) {
this.log('INFO - Creating SecurityService Service ' + securitySystemName);
HKSecurityService = new Service.SecuritySystem(
securitySystemName,
'SecuritySystemService' + securitySystemName
);
HKSecurityService.subtype = 'SecuritySystemService' + securitySystemName;
mySecuritySystemAccessory.addService(HKSecurityService);
}
this.bindSecuritySystemCurrentStateCharacteristic(HKSecurityService);
this.bindSecuritySystemTargetStateCharacteristic(HKSecurityService);
this._confirmedAccessories.push(mySecuritySystemAccessory);
this._confirmedServices.push(HKSecurityService);
// Required Characteristics
//this.addCharacteristic(Characteristic.SecuritySystemCurrentState);
//this.addCharacteristic(Characteristic.SecuritySystemTargetState);
// Optional Characteristics
//this.addOptionalCharacteristic(Characteristic.StatusFault);
//this.addOptionalCharacteristic(Characteristic.StatusTampered);
//this.addOptionalCharacteristic(Characteristic.SecuritySystemAlarmType);
//this.addOptionalCharacteristic(Characteristic.Name);
}
},
createSmokeSensorsAccessories() {
if (this.sepsadSecurityAPI.securitySystem.fire) {
let smokeDetectors = this.sepsadSecurityAPI.securitySystem.fire.smokeDetectors;
for (let a = 0; a < smokeDetectors.length; a++) {
let smokeSensorName = smokeDetectors[a].label;
let smokeSensorModel = this.sepsadSecurityAPI.securitySystem.model;
let smokeSensorSeriaNumber =
this.sepsadSecurityAPI.securitySystem.id + '/' + smokeDetectors[a].id;
this.log('INFO - Discovered SmokeSensor : ' + smokeSensorName);
let uuid = UUIDGen.generate(smokeSensorName + smokeSensorSeriaNumber);
let mySmokeSensorAccessory = this.foundAccessories.find((x) => x.UUID == uuid);
if (!mySmokeSensorAccessory) {
mySmokeSensorAccessory = new Accessory(smokeSensorName, uuid);
mySmokeSensorAccessory.name = smokeSensorName;
mySmokeSensorAccessory.model = smokeSensorModel;
mySmokeSensorAccessory.manufacturer = 'Sepsad/EPS';
mySmokeSensorAccessory.serialNumber = smokeSensorSeriaNumber;
mySmokeSensorAccessory.smokeSensorID = smokeDetectors[a].id;
mySmokeSensorAccessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, mySmokeSensorAccessory.manufacturer)
.setCharacteristic(Characteristic.Model, mySmokeSensorAccessory.model)
.setCharacteristic(Characteristic.SerialNumber, mySmokeSensorAccessory.serialNumber);
this.api.registerPlatformAccessories('homebridge-sepsadsecurity', 'SepsadSecurity', [
mySmokeSensorAccessory,
]);
this.foundAccessories.push(mySmokeSensorAccessory);
}
mySmokeSensorAccessory.smokeSensorID = smokeDetectors[a].id;
mySmokeSensorAccessory.name = smokeSensorName;
let HKSmokeSensorService = mySmokeSensorAccessory.getServiceByUUIDAndSubType(
smokeSensorName,
'SmokeSensorService' + smokeSensorName
);
if (!HKSmokeSensorService) {
this.log('INFO - Creating SmokeSensor Service ' + smokeSensorName);
HKSmokeSensorService = new Service.SmokeSensor(
smokeSensorName,
'SmokeSensorService' + smokeSensorName
);
HKSmokeSensorService.subtype = 'SmokeSensorService' + smokeSensorName;
mySmokeSensorAccessory.addService(HKSmokeSensorService);
}
this.bindSmokeDetectedCharacteristic(HKSmokeSensorService);
this.bindSmokeStatusActiveCharacteristic(HKSmokeSensorService);
this._confirmedAccessories.push(mySmokeSensorAccessory);
this._confirmedServices.push(HKSmokeSensorService);
//this.bindSmokeStatusLowBatteryCharacteristic(HKSmokeSensorService);
//this.bindSmokeStatusFaultCharacteristic(HKSmokeSensorService);
// Required Characteristics
//this.addCharacteristic(Characteristic.SmokeDetected);
// Optional Characteristics
//this.addOptionalCharacteristic(Characteristic.StatusActive);
//this.addOptionalCharacteristic(Characteristic.StatusFault);
//this.addOptionalCharacteristic(Characteristic.StatusTampered);
//this.addOptionalCharacteristic(Characteristic.StatusLowBattery);
//this.addOptionalCharacteristic(Characteristic.Name);
}
}
},
createTemperatureSensorsAccessories() {
if (this.sepsadSecurityAPI.securitySystem.temperatureInfo) {
let tempSensors = this.sepsadSecurityAPI.securitySystem.temperatureInfo;
for (let a = 0; a < tempSensors.length; a++) {
let tempSensorName = tempSensors[a].label;
let tempSensorModel = this.sepsadSecurityAPI.securitySystem.model;
let tempSensorSeriaNumber =
this.sepsadSecurityAPI.securitySystem.id + '/' + tempSensors[a].id;
this.log('INFO - Discovered TemperatureSensor : ' + tempSensorName);
let uuid = UUIDGen.generate(tempSensorName + tempSensorSeriaNumber);
let myTempSensorAccessory = this.foundAccessories.find((x) => x.UUID == uuid);
if (!myTempSensorAccessory) {
myTempSensorAccessory = new Accessory(tempSensorName, uuid);
myTempSensorAccessory.name = tempSensorName;
myTempSensorAccessory.model = tempSensorModel;
myTempSensorAccessory.manufacturer = 'Sepsad/EPS';
myTempSensorAccessory.serialNumber = tempSensorSeriaNumber;
myTempSensorAccessory.tempSensorID = tempSensors[a].id;
myTempSensorAccessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, myTempSensorAccessory.manufacturer)
.setCharacteristic(Characteristic.Model, myTempSensorAccessory.model)
.setCharacteristic(Characteristic.SerialNumber, myTempSensorAccessory.serialNumber);
this.api.registerPlatformAccessories('homebridge-sepsadsecurity', 'SepsadSecurity', [
myTempSensorAccessory,
]);
this.foundAccessories.push(myTempSensorAccessory);
}
myTempSensorAccessory.tempSensorID = tempSensors[a].id;
myTempSensorAccessory.name = tempSensorName;
let HKTempSensorService = myTempSensorAccessory.getServiceByUUIDAndSubType(
tempSensorName,
'TempSensorService' + tempSensorName
);
if (!HKTempSensorService) {
this.log('INFO - Creating TempSensor Service ' + tempSensorName);
HKTempSensorService = new Service.TemperatureSensor(
tempSensorName,
'TempSensorService' + tempSensorName
);
HKTempSensorService.subtype = 'TempSensorService' + tempSensorName;
myTempSensorAccessory.addService(HKTempSensorService);
}
this.bindCurrentTemperatureCharacteristic(HKTempSensorService);
this._confirmedAccessories.push(myTempSensorAccessory);
this._confirmedServices.push(HKTempSensorService);
//this.bindTempStatusActiveCharacteristic(HKTempSensorService);
//this.bindTempStatusLowBatteryCharacteristic(HKTempSensorService);
//this.bindTempStatusFaultCharacteristic(HKTempSensorService);
// Required Characteristics
//this.addCharacteristic(Characteristic.CurrentTemperature);
// Optional Characteristics
//this.addOptionalCharacteristic(Characteristic.StatusActive);
//this.addOptionalCharacteristic(Characteristic.StatusFault);
//this.addOptionalCharacteristic(Characteristic.StatusLowBattery);
//this.addOptionalCharacteristic(Characteristic.StatusTampered);
//this.addOptionalCharacteristic(Characteristic.Name);
}
this.tempLoaded = true;
this.cleanPlatform();
this.updateTemperature();
}
},
loadSecuritySystem() {
if (this.sepsadSecurityAPI.securitySystem.systemLastState) {
this.createSecuritySystemAccessory();
this.createSmokeSensorsAccessories();
if (
this.sepsadSecurityAPI.securitySystem.temperature &&
this.sepsadSecurityAPI.securitySystem.temperature.nbActiveDevices > 0
) {
this.sepsadSecurityAPI.getTemperature();
} else {
this.cleanPlatform();
}
this.updateSecuritySystem();
this.loaded = true;
//timer for background refresh
this.refreshBackground();
} else {
this.log(
'ERROR - discoverSecuritySystem - no security system found, will retry in 1 minute - ' +
result
);
setTimeout(() => {
this.sepsadSecurityAPI.getSecuritySystem();
}, 60000);
}
},
updateSecuritySystem() {
for (let a = 0; a < this.foundAccessories.length; a++) {
if (
this.foundAccessories[a].securitySystemID &&
this.sepsadSecurityAPI.securitySystem.systemLastState
) {
this.log.debug('INFO - refreshing securit System- ' + this.foundAccessories[a].name);
let securitySystemResult = undefined;
if (
this.sepsadSecurityAPI.securitySystem &&
this.sepsadSecurityAPI.securitySystem.id == this.foundAccessories[a].securitySystemID
) {
securitySystemResult = this.sepsadSecurityAPI.securitySystem.systemLastState;
}
if (securitySystemResult !== undefined) {
this.refreshSecuritySystem(this.foundAccessories[a], securitySystemResult);
} else {
this.log(
'ERROR - updateSecuritySystem - no result for securitySystem - ' +
this.foundAccessories[a].name
);
}
} else if (this.foundAccessories[a].smokeSensorID) {
this.log.debug('INFO - refreshing smokeSensor - ' + this.foundAccessories[a].name);
let smokeResults = this.sepsadSecurityAPI.securitySystem.fire;
if (smokeResults !== undefined) {
this.refreshSmokeSensor(this.foundAccessories[a], smokeResults);
} else {
this.log(
'ERROR - updateSecuritySystem - no result for smokeSensor - ' +
this.foundAccessories[a].name
);
}
}
}
},
updateTemperature() {
for (let a = 0; a < this.foundAccessories.length; a++) {
if (
this.foundAccessories[a].tempSensorID &&
this.sepsadSecurityAPI.securitySystem.temperatureInfo
) {
this.log.debug('INFO - refreshing temp Sensor - ' + this.foundAccessories[a].name);
let tempResults = this.sepsadSecurityAPI.securitySystem.temperatureInfo;
var tempSensorResult = undefined;
for (let b = 0; b < tempResults.length; b++) {
if (tempResults[b].id == this.foundAccessories[a].tempSensorID) {
tempSensorResult = tempResults[b];
break;
}
}
if (tempSensorResult !== undefined) {
this.refreshTempSensor(this.foundAccessories[a], tempSensorResult);
} else {
this.log(
'ERROR - updateSecuritySystem - no result for tempSensor - ' +
this.foundAccessories[a].name
);
}
}
}
},
getCurrentSecuritySystemStateCharacteristic: function (service, callback) {
callback(undefined, service.getCharacteristic(Characteristic.SecuritySystemCurrentState).value);
//no operationInProgress, refresh current state
if (service.TargetSecuritySystemStateOperationStart == undefined) {
this.sepsadSecurityAPI.getSecuritySystem();
}
// Characteristic.SecuritySystemCurrentState.STAY_ARM = 0;
// Characteristic.SecuritySystemCurrentState.AWAY_ARM = 1;
// Characteristic.SecuritySystemCurrentState.NIGHT_ARM = 2;
// Characteristic.SecuritySystemCurrentState.DISARMED = 3;
// Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED = 4;
},
getTargetSecuritySystemStateCharacteristic: function (service, callback) {
callback(undefined, service.getCharacteristic(Characteristic.SecuritySystemTargetState).value);
//handled through currentState
// Characteristic.SecuritySystemTargetState.STAY_ARM = 0;
// Characteristic.SecuritySystemTargetState.AWAY_ARM = 1;
// Characteristic.SecuritySystemTargetState.NIGHT_ARM = 2;
// Characteristic.SecuritySystemTargetState.DISARM = 3;
},
setTargetSecuritySystemtateCharacteristic: function (service, value, callback) {
var currentValue = service.getCharacteristic(Characteristic.SecuritySystemTargetState).value;
var currentState = service.getCharacteristic(Characteristic.SecuritySystemCurrentState).value;
var that = this;
callback();
if (currentState != value) {
if (value < Characteristic.SecuritySystemTargetState.DISARM && this.allowActivation) {
this.log.debug(
'INFO - SET Characteristic.SecuritySystemTargetState - ' +
service.subtype +
' - SecuritySystemCurrentState is ' +
this.sepsadSecurityAPI.getStateString(currentState)
);
let mode = SepsadSecurityConst.DISABLED;
if (value == Characteristic.SecuritySystemTargetState.AWAY_ARM)
mode = SepsadSecurityConst.ACTIVATED;
else if (
value == Characteristic.SecuritySystemTargetState.STAY_ARM ||
value == Characteristic.SecuritySystemTargetState.NIGHT_ARM
)
mode = SepsadSecurityConst.PARTIAL;
this.sepsadSecurityAPI.activateSecuritySystem(mode, function (error) {
if (error) {
that.endSecuritySystemOperation(service);
that.log.debug(
'ERROR - SET Characteristic.SecuritySystemTargetState - ' +
service.subtype +
' error activating '
);
setTimeout(() => {
service
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(currentValue);
service
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.updateValue(currentState);
}, 500);
} else {
that.beginSecuritySystemOperation(service, value);
that.log.debug(
'INFO - SET Characteristic.SecuritySystemTargetState - ' +
service.subtype +
' success activating '
);
}
});
} else {
//CANCEL
setTimeout(() => {
service
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(currentValue);
service
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.updateValue(currentState);
}, 500);
}
}
},
getCurrentTemperatureCharacteristic: function (service, callback) {
callback(undefined, service.getCharacteristic(Characteristic.CurrentTemperature).value);
this.sepsadSecurityAPI.getTemperature();
},
getSmokeDetectedCharacteristic: function (service, callback) {
callback(undefined, service.getCharacteristic(Characteristic.SmokeDetected).value);
//no operationInProgress, refresh current state
if (service.TargetSecuritySystemStateOperationStart == undefined) {
this.sepsadSecurityAPI.getSecuritySystem();
}
},
getSmokeStatusActiveCharacteristic: function (service, callback) {
callback(undefined, service.getCharacteristic(Characteristic.StatusActive).value);
},
bindCurrentTemperatureCharacteristic: function (service) {
service.getCharacteristic(Characteristic.CurrentTemperature).on(
'get',
function (callback) {
this.getCurrentTemperatureCharacteristic(service, callback);
}.bind(this)
);
},
bindSmokeDetectedCharacteristic(service) {
service.getCharacteristic(Characteristic.SmokeDetected).on(
'get',
function (callback) {
this.getSmokeDetectedCharacteristic(service, callback);
}.bind(this)
);
},
bindSmokeStatusActiveCharacteristic(service) {
service.getCharacteristic(Characteristic.StatusActive).on(
'get',
function (callback) {
this.getSmokeStatusActiveCharacteristic(service, callback);
}.bind(this)
);
},
bindSecuritySystemCurrentStateCharacteristic: function (service) {
service.getCharacteristic(Characteristic.SecuritySystemCurrentState).on(
'get',
function (callback) {
this.getCurrentSecuritySystemStateCharacteristic(service, callback);
}.bind(this)
);
},
bindSecuritySystemTargetStateCharacteristic: function (service) {
//at startup, set to currentstate to reset
service
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(service.getCharacteristic(Characteristic.SecuritySystemCurrentState).value);
service
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.on(
'get',
function (callback) {
this.getTargetSecuritySystemStateCharacteristic(service, callback);
}.bind(this)
)
.on(
'set',
function (value, callback) {
this.setTargetSecuritySystemtateCharacteristic(service, value, callback);
}.bind(this)
);
},
beginSecuritySystemOperation(service, state) {
//stop timer if one exists.
if (this.timerID !== undefined) {
clearInterval(this.timerID);
this.timerID = undefined;
}
service.TargetSecuritySystemState = state;
service.TargetSecuritySystemStateOperationStart = Date.now();
//start operating timer
this.log.debug(
'INFO - beginSecuritySystemOperation - ' + service.subtype + ' - Setting Timer for operation'
);
this.timerID = setInterval(() => {
this.sepsadSecurityAPI.getSecuritySystem();
}, this.refreshTimerDuringOperation * 1000);
},
endSecuritySystemOperation(service) {
//stop timer for this operation
this.log.debug(
'INFO - endSecuritySystemOperation - ' + service.subtype + ' - Stopping operation'
);
service.TargetSecuritySystemState = undefined;
service.TargetSecuritySystemStateOperationStart = undefined;
this.checkEndOperation();
},
checkEndOperation() {
//clear timer and set background again if no other operation in progress
if (this.timerID !== undefined) {
let operationInProgress = false;
for (let a = 0; a < this.foundAccessories.length; a++) {
let mySecuritySystemAccessory = this.foundAccessories[a];
for (let s = 0; s < mySecuritySystemAccessory.services.length; s++) {
let service = mySecuritySystemAccessory.services[s];
if (service.TargetSecuritySystemState !== undefined) {
operationInProgress = true;
break;
}
}
if (operationInProgress) break;
}
if (!operationInProgress) {
this.log.debug('Stopping Operation Timer ');
clearInterval(this.timerID);
this.timerID = undefined;
this.refreshBackground();
}
}
},
operationMode(result) {
if (result.securityMode == SepsadSecurityConst.DISABLED) {
return Characteristic.SecuritySystemCurrentState.DISARMED;
} else if (result.securityMode == SepsadSecurityConst.ACTIVATED) {
return Characteristic.SecuritySystemCurrentState.AWAY_ARM;
} else if (result.securityMode == SepsadSecurityConst.PARTIAL) {
return Characteristic.SecuritySystemCurrentState.NIGHT_ARM;
} else {
return -1;
}
},
refreshBackground() {
//timer for background refresh
if (this.refreshTimer !== undefined && this.refreshTimer > 0) {
this.log.debug(
'INFO - Setting Timer for background refresh every : ' + this.refreshTimer + 's'
);
this.timerID = setInterval(
() => this.sepsadSecurityAPI.getSecuritySystem(),
this.refreshTimer * 1000
);
}
},
refreshSecuritySystem: function (mySepsadSecurityAccessory, result) {
let securitySystemName = mySepsadSecurityAccessory.name;
let HKSecurityService = mySepsadSecurityAccessory.getServiceByUUIDAndSubType(
securitySystemName,
'SecuritySystemService' + securitySystemName
);
if (!HKSecurityService) {
this.log('Error - refreshSecuritySystem - ' + securitySystemName + ' - no service found');
return;
}
let currentSecurityServiceState = this.operationMode(result);
let operationInProgress =
HKSecurityService.TargetSecuritySystemStateOperationStart !== undefined;
let operationInProgressIsFinished =
operationInProgress &&
HKSecurityService.TargetSecuritySystemState == currentSecurityServiceState;
let oldSecurityServiceState = HKSecurityService.getCharacteristic(
Characteristic.SecuritySystemCurrentState
).value;
let oldTargetState = HKSecurityService.getCharacteristic(
Characteristic.SecuritySystemTargetState
).value;
this.log.debug(
'INFO - refreshSecuritySystem - Got Status for : ' +
HKSecurityService.subtype +
' - (currentState/operationInProgress/operationInProgressIsFinished/oldState/oldTargetState) : (' +
currentSecurityServiceState +
'/' +
operationInProgress +
'/' +
operationInProgressIsFinished +
'/' +
oldSecurityServiceState +
'/' +
oldTargetState +
')'
);
var newSecurityServiceState = oldSecurityServiceState;
var newTargetState = oldTargetState;
//operation has finished or timed out
if (operationInProgressIsFinished || this.endOperation(HKSecurityService, result)) {
this.endSecuritySystemOperation(HKSecurityService);
if (!operationInProgressIsFinished) {
this.log(
'WARNING - refreshSecuritySystem - ' +
HKSecurityService.subtype +
' - operation was in progress and has timedout or no status retrieval'
);
}
newSecurityServiceState = currentSecurityServiceState;
newTargetState = currentSecurityServiceState;
} else if (!operationInProgress && currentSecurityServiceState != oldSecurityServiceState) {
newSecurityServiceState = currentSecurityServiceState;
newTargetState = currentSecurityServiceState;
}
if (newTargetState != oldTargetState) {
this.log.debug(
'INFO - refreshSecuritySystem - ' +
HKSecurityService.subtype +
' updating TargetState to : ' +
newTargetState +
'-' +
this.sepsadSecurityAPI.getStateString(newTargetState)
);
//TargetState before CurrentState
setImmediate(() => {
HKSecurityService.getCharacteristic(Characteristic.SecuritySystemTargetState).updateValue(
newTargetState
);
});
}
if (newSecurityServiceState != oldSecurityServiceState) {
this.log.debug(
'INFO - refreshSecuritySystem - ' +
HKSecurityService.subtype +
' updating CurrenState to : ' +
this.sepsadSecurityAPI.getStateString(newSecurityServiceState)
);
setImmediate(() => {
HKSecurityService.getCharacteristic(Characteristic.SecuritySystemCurrentState).updateValue(
newSecurityServiceState
);
});
}
},
refreshTempSensor: function (myTempAccessory, result) {
let tempSensorName = myTempAccessory.name;
let HKTempSensorService = myTempAccessory.getServiceByUUIDAndSubType(
tempSensorName,
'TempSensorService' + tempSensorName
);
if (!HKTempSensorService) {
this.log('Error - refreshTempSensor - ' + tempSensorName + ' - no service found');
return;
}
let currentTemp = HKTempSensorService.getCharacteristic(Characteristic.CurrentTemperature)
.value;
let newTemp = result.temperature;
if (newTemp != currentTemp)
HKTempSensorService.getCharacteristic(Characteristic.CurrentTemperature).updateValue(newTemp);
},
refreshSmokeSensor: function (mySmokeAccessory, result) {
let smokeSensorName = mySmokeAccessory.name;
let HKSmokeSensorService = mySmokeAccessory.getServiceByUUIDAndSubType(
smokeSensorName,
'SmokeSensorService' + smokeSensorName
);
if (!HKSmokeSensorService) {
this.log('Error - refreshSmokeSensor - ' + smokeSensorName + ' - no service found');
return;
}
let currentStatus = HKSmokeSensorService.getCharacteristic(Characteristic.StatusActive);
let newStatus = result.fireStatus == 'ON';
if (currentStatus != newStatus)
HKSmokeSensorService.getCharacteristic(Characteristic.StatusActive).updateValue(newStatus);
var newSmokeStatus = undefined;
for (let a = 0; a < result.smokeDetectors.length; a++) {
if (result.smokeDetectors[a].id == mySmokeAccessory.smokeSensorID) {
newSmokeStatus = result.smokeDetectors[a].status != null;
break;
}
}
if (newSmokeStatus == undefined) {
this.log(
'Error - refreshSmokeSensor - ' +
smokeSensorName +
'/' +
mySmokeAccessory.smokeSensorID +
' - no data found for smoke detection Status'
);
return;
} else {
let currentSmokeStatus = HKSmokeSensorService.getCharacteristic(Characteristic.SmokeDetected);
if (currentSmokeStatus != newSmokeStatus)
HKSmokeSensorService.getCharacteristic(Characteristic.SmokeDetected).updateValue(
newSmokeStatus
);
}
},
endOperation(service, result) {
// TODO CHECK CHECK
if (this.operationMode(result) == SepsadSecurityConst.UNKNOWN) return true;
//timeout
if (
service.TargetSecuritySystemState !== undefined &&
service.TargetSecuritySystemStateOperationStart !== undefined
) {
let elapsedTime = Date.now() - service.TargetSecuritySystemStateOperationStart;
this.log.debug(
'INFO - CheckTimeout / result : ' +
JSON.stringify(result) +
' - elapsedTime : ' +
elapsedTime
);
if (elapsedTime > this.maxWaitTimeForOperation * 1000) {
return true;
}
}
return false;
},
};