Merge pull request #19 from tickez/limit-ap

New features
This commit is contained in:
oznu 2020-01-29 08:57:07 +11:00 committed by GitHub
commit 2da88b0026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 204 additions and 148 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
node_modules node_modules
yarn.lock yarn.lock
package-lock.json. package-lock.json.
/homebridge-unifi-occupancy-sensor.iml
/.idea/

View File

@ -23,8 +23,12 @@ The plugin connects to the UniFi Controller event web socket to get instant noti
"site": "default", // Optional. The UniFi site to connect to. "site": "default", // Optional. The UniFi site to connect to.
"secure": false // Optional. Set true to validate the SSL certificate. "secure": false // Optional. Set true to validate the SSL certificate.
}, },
"watch": ["44:00:10:f0:3e:66"] // Required. An array of device MAC addresses to watch for. "watch": [
"watchGuests": true // Optional. Set false to not monitor guest networks. "44:00:10:f0:3e:66",
{ "device": "44:00:10:f0:3e:67", "ap": "44:00:10:f0:3e:44" }
], // Required. An array of device MAC addresses to watch for or objects with device MAC / AP MAC
"watchGuests": true, // Optional. Set false to not monitor guest networks.
"interval": 1800, // Optional. Polling interval used to query Unifi in seconds
"mode": "any" // Optional. Set to "any", "all" or "none". "mode": "any" // Optional. Set to "any", "all" or "none".
} }
] ]

View File

@ -45,9 +45,20 @@
"title": "Watched Devices", "title": "Watched Devices",
"type": "array", "type": "array",
"items": { "items": {
"title": "MAC Address", "title": "Device / AP",
"type": "string", "type": "object",
"pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$" "properties": {
"device": {
"title": "Device MAC Address",
"type": "string",
"pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$"
},
"ap": {
"title": "AP MAC Address",
"type": "string",
"pattern": "^([a-f0-9]{2}:){5}[a-f0-9]{2}$"
}
}
} }
}, },
"mode": { "mode": {
@ -55,15 +66,36 @@
"type": "string", "type": "string",
"default": "any", "default": "any",
"oneOf": [ "oneOf": [
{ "title": "Any - only trigger occupancy when at least one watched device is connected", "enum": ["any"] }, {
{ "title": "All - only trigger occupancy when all watched devices are connected", "enum": ["all"] }, "title": "Any - only trigger occupancy when at least one watched device is connected",
{ "title": "None - only trigger occupancy when none of the watched devices are connected", "enum": ["none"] } "enum": [
"any"
]
},
{
"title": "All - only trigger occupancy when all watched devices are connected",
"enum": [
"all"
]
},
{
"title": "None - only trigger occupancy when none of the watched devices are connected",
"enum": [
"none"
]
}
], ],
"required": true "required": true
}, },
"watchGuests": { "watchGuests": {
"title": "Watch Guest Networks?", "title": "Watch Guest Networks?",
"type": "boolean" "type": "boolean"
},
"interval": {
"title": "Interval in seconds to query Unifi Controller",
"type": "integer",
"required": false,
"default": 1800
} }
} }
} }

192
index.js
View File

@ -1,25 +1,37 @@
'use strict' 'use strict';
const debug = require('debug')('unifi') const debug = require('debug')('unifi');
const UnifiEvents = require('unifi-events') const UnifiEvents = require('unifi-events');
const manifest = require('./package.json') const manifest = require('./package.json');
var Service, Characteristic var Service, Characteristic;
module.exports = function (homebridge) { module.exports = function (homebridge) {
Service = homebridge.hap.Service Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic Characteristic = homebridge.hap.Characteristic;
homebridge.registerAccessory('homebridge-unifi-occupancy-sensor', 'UniFi Occupancy Sensor', OccupancySensor) homebridge.registerAccessory('homebridge-unifi-occupancy-sensor',
} 'UniFi Occupancy Sensor', OccupancySensor)
};
class OccupancySensor { class OccupancySensor {
constructor (log, config) { constructor(log, config) {
this.log = log this.log = log;
this.name = config.name this.name = config.name;
this.occupancyService = new Service.OccupancySensor(this.name) this.occupancyService = new Service.OccupancySensor(this.name);
this.watch = config.watch || []
this.watchGuests = config.watchGuests this._watch = config.watch || [];
this.mode = config.mode || 'any' // This allows for backwards compatibility with simple strings
this.watch = this._watch.map(function (watched) {
if (typeof watched === 'string' || watched instanceof String) {
return {"device": watched, "ap": undefined};
} else {
return watched;
}
});
this.watchGuests = config.watchGuests;
this.mode = config.mode || 'any';
this.interval = config.interval || 1800;
this.unifi = new UnifiEvents({ this.unifi = new UnifiEvents({
controller: config.unifi.controller, controller: config.unifi.controller,
@ -28,109 +40,115 @@ class OccupancySensor {
site: config.unifi.site || 'default', site: config.unifi.site || 'default',
rejectUnauthorized: config.unifi.secure || false, rejectUnauthorized: config.unifi.secure || false,
listen: true listen: true
}) });
this.unifi.on('websocket-status', (socketLog) => { this.unifi.on('websocket-status', (socketLog) => {
this.log(socketLog) this.log(socketLog)
}) });
this.unifi.on('connected', (data) => { this.unifi.on('connected', (data) => {
debug(`Device Connected Event Received from UniFi Controller: ${data.msg}`) debug(`Device Connected Event Received from UniFi Controller: ${data.msg}`);
return this.checkOccupancy() return this.checkOccupancy()
}) });
this.unifi.on('disconnected', (data) => { this.unifi.on('disconnected', (data) => {
debug(`Device Disconnected Event Received from UniFi Controller: ${data.msg}`) debug(`Device Disconnected Event Received from UniFi Controller: ${data.msg}`);
return this.checkOccupancy() return this.checkOccupancy()
}) });
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED;
this.checkOccupancy() this.checkOccupancy();
setInterval(this.checkOccupancy.bind(this), 1800 * 1000) setInterval(this.checkOccupancy.bind(this), this.interval * 1000)
} }
checkGuest (isGuest, mac) { checkGuest(isGuest, mac) {
if (this.watchGuests && isGuest) { if (this.watchGuests && isGuest) {
debug(`Device [${mac}] is connected to a guest network and guest network monitoring is enabled.`) debug(`Device [${mac}] is connected to a guest network and guest network monitoring is enabled.`);
return true return true
} else if (!this.watchGuests && isGuest) { } else if (!this.watchGuests && isGuest) {
debug(`Device [${mac}] is connected to a guest network but guest network monitoring is NOT enabled.`) debug(`Device [${mac}] is connected to a guest network but guest network monitoring is NOT enabled.`);
return false return false
} else { } else {
debug(`Device [${mac}] is NOT connected to a guest network.`) debug(`Device [${mac}] is NOT connected to a guest network.`);
return true return true
} }
} }
checkOccupancy () { isInWatchlist(device) {
debug('Getting list of connected clients from UniFi Controller...') return this.watch.some(watchedDevice => (
return this.unifi.getClients() watchedDevice.device === device.mac && (watchedDevice.ap === undefined || watchedDevice.ap === device.ap_mac))
.then((res) => { );
debug(`${res.data.length} devices are currently connected to the UniFi network, checking each one to see if any are on the watch list...`)
let activeDevices = res.data.filter((device) => {
debug(`Device [${device.mac}] HOSTNAME: "${device.hostname}" , GUEST: "${device.is_guest}", SSID: "${device.essid}"`)
if (this.watch.includes(device.mac) && this.checkGuest(device.is_guest, device.mac)) {
debug(`Device [${device.mac}] Device is on the watch list. Going to trigger occupancy.`)
return true
} else {
debug(`Device [${device.mac}] Ignoring. Not on the watch list.`)
return false
}
})
debug(`Monitored devices found:`, activeDevices.map(x => x.mac))
if (this.mode === 'none') {
if (activeDevices.length > 0) {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "none" so NOT triggering occupancy.`)
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED
} else {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "none" so triggering occupancy.`)
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_DETECTED
}
} else if (this.mode === 'all') {
if (activeDevices.length === this.watch.length) {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "all" and all watched devices are connected so triggering occupancy.`)
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_DETECTED
} else {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "all" and not all watched devices are connected so NOT triggering occupancy.`)
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED
}
} else {
if (activeDevices.length > 0) {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "any" so triggering occupancy.`)
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_DETECTED
} else {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "any" so NOT triggering occupancy.`)
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED
}
}
this.setOccupancyDetected(this.occupancyDetected)
})
.catch((err) => {
this.log(`ERROR: Failed to check occupancy: ${err.message}`)
})
} }
getOccupancyDetected (callback) { checkOccupancy() {
debug('Getting list of connected clients from UniFi Controller...');
return this.unifi.getClients()
.then((res) => {
debug(`${res.data.length} devices are currently connected to the UniFi network, checking each one to see if any are on the watch list...`);
let activeDevices = res.data.filter((device) => {
debug(`Device [${device.mac}, ${device.ap_mac}] HOSTNAME: "${device.hostname}" , GUEST: "${device.is_guest}", SSID: "${device.essid}"`);
if (this.isInWatchlist(device) && this.checkGuest(device.is_guest, device.mac)) {
debug(`Device [${device.mac}, ${device.ap_mac}] Device is on the watch list. Going to trigger occupancy.`);
return true
} else {
debug(`Device [${device.mac}] Ignoring. Not on the watch list.`);
return false
}
});
debug(`Monitored devices found:`, activeDevices.map(x => x.mac));
if (this.mode === 'none') {
if (activeDevices.length > 0) {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "none" so NOT triggering occupancy.`);
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED
} else {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "none" so triggering occupancy.`);
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_DETECTED
}
} else if (this.mode === 'all') {
if (activeDevices.length === this.watch.length) {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "all" and all watched devices are connected so triggering occupancy.`);
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_DETECTED
} else {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "all" and not all watched devices are connected so NOT triggering occupancy.`);
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED
}
} else {
if (activeDevices.length > 0) {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "any" so triggering occupancy.`);
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_DETECTED
} else {
this.log(`${activeDevices.length} monitored device(s) found. Accessory is in mode "any" so NOT triggering occupancy.`);
this.occupancyDetected = Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED
}
}
this.setOccupancyDetected(this.occupancyDetected)
})
.catch((err) => {
this.log(`ERROR: Failed to check occupancy: ${err.message}`)
})
}
getOccupancyDetected(callback) {
return callback(null, this.occupancyDetected) return callback(null, this.occupancyDetected)
} }
setOccupancyDetected (value) { setOccupancyDetected(value) {
return this.occupancyService.setCharacteristic(Characteristic.OccupancyDetected, value) return this.occupancyService.setCharacteristic(Characteristic.OccupancyDetected, value)
} }
getServices () { getServices() {
var informationService = new Service.AccessoryInformation() var informationService = new Service.AccessoryInformation()
.setCharacteristic(Characteristic.Manufacturer, 'oznu') .setCharacteristic(Characteristic.Manufacturer, 'oznu')
.setCharacteristic(Characteristic.Model, 'unifi-occupancy') .setCharacteristic(Characteristic.Model, 'unifi-occupancy')
.setCharacteristic(Characteristic.SerialNumber, manifest.version) .setCharacteristic(Characteristic.SerialNumber, manifest.version);
this.occupancyService this.occupancyService
.getCharacteristic(Characteristic.OccupancyDetected) .getCharacteristic(Characteristic.OccupancyDetected)
.on('get', this.getOccupancyDetected.bind(this)) .on('get', this.getOccupancyDetected.bind(this));
return [informationService, this.occupancyService] return [informationService, this.occupancyService]
} }

102
package-lock.json generated
View File

@ -13,11 +13,11 @@
} }
}, },
"ajv": { "ajv": {
"version": "6.8.1", "version": "6.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
"integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
"requires": { "requires": {
"fast-deep-equal": "^2.0.1", "fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0", "fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1", "json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2" "uri-js": "^4.2.2"
@ -37,9 +37,9 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
}, },
"async-limiter": { "async-limiter": {
"version": "1.0.0", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
}, },
"asynckit": { "asynckit": {
"version": "0.4.0", "version": "0.4.0",
@ -52,9 +52,9 @@
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
}, },
"aws4": { "aws4": {
"version": "1.8.0", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
}, },
"bcrypt-pbkdf": { "bcrypt-pbkdf": {
"version": "1.0.2", "version": "1.0.2",
@ -65,9 +65,9 @@
} }
}, },
"bluebird": { "bluebird": {
"version": "3.5.3", "version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
}, },
"caseless": { "caseless": {
"version": "0.12.0", "version": "0.12.0",
@ -75,9 +75,9 @@
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
}, },
"combined-stream": { "combined-stream": {
"version": "1.0.7", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": { "requires": {
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
} }
@ -128,14 +128,14 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
}, },
"fast-deep-equal": { "fast-deep-equal": {
"version": "2.0.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
}, },
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.0.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
}, },
"forever-agent": { "forever-agent": {
"version": "0.6.1", "version": "0.6.1",
@ -226,21 +226,21 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.11", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
}, },
"mime-db": { "mime-db": {
"version": "1.37.0", "version": "1.43.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
}, },
"mime-types": { "mime-types": {
"version": "2.1.21", "version": "2.1.26",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
"requires": { "requires": {
"mime-db": "~1.37.0" "mime-db": "1.43.0"
} }
}, },
"ms": { "ms": {
@ -259,9 +259,9 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
}, },
"psl": { "psl": {
"version": "1.1.31", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
"integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ=="
}, },
"punycode": { "punycode": {
"version": "2.1.1", "version": "2.1.1",
@ -301,22 +301,22 @@
} }
}, },
"request-promise": { "request-promise": {
"version": "4.2.2", "version": "4.2.5",
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
"integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
"requires": { "requires": {
"bluebird": "^3.5.0", "bluebird": "^3.5.0",
"request-promise-core": "1.1.1", "request-promise-core": "1.1.3",
"stealthy-require": "^1.1.0", "stealthy-require": "^1.1.1",
"tough-cookie": ">=2.3.3" "tough-cookie": "^2.3.3"
} }
}, },
"request-promise-core": { "request-promise-core": {
"version": "1.1.1", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
"requires": { "requires": {
"lodash": "^4.13.1" "lodash": "^4.17.15"
} }
}, },
"safe-buffer": { "safe-buffer": {
@ -380,9 +380,9 @@
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
}, },
"unifi-events": { "unifi-events": {
"version": "0.4.2", "version": "0.4.3",
"resolved": "https://registry.npmjs.org/unifi-events/-/unifi-events-0.4.2.tgz", "resolved": "https://registry.npmjs.org/unifi-events/-/unifi-events-0.4.3.tgz",
"integrity": "sha512-NKWbGGgvW/0yzbVv8zGBJArUixt4HOkWgRsrtV0IJQrDgLphUYHHdf+mKTbwvPSyXyugi/hRGlDc254kWTIQZQ==", "integrity": "sha512-nXaP8p0hOZMD4mmMp5kuotQUvdITT4kDdmytYR7Xc+LJmC7HQZcAT+fVoMo1TluqH96vl8AuHI+xVdb2oOoSqA==",
"requires": { "requires": {
"@oznu/ws-connect": "^0.0.4", "@oznu/ws-connect": "^0.0.4",
"request": "^2.88.0", "request": "^2.88.0",
@ -398,9 +398,9 @@
} }
}, },
"uuid": { "uuid": {
"version": "3.3.2", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}, },
"verror": { "verror": {
"version": "1.10.0", "version": "1.10.0",

View File

@ -1,11 +1,11 @@
{ {
"name": "homebridge-unifi-occupancy-sensor", "name": "homebridge-unifi-occupancy-sensor",
"version": "0.1.2", "version": "0.2.0",
"description": "An occupancy sensor for Homebridge and UniFi", "description": "An occupancy sensor for Homebridge and UniFi",
"main": "index.js", "main": "index.js",
"dependencies": { "dependencies": {
"debug": "^3.2.6", "debug": "^3.2.6",
"unifi-events": "^0.4.2" "unifi-events": "^0.4.3"
}, },
"keywords": [ "keywords": [
"homebridge-plugin" "homebridge-plugin"