Closed ghost closed 7 years ago
Dear Mobius,
I am afraid I won't be able to help you with this issue. My plugin alone is not defining any logic regarding alarm states and actual alarms, it only acts as a relay: it simply forwards queries from your iPhone to an arbitrary web application of yours.
When you are using http-securitysystem, you need a web app to connect it to and it has to be the web app that listens for inputs and triggers responses. Basically: this plugin shows a completely 3rd party security solution as if it was homekit-compatible.
To give you an example: I am using Node-Red for defining certain automation rules of my home. Node-red itself is not homekit-compatible, but it can expose web endpoints, on which it listens to requests and provides responses based on logic you define. I have my home security logic inside node-red (it is receiving inputs from motion sensors and it is triggering alarms and lights, it can also control Philips Hue stuff for example) and I have this securitysystem homebridge-plugin running and relaying HomeKit requests to node-red web endpoints. This way my completely custom security solution seems like if it was a HomeKit device and I can use my phone or Siri to toggle it.
Dear Codetwice,
Sorry for my late response, I was for a couple of days on holidays. Yesterday I have installed your Plugin from the develop branch. The polling option is for me mandatory for the challenge to use the Philips Hue motion sensors. Interestingly I could only install the develop branch as local user without sudo and -g.
I have installed Node-Red in a virtual machine and it looks really interesting. But when I'm correctly informed, it is not possible to integrate the Hue sensors in Node Red.
I have now configured your plugin to work with my Hue sensors (homebridge-hue from ebaauw). I also made some chances in the homebridge-hue Plugin.
For everyone who is interested I added the changes Below:
First I added a new file (motion) inside my web server (/var/www/html/alarm). Inside the file HueSensor.js (/.../homebridge-hue/lib/) In the Function „HueSensor.prototype.heartbeat = function(obj) {“ I chanced and added following code (line ~580).
Original:
this.durationTimer = null;
this.service
.updateCharacteristic(this.type.Characteristic, saved.value);
}.bind(this), this.duration);
} else {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
this.service
.updateCharacteristic(this.type.Characteristic, this.hk.value);
}
}
}
Changed:
this.durationTimer = null;
this.service
.updateCharacteristic(this.type.Characteristic, saved.value);
}.bind(this), this.duration);
} else {
if (this.type.name == "motion") {
var fs = require('fs');
var alarmstatus;
try {
alarmstatus = JSON.parse(fs.readFileSync('/var/www/html/alarm/check', 'utf8'));
} catch (err) {
self.log("Error: alarmstatus = %s", alarmstatus);
}
if (alarmstatus !== 3) {
this.log.info('alarmstatus ist: %s : Motion detected!', alarmstatus);
if (alarmstatus == 0 || alarmstatus == 2) {
this.log.info('alarmstatus ist:%s', alarmstatus);
var fs = require('fs');
if (this.name == "Motion Sensor Name 1" || this.name == "Motion Sensor Name 2" || this.name == "Motion Sensor Name 3" && old.hk.value == 0) {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
fs.writeFile("/var/www/html/alarm/motion", 1, function(err) {
if(err) {
return console.log(err);
}
});
} else if (this.name == "Motion Sensor Name 1" || this.name == "Motion Sensor Name 2" || this.name == "Motion Sensor Name 3" && old.hk.value == 1) {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
fs.writeFile("/var/www/html/alarm/motion", 0, function(err) {
if(err) {
return console.log(err);
}
});
} else {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
}
}
if (alarmstatus == 1) {
this.log.info('alarmstatus ist:%s', alarmstatus);
var fs = require('fs');
if (this.name == "Motion Sensor Name 1" || this.name == "Motion Sensor Name 2" || this.name == "Motion Sensor Name 3" || this.name == "Motion Sensor Name 4" && old.hk.value == 0) {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
fs.writeFile("/var/www/html/alarm/motion", 1, function(err) {
if(err) {
return console.log(err);
}
});
} else if (this.name == "Motion Sensor Name 1" || this.name == "Motion Sensor Name 2" || this.name == "Motion Sensor Name 3" || this.name == "Motion Sensor Name 4" && old.hk.value == 1) {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
fs.writeFile("/var/www/html/alarm/motion", 0, function(err) {
if(err) {
return console.log(err);
}
});
} else {
this.log.info(
'%s: set homekit %s from %s%s to %s%s on %s', this.name,
this.type.name, old.hk.value, this.type.unit,
this.hk.value, this.type.unit, this.hk.lastupdated
);
}
}
} else {
fs.writeFile("/var/www/html/alarm/motion", 0, function(err) {
if(err) {
return console.log(err);
}
});
}
this.service
.updateCharacteristic(this.type.Characteristic, this.hk.value);
}
}
}
}
When motion will be detected with specific motion sensors, the value 1 will be written inside motion file. When the motion sensor detects no motion anymore, the value 0 will be written. Which Motion Sensor is selected is based on the alarm state (alarmstatus). State 0 and 2 is in ma setup the same (Home and Night). State 1 = Away.
In the function "HttpSecuritySystemAccessory.prototype.setTargetState = function(state, callback)" I have chanced the "if (error)" as follows:
var url = cfg.url;
var body = cfg.body;
if (url) {
this.httpRequest(url, body, function(error, response) {
if (error) {
this.log("SetState function failed: %s", error.message);
callback(error);
} else {
this.log("SetState function succeeded!");
self.securityService.setCharacteristic(Characteristic.SecuritySystemCurrentState, state);
callback(error, response, state);
var fs = require('fs');
fs.writeFile("/var/www/html/alarm/check", state, function(err) {
if(err) {
return console.log(err);
}
});
}
}.bind(this));
} else {
callback(null);
}
};
With this code the security state chance inside the HomeKit app will be written to the check file. I use this because I have no "intelligent" alarm system at the backend.
The chances at function "HttpSecuritySystemAccessory.prototype.getCurrentState = function(callback)" are as follows: HttpSecuritySystemAccessory.prototype.getCurrentState = function(callback) { var self = this; self.debugLog("Getting current state"); this.getState(this.urls.readCurrentState.url, this.urls.readCurrentState.body, function(err, state) { self.debugLog("Current state is %s", state); var fs = require('fs'); var motion; try { motion = JSON.parse(fs.readFileSync('/var/www/html/alarm/motion', 'utf8')); } catch (err) { self.log("Error: Motion = %s", motion); } if (motion == "") { fs.writeFile("/var/www/html/alarm/motion", 0, function(err) { if(err) { return console.log(err); } }); } if (self.previousCurrentState !== 3 && motion == "1") { state = 4; self.previousCurrentState = state; self.log("Current state changed to %s", state); } if (self.previousCurrentState !== state) { self.previousCurrentState = state; self.log("Current state changed to %s", state); }
callback(err, state);
});
};
Congrats and thanks for the explanation. I'd have never thought of using homebridge itself to connect devices!
Hello,
I would like to implement an alarm system in Homekit. I'm using a Hue Homebridge plugin for the Philips Hue motion detectors. They are visible and working in Homekit. When I activate, for an example, the state Away and one of the motion detectors detects motion nothing happens. Do I miss something? Do I need to change something on the webserver? I only have a simple Apache2 webserver.
Thanks a lot.