hap-nodejs
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -421,4 +421,9 @@ var debug = require('debug')('Accessory'); | ||
iid: iid, | ||
status: -70402 // error status | ||
status: HAPServer.Status.SERVICE_COMMUNICATION_FAILURE // generic error status | ||
}); | ||
// have we collected all responses yet? | ||
if (characteristics.length === data.length) | ||
callback(null, characteristics); | ||
return; | ||
@@ -448,3 +453,3 @@ } | ||
iid: iid, | ||
status: -70402 // error status | ||
status: HAPServer.Status.SERVICE_COMMUNICATION_FAILURE // generic error status | ||
}); | ||
@@ -469,7 +474,2 @@ } | ||
}.bind(this)); | ||
// have we already collected all responses on this first pass? if all characteristics were not found | ||
// for instance, this may be the case. so we'll need to call the callback. | ||
if (characteristics.length === data.length) | ||
callback(null, characteristics); | ||
} | ||
@@ -481,18 +481,15 @@ | ||
// data looks something like this: | ||
// { characteristics: [ { aid: 1, iid: 8, value: true, ev: true } ] } | ||
// data is an array of characteristics and values like this: | ||
// [ { aid: 1, iid: 8, value: true, ev: true } ] | ||
debug("[%s] Processing characteristic set: %s", this.displayName, JSON.stringify(data)); | ||
// if we encounter an error while setting multiple characteristics, remember it here and move on | ||
var lastError = null; | ||
var pendingAsyncCalls = 0; // number of pending async calls to setValue by the end of this function | ||
var finishedLoop = false; | ||
// build up our array of responses to the characteristics requested asynchronously | ||
var characteristics = []; | ||
for (var index in data.characteristics) { | ||
var setting = data.characteristics[index]; | ||
var aid = setting.aid; | ||
var iid = setting.iid; | ||
var value = setting.value; | ||
var ev = setting.ev; | ||
data.forEach(function(characteristicData) { | ||
var aid = characteristicData.aid; | ||
var iid = characteristicData.iid; | ||
var value = characteristicData.value; | ||
var ev = characteristicData.ev; | ||
@@ -502,4 +499,14 @@ var characteristic = this.findCharacteristic(aid, iid); | ||
if (!characteristic) { | ||
lastError = new Error("Could not find a Characteristic with iid of " + iid + " and aid of " + aid); | ||
continue; | ||
debug('[%s] Could not find a Characteristic with iid of %s and aid of %s', this.displayName, characteristicData.aid, characteristicData.iid); | ||
characteristics.push({ | ||
aid: aid, | ||
iid: iid, | ||
status: HAPServer.Status.SERVICE_COMMUNICATION_FAILURE // generic error status | ||
}); | ||
// have we collected all responses yet? | ||
if (characteristics.length === data.length) | ||
callback(null, characteristics); | ||
return; | ||
} | ||
@@ -514,2 +521,17 @@ | ||
// if "ev" is present, that means we need to register or unregister this client for change events for | ||
// this characteristic. | ||
if (typeof ev !== 'undefined') { | ||
debug('[%s] %s Characteristic "%s" for events', this.displayName, ev ? "Registering" : "Unregistering", characteristic.displayName); | ||
// store event registrations in the supplied "events" dict which is associated with the connection making | ||
// the request. | ||
var eventName = aid + '.' + iid; | ||
if (ev) | ||
events[eventName] = true; // value is arbitrary, just needs to be non-falsey | ||
else | ||
delete events[eventName]; // unsubscribe by deleting name from dict | ||
} | ||
// Found the characteristic - set the value if there is one | ||
@@ -521,40 +543,42 @@ if (typeof value !== 'undefined') { | ||
// set the value and wait for success | ||
pendingAsyncCalls++; | ||
characteristic.setValue(value, function(err) { | ||
pendingAsyncCalls--; | ||
if (err) { | ||
debug('[%s] Error setting Characteristic "%s" to value %s: ', this.displayName, characteristic.displayName, value, err.message); | ||
lastError = err; | ||
characteristics.push({ | ||
aid: aid, | ||
iid: iid, | ||
status: HAPServer.Status.SERVICE_COMMUNICATION_FAILURE // generic error status | ||
}); | ||
} | ||
else { | ||
characteristics.push({ | ||
aid: aid, | ||
iid: iid, | ||
status: 0 | ||
}); | ||
} | ||
// was this the last setValue callback called? and we're done looping? then we need to call the callback. | ||
if (finishedLoop && pendingAsyncCalls == 0) | ||
callback(lastError); | ||
// have we collected all responses yet? | ||
if (characteristics.length === data.length) | ||
callback(null, characteristics); | ||
}.bind(this), context); | ||
} | ||
else { | ||
// no value to set, so we're done (success) | ||
characteristics.push({ | ||
aid: aid, | ||
iid: iid, | ||
status: 0 | ||
}); | ||
// have we collected all responses yet? | ||
if (characteristics.length === data.length) | ||
callback(null, characteristics); | ||
} | ||
// if "ev" is present, that means we need to register or unregister this client for change events for | ||
// this characteristic. | ||
if (typeof ev !== 'undefined') { | ||
debug('[%s] %s Characteristic "%s" for events', this.displayName, ev ? "Registering" : "Unregistering", characteristic.displayName); | ||
// store event registrations in the supplied "events" dict which is associated with the connection making | ||
// the request. | ||
var eventName = aid + '.' + iid; | ||
if (ev) | ||
events[eventName] = true; // value is arbitrary, just needs to be non-falsey | ||
else | ||
delete events[eventName]; // unsubscribe by deleting name from dict | ||
} | ||
} | ||
// so that if the setValue callback was called synchronously during the loop above, we can hold off | ||
// calling the final callback until now. | ||
finishedLoop = true; | ||
if (pendingAsyncCalls == 0) | ||
callback(lastError); | ||
}.bind(this)); | ||
} | ||
@@ -561,0 +585,0 @@ |
@@ -131,2 +131,8 @@ var debug = require('debug')('HAPServer'); | ||
// Status codes for underlying HAP calls | ||
HAPServer.Status = { | ||
SERVICE_COMMUNICATION_FAILURE: -70402, | ||
RESOURCE_BUSY: -70403 | ||
} | ||
HAPServer.prototype.listen = function(port) { | ||
@@ -664,13 +670,21 @@ this._httpServer.listen(port); | ||
err = new Error("characteristics not supplied by the get-characteristics event callback"); | ||
if (err) { | ||
debug("[%s] Error getting characteristics: %s", this.accessoryInfo.username, err.message); | ||
response.writeHead(500, "Server Error"); | ||
response.end(); | ||
return; | ||
debug("[%s] Error getting characteristics: %s", this.accessoryInfo.username, err.stack); | ||
// rewrite characteristics array to include error status for each characteristic requested | ||
characteristics = []; | ||
for (var i in data) { | ||
characteristics.push({ | ||
aid: data[i].aid, | ||
iid: data[i].iid, | ||
status: HAPServer.Status.SERVICE_COMMUNICATION_FAILURE | ||
}); | ||
} | ||
} | ||
// 207 is "multi-status" since HomeKit is requesting multiple things and any one can fail independently | ||
// 207 is "multi-status" since HomeKit may be requesting multiple things and any one can fail independently | ||
response.writeHead(207, {"Content-Type": "application/hap+json"}); | ||
response.end(JSON.stringify({characteristics:characteristics})); | ||
}.bind(this)); | ||
@@ -680,17 +694,26 @@ } | ||
// requestData is a JSON payload | ||
var data = JSON.parse(requestData.toString()); | ||
// requestData is a JSON payload like { characteristics: [ { aid: 1, iid: 8, value: true, ev: true } ] } | ||
var data = JSON.parse(requestData.toString()).characteristics; // pull out characteristics array | ||
// call out to listeners to retrieve the latest accessories JSON | ||
this.emit('set-characteristics', data, events, once(function(err) { | ||
this.emit('set-characteristics', data, events, once(function(err, characteristics) { | ||
if (err) { | ||
debug("[%s] Error setting characteristics: %s", this.accessoryInfo.username, err.message); | ||
response.writeHead(500, "Server Error"); | ||
response.end(); | ||
return; | ||
// rewrite characteristics array to include error status for each characteristic requested | ||
characteristics = []; | ||
for (var i in data) { | ||
characteristics.push({ | ||
aid: data[i].aid, | ||
iid: data[i].iid, | ||
status: HAPServer.Status.SERVICE_COMMUNICATION_FAILURE | ||
}); | ||
} | ||
} | ||
response.writeHead(204, {"Content-Type": "application/hap+json"}); | ||
response.end(); | ||
// 207 is "multi-status" since HomeKit may be setting multiple things and any one can fail independently | ||
response.writeHead(207, {"Content-Type": "application/hap+json"}); | ||
response.end(JSON.stringify({characteristics:characteristics})); | ||
}.bind(this))); | ||
@@ -697,0 +720,0 @@ } |
{ | ||
"name": "hap-nodejs", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "HAP-NodeJS is a Node.js implementation of HomeKit Accessory Server.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 3 instances in 1 package
219653
5163
2