Skip to content

Commit a00e4ef

Browse files
committed
Initial commit
0 parents  commit a00e4ef

File tree

9 files changed

+318
-0
lines changed

9 files changed

+318
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
6+
# Runtime data
7+
pids
8+
*.pid
9+
*.seed
10+
*.pid.lock
11+
12+
# Directory for instrumented libs generated by jscoverage/JSCover
13+
lib-cov
14+
15+
# Coverage directory used by tools like istanbul
16+
coverage
17+
18+
# nyc test coverage
19+
.nyc_output
20+
21+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22+
.grunt
23+
24+
# node-waf configuration
25+
.lock-wscript
26+
27+
# Compiled binary addons (http://nodejs.org/api/addons.html)
28+
build/Release
29+
30+
# Dependency directories
31+
node_modules
32+
jspm_packages
33+
34+
# Optional npm cache directory
35+
.npm
36+
37+
# Optional eslint cache
38+
.eslintcache
39+
40+
# Optional REPL history
41+
.node_repl_history
42+
43+
# Output of 'npm pack'
44+
*.tgz
45+
46+
# Yarn Integrity file
47+
.yarn-integrity
48+

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
node_modules/

LICENSE

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
BSD 2-Clause License
2+
3+
Copyright (c) 2017, jsWorks
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
* Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
homebridge-applescript-file
2+
===========================
3+
4+
Supports triggering AppleScript commands on the HomeBridge platform via Applescript files.
5+
6+
## Installation
7+
8+
1. Install homebridge using: `npm install -g homebridge`
9+
2. Install this plugin using: `npm install -g homebridge-applescript-file`
10+
3. Update your configuration file. See `sample-config.json` in this repository for a sample.
11+
12+
## Configuration
13+
14+
Configuration sample:
15+
16+
```
17+
"accessories": [
18+
{
19+
"accessory": "ApplescriptFile",
20+
"name": "Security Camera",
21+
"on": "/Users/bendodson/Documents/Scripts/cameraOn.applescript",
22+
"off": "/Users/bendodson/Documents/Scripts/cameraOff.applescript"
23+
}
24+
]
25+
```
26+
27+
Note that you must use absolute paths for your AppleScript file.

config-sample.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"bridge": {
3+
"name": "Homebridge",
4+
"username": "CD:22:3D:E3:CE:30",
5+
"port": 51826,
6+
"pin": "031-45-154"
7+
},
8+
9+
"description": "This is an example configuration for the Ping Hosts homebridge plugin",
10+
11+
"platforms": [
12+
{
13+
"platform": "PingHosts",
14+
"sensors": [
15+
{
16+
"id": "ping-router",
17+
"name": "Router Connectivity",
18+
"host": "192.168.0.1",
19+
"interval": 60
20+
},
21+
{
22+
"id": "ping-internent",
23+
"name": "Internet Connectivity",
24+
"host": "www.domain.com",
25+
"interval": 300
26+
}
27+
]
28+
}
29+
]
30+
}

index.js

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
"use strict";
2+
3+
var Service, Characteristic, detectedState, notDetectedState;
4+
var ping = require('ping');
5+
6+
// Update UI immediately after sensor state change
7+
var updateUI = false;
8+
9+
module.exports = function(homebridge) {
10+
11+
// Service and Characteristic are from hap-nodejs
12+
Service = homebridge.hap.Service;
13+
Characteristic = homebridge.hap.Characteristic;
14+
homebridge.registerPlatform('homebridge-ping-hosts', 'PingHosts', PingHostsPlatform);
15+
homebridge.registerAccessory('homebridge-ping-hosts', 'PingHostsContact', PingHostsContactAccessory);
16+
17+
detectedState = Characteristic.ContactSensorState.CONTACT_DETECTED; // Closed
18+
notDetectedState = Characteristic.ContactSensorState.CONTACT_NOT_DETECTED; // Open
19+
20+
};
21+
22+
function PingHostsPlatform(log, config) {
23+
24+
this.log = log;
25+
26+
this.sensors = config['sensors'] || [];
27+
28+
// Allow retrieval of data from package.json
29+
this.pkginfo = require('pkginfo')(module);
30+
31+
}
32+
33+
PingHostsPlatform.prototype = {
34+
35+
accessories: function(callback) {
36+
37+
var accessories = [];
38+
39+
for (var i = 0; i < this.sensors.length; i++) {
40+
var sensorAccessory = new PingHostsContactAccessory(this.pkginfo, this.log, this.sensors[i]);
41+
accessories.push(sensorAccessory);
42+
}
43+
44+
var accessoriesCount = accessories.length;
45+
46+
this.log(callback);
47+
48+
callback(accessories);
49+
50+
}
51+
52+
}
53+
54+
function PingHostsContactAccessory(pkginfo, log, config) {
55+
56+
this.log = log;
57+
this.pkginfo = pkginfo;
58+
59+
this.id = config['id'];
60+
this.name = config['name'] || 'Host Ping Sensor';
61+
this.host = config['host'] || 'localhost';
62+
this.pingInterval = parseInt(config['interval']) || 300;
63+
64+
// Initial state
65+
this.stateValue = detectedState;
66+
67+
this._service = new Service.ContactSensor(this.name);
68+
69+
// Default state is open, we want it to be closed
70+
this._service.getCharacteristic(Characteristic.ContactSensorState)
71+
.setValue(this.stateValue);
72+
73+
this._service
74+
.getCharacteristic(Characteristic.ContactSensorState)
75+
.on('get', this.getState.bind(this));
76+
77+
this._service.addCharacteristic(Characteristic.StatusFault);
78+
79+
this.changeHandler = (function(newState) {
80+
81+
this.log('[' + this.name + '] Setting sensor state set to ' + newState);
82+
this._service.getCharacteristic(Characteristic.ContactSensorState)
83+
.setValue(newState ? detectedState : notDetectedState);
84+
85+
if (updateUI)
86+
this._service.getCharacteristic(Characteristic.ContactSensorState)
87+
.getValue();
88+
89+
}).bind(this);
90+
91+
this.doPing();
92+
setInterval(this.doPing.bind(this), this.pingInterval * 1000);
93+
94+
}
95+
96+
PingHostsContactAccessory.prototype = {
97+
98+
doPing: function() {
99+
100+
var self = this;
101+
var lastState = self.stateValue;
102+
103+
ping.promise.probe(self.host)
104+
.then(function (res, err) {
105+
106+
if (err) {
107+
self.log(err);
108+
self.stateValue = notDetectedState;
109+
self.setStatusFault(1);
110+
} else {
111+
self.stateValue = res.alive ? notDetectedState : detectedState;
112+
self.setStatusFault(0);
113+
if (! self.stateValue) {
114+
self.log('[' + self.name + '] Ping result for ' + self.host + ' was ' + self.stateValue);
115+
}
116+
}
117+
// Notify of state change, if applicable
118+
if (self.stateValue != lastState) self.changeHandler(self.stateValue);
119+
120+
});
121+
122+
},
123+
124+
setStatusFault: function(value) {
125+
126+
this._service.setCharacteristic(Characteristic.StatusFault, value);
127+
128+
},
129+
130+
identify: function(callback) {
131+
132+
this.log('[' + this.name + '] Identify sensor requested');
133+
callback();
134+
135+
},
136+
137+
getState: function(callback) {
138+
139+
this.log('[' + this.name + '] Getting sensor state, which is currently ' + this.stateValue);
140+
callback(null, this.stateValue);
141+
142+
},
143+
144+
getServices: function() {
145+
146+
var informationService = new Service.AccessoryInformation();
147+
148+
149+
150+
// Set plugin information
151+
informationService
152+
.setCharacteristic(Characteristic.Manufacturer, 'jsWorks')
153+
.setCharacteristic(Characteristic.Model, 'Internet Connectivity Sensor')
154+
.setCharacteristic(Characteristic.SerialNumber, 'Version ' + module.exports.version);
155+
156+
return [informationService, this._service];
157+
158+
}
159+
160+
};

package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "homebridge-ping-hosts",
3+
"version": "1.0.0",
4+
"description": "Ping state sensor plugin for homebridge (https://github.com/nfarina/homebridge)",
5+
"license": "ISC",
6+
"keywords": [
7+
"homebridge-plugin"
8+
],
9+
"engines": {
10+
"node": ">=0.12.0",
11+
"homebridge": ">=0.2.0"
12+
},
13+
"author": {
14+
"name": "jsWorks"
15+
},
16+
"repository": {
17+
"type": "git",
18+
"url": "[email protected]:jsworks/homebridge-ping-hosts.git"
19+
},
20+
"dependencies": {
21+
"ping": "^0.2.0",
22+
"pkginfo": "^0.3.1"
23+
}
24+
}

0 commit comments

Comments
 (0)