New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hap-node-client

Package Overview
Dependencies
Maintainers
1
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hap-node-client - npm Package Compare versions

Comparing version 0.2.8-beta.0 to 0.2.8-beta.1

lib/dnsEqual.js

903

HAPNodeJSClient.js

@@ -13,2 +13,4 @@ 'use strict';

var monitorBridgeUpdates = require('./lib/monitorBridgeUpdates.js');
axiosRetry(axios, { retries: 3 });

@@ -23,6 +25,2 @@

module.exports = {
HAPNodeJSClient: HAPNodeJSClient
};
/**

@@ -45,68 +43,459 @@ * HAPNodeJSClient - Client for Homebridge and HAP-NodeJS in insecure mode.

function HAPNodeJSClient(options) {
// console.log('Options', options);
this.debug = options.debug || false;
this.refresh = options.refresh || 900;
this.timeout = options.timeout || 20;
this.reqTimeout = options.reqTimeout || 7000;
this.RegisterPin('default', options.pin || '031-45-154');
filter = options.filter || false;
if (this.debug) {
let debugEnable = require('debug');
let namespaces = debugEnable.disable();
var populateCacheTimeout;
// this.log('DEBUG-1', namespaces);
if (namespaces) {
namespaces = namespaces + ',hap*';
} else {
namespaces = 'hap*';
class HAPNodeJSClient {
constructor(options) {
// console.log('Options', options);
this.debug = options.debug || false;
this.refresh = options.refresh || 900;
this.timeout = options.timeout || 20;
this.reqTimeout = options.reqTimeout || 7000;
this.RegisterPin('default', options.pin || '031-45-154');
filter = options.filter || false;
if (this.debug) {
let debugEnable = require('debug');
let namespaces = debugEnable.disable();
// this.log('DEBUG-1', namespaces);
if (namespaces) {
namespaces = namespaces + ',hap*';
} else {
namespaces = 'hap*';
}
// this.log('DEBUG-2', namespaces);
debugEnable.enable(namespaces);
}
// this.log('DEBUG-2', namespaces);
debugEnable.enable(namespaces);
}
this.eventRegistry = {};
_discovery.call(this);
this._eventBus = new EventEmitter();
setInterval(_discovery.bind(this), this.refresh * 1000);
this.eventRegistry = {};
_discovery.call(this); // Inital discovery of devices
this._eventBus = new EventEmitter();
this.discoveryTimer = setInterval(_discovery.bind(this), this.refresh * 1000);
/**
* HomeKit Accessory Characteristic event pass thru
*
* @event HAPNodeJSClient#Disconnected
* @Type {object}
* @property {string} server - IP Address and port of disconnected homebridge
* @example Sample Message
*
* { host: '192.168.1.4', port: 51826, aid: 16, iid: 11, status: false }
*/
this._eventBus.on('Disconnected', _reconnectServer.bind(this));
this._eventBus.on('Event', function (events) {
debug('Events', JSON.stringify(events));
/**
* HomeKit Accessory Characteristic event pass thru
*
* @event HAPNodeJSClient#hapEvent
* @event HAPNodeJSClient#Disconnected
* @Type {object}
* @property {string} host - IP Address of homebridge instance generating event
* @property {number} port - Port of homebridge instance generating event
* @property {number} deviceID - deviceID of homebridge instance generating event
* @property {number} aid - Accessory ID of accessory generating event
* @property {number} iid - Instance ID of accessory characteristic generating event
* @property {object} value - Updated characteristic value
* @property {string} server - IP Address and port of disconnected homebridge
* @example Sample Message
*
* [{"host":"192.168.1.13","port":43787,"deviceID":"76:59:CE:25:B9:6E","aid":1,"iid":13,"value":true,"status":true}]
* { host: '192.168.1.4', port: 51826, aid: 16, iid: 11, status: false }
*/
this.emit('hapEvent', events);
this.emit(events[0].host + events[0].port + events[0].aid, events);
events.forEach(function (event) {
// debug('hapEvent', event.host + event.port + event.aid + event.iid, event);
this.emit(event.host + event.port + event.aid + event.iid, event);
this.emit(event.deviceID + event.aid + event.iid, event);
this._eventBus.on('Disconnected', _reconnectServer.bind(this));
this._eventBus.on('Event', function (events) {
debug('Events', JSON.stringify(events));
/**
* HomeKit Accessory Characteristic event pass thru
*
* @event HAPNodeJSClient#hapEvent
* @Type {object}
* @property {string} host - IP Address of homebridge instance generating event
* @property {number} port - Port of homebridge instance generating event
* @property {number} deviceID - deviceID of homebridge instance generating event
* @property {number} aid - Accessory ID of accessory generating event
* @property {number} iid - Instance ID of accessory characteristic generating event
* @property {object} value - Updated characteristic value
* @example Sample Message
*
* [{"host":"192.168.1.13","port":43787,"deviceID":"76:59:CE:25:B9:6E","aid":1,"iid":13,"value":true,"status":true}]
*/
this.emit('hapEvent', events);
this.emit(events[0].host + events[0].port + events[0].aid, events);
events.forEach(function (event) {
// debug('hapEvent', event.host + event.port + event.aid + event.iid, event);
this.emit(event.host + event.port + event.aid + event.iid, event);
this.emit(event.deviceID + event.aid + event.iid, event);
}.bind(this));
}.bind(this));
}.bind(this));
// debug('This', this);
// debug('This', this);
}
/**
* HAPNodeJSClient.prototype.RegisterPin - Register pin numbers ()
*
* @class
* @param {type} key Unique identifier of homebridge instance (ip:port or deviceID)
* @param {type} pin Homebridge PIN
* @return {type} bool updated
*/
RegisterPin(key, pin) {
if (!key || (key in pins && pins[key] === pin)) {
return false;
}
key = key.toLowerCase();
pins[key] = pin;
debug('Registered/updated PIN for `%s`: %s', key, pin);
return true;
}
/**
* HAPNodeJSClient.prototype.HAPaccessories - Returns an array of all homebridge instances, and the accessories for each.
*
* @class
* @param {type} callback description
* @return {type} description
*/
HAPaccessories(callback) {
// This is a callback as in the future may need to call something
callback(discovered);
}
/**
* HAPNodeJSClient.prototype.mdnsCache
*
* @returns mdnsCacheObject
*/
mdnsCache() {
return mdnsCache;
}
// curl -X PUT http://127.0.0.1:51826/characteristics --header "Content-Type:Application/json"
// --header "authorization: 031-45-154" --data "{ \"characteristics\": [{ \"aid\": 2, \"iid\": 9, \"value\": 0}] }"
/**
* HAPNodeJSClient.prototype.HAPcontrolByDeviceID - Send a characteristic PUT Message to a particular homebridge instance
*
* @param {type} deviceID deviceID of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPcontrolByDeviceID(deviceID, body, callback) {
_mdnsLookup(deviceID, function (err, instance) {
if (err) {
callback(err);
} else {
HAPNodeJSClient.prototype.HAPcontrol.call(this, instance.host, instance.port, body, function (err, response) {
if (err) {
_mdnsError(deviceID);
}
callback(err, response);
}, instance);
}
}.bind(this));
}
/**
* HAPNodeJSClient.prototype.HAPcontrol - Send a characteristic PUT Message to a particular homebridge instance
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPcontrol(ipAddress, port, body, callback, instance) {
axios({
eventBus: this._eventBus,
method: 'PUT',
url: instance.url + '/characteristics',
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
data: body,
validateStatus: function (status) {
return true; // Resolve only if the status code is less than 500
}
}).then(function (response) {
// debug('HAPcontrol-then', response.status, response.statusText, response.headers, response.data, response.config);
switch (response.status) {
case 204:
callback(null, null);
break;
case 207:
callback(null, response.data);
break;
case 401:
case 470:
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, response.data);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
break;
default:
debug('Homebridge Control failed %s:%s Status: %s ', ipAddress, port, response.status, body, response.data);
callback(new Error('Homebridge control failed'));
}
}).catch(function (err) {
// Response s/b 200 OK
debug('HAPcontrol-catch', err);
debug('Homebridge Control failed %s:%s', ipAddress, port, body, err.message);
callback(err);
});
}
/**
* HAPNodeJSClient.prototype.HAPeventByDeviceID - Send a characteristic PUT Message to a particular homebridge instance, this maintains a socket connection for use in returning Events
*
* @param {type} deviceID deviceID homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPeventByDeviceID(deviceID, body, callback) {
// console.log('This-0', this);
_mdnsLookup(deviceID, function (err, instance) {
// debug('This-1', instance);
if (err) {
callback(err);
} else {
hapRequest({
eventBus: this._eventBus,
method: 'PUT',
deviceID: deviceID,
url: instance.url + '/characteristics',
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(deviceID),
'connection': 'keep-alive'
},
body: body
}, function (err, response) {
// Response s/b 200 OK
if (err) {
debug('Homebridge event reg failed %s:%s', instance.host, instance.port, body, err.message);
_mdnsError(deviceID);
callback(err);
} else if (response.statusCode !== 207 && response.statusCode !== 204) {
if (response.statusCode === 401 || response.statusCode === 470) {
debug('Homebridge auth failed, invalid PIN %s', _findPinByKey(deviceID), deviceID, body, err, response.body);
_mdnsError(deviceID);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(deviceID)));
} else {
debug('Homebridge event reg failed %s:%s Status: %s ', deviceID, response.statusCode, body, err, response.body);
_mdnsError(deviceID);
callback(new Error('Homebridge event reg failed'));
}
} else {
var rsp;
if (!this.eventRegistry[deviceID]) {
this.eventRegistry[deviceID] = [];
}
// debug('1', JSON.parse(body).characteristics);
this.eventRegistry[deviceID] = this.eventRegistry[deviceID].concat(JSON.parse(body).characteristics);
// debug('2', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[deviceID].sort((a, b) => (JSON.stringify(a) > JSON.stringify(b)) ? 1 : ((JSON.stringify(b) > JSON.stringify(a)) ? -1 : 0));
// debug('3', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[deviceID] = Array.from(new Set(this.eventRegistry[deviceID].map(JSON.stringify))).map(JSON.parse);
// debug('4', JSON.stringify(this.eventRegistry[key]));
try {
rsp = JSON.parse(response.body);
} catch (ex) {
debug('Homebridge Response Failed %s:%s', deviceID, response.statusCode, response.statusMessage);
debug('Homebridge Response Failed %s:%s', deviceID, response.body, ex);
callback(new Error(ex));
return;
}
callback(null, rsp);
}
}.bind(this));
}
}.bind(this));
}
/**
* HAPNodeJSClient.prototype.HAPevent - Send a characteristic PUT Message to a particular homebridge instance, this maintains a socket connection for use in returning Events
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPevent(ipAddress, port, body, callback, instance) {
hapRequest({
eventBus: this._eventBus,
method: 'PUT',
url: instance.url + '/characteristics',
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
body: body
}, function (err, response) {
// Response s/b 200 OK
if (err) {
debug('Homebridge event reg failed %s:%s', ipAddress, port, body, err.message);
callback(err);
} else if (response.statusCode !== 207 && response.statusCode !== 204) {
if (response.statusCode === 401 || response.statusCode === 470) {
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, err, response.body);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
} else {
debug('Homebridge event reg failed %s:%s Status: %s ', ipAddress, port, response.statusCode, body, err, response.body);
callback(new Error('Homebridge event reg failed'));
}
} else {
var rsp;
var key = ipAddress + ':' + port;
if (!this.eventRegistry[key]) {
this.eventRegistry[key] = [];
}
// debug('1', JSON.parse(body).characteristics);
this.eventRegistry[key] = this.eventRegistry[key].concat(JSON.parse(body).characteristics);
// debug('2', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[key].sort((a, b) => (JSON.stringify(a) > JSON.stringify(b)) ? 1 : ((JSON.stringify(b) > JSON.stringify(a)) ? -1 : 0));
// debug('3', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[key] = Array.from(new Set(this.eventRegistry[key].map(JSON.stringify))).map(JSON.parse);
// debug('4', JSON.stringify(this.eventRegistry[key]));
try {
rsp = JSON.parse(response.body);
} catch (ex) {
debug('Homebridge Response Failed %s:%s', ipAddress, port, response.statusCode, response.statusMessage);
debug('Homebridge Response Failed %s:%s', ipAddress, port, response.body, ex);
callback(new Error(ex));
return;
}
callback(null, rsp);
}
}.bind(this));
}
/**
* HAPNodeJSClient.prototype.HAPresourceByDeviceID - Send a characteristic PUT Message to a particular homebridge instance using resource interface, ie camera
*
* @param {type} DeviceID DeviceID of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPresourceByDeviceID(deviceID, body, callback) {
// console.log('This-0', this);
_mdnsLookup(deviceID, function (err, instance) {
// console.log('This-1', this);
if (err) {
callback(err);
} else {
HAPNodeJSClient.prototype.HAPresource.call(this, instance.host, instance.port, body, function (err, response) {
if (err) {
_mdnsError(deviceID);
}
callback(err, response);
}, instance);
}
}.bind(this));
}
/**
* HAPNodeJSClient.prototype.HAPresource - Send a characteristic PUT Message to a particular homebridge instance using resource interface, ie camera
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPresource(ipAddress, port, body, callback, instance) {
axios({
eventBus: this._eventBus,
method: 'POST',
url: instance.url + '/resource',
timeout: this.reqTimeout,
responseType: 'arraybuffer',
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
data: body,
validateStatus: function (status) {
return true; // Resolve only if the status code is less than 500
}
}).then(function (response) {
// debug('HAPcontrol-then', response.status, response.statusText, response.headers, response.config);
switch (response.status) {
case 200:
callback(null, response.data);
break;
case 401:
case 470:
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, response.data);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
break;
default:
debug('Homebridge Resource failed %s:%s Status: %s ', ipAddress, port, response.status, body, response.data);
callback(new Error('Homebridge Resource failed'));
}
}).catch(function (err) {
// Response s/b 200 OK
debug('HAPcontrol-catch', err);
debug('Homebridge Resource failed %s:%s', ipAddress, port, body, err.message);
callback(err);
});
}
/**
* HAPNodeJSClient.prototype.HAPstatusByDeviceID - Get current status for characteristics
*
* @param {type} deviceID deviceID of homebridge instance
* @param {type} body description
* @param {type} callback Callback to execute upon completion of characteristic getting, function(err, response)
*/
HAPstatusByDeviceID(deviceID, body, callback) {
// console.log('This-0', this);
_mdnsLookup(deviceID, function (err, instance) {
// console.log('This-1', this);
if (err) {
callback(err);
} else {
HAPNodeJSClient.prototype.HAPstatus.call(this, instance.host, instance.port, body, function (err, response) {
if (err) {
_mdnsError(deviceID);
}
callback(err, response);
}, instance);
}
}.bind(this));
}
/**
* HAPNodeJSClient.prototype.HAPstatus - Get current status for characteristics
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body description
* @param {type} callback Callback to execute upon completion of characteristic getting, function(err, response)
*/
HAPstatus(ipAddress, port, body, callback, instance) {
axios({
eventBus: this._eventBus,
method: 'GET',
url: instance.url + '/characteristics' + body,
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
validateStatus: function (status) {
return true; // Resolve only if the status code is less than 500
}
}).then(function (response) {
// debug('HAPstatus-then', response.status, response.statusText, response.headers, response.data, response.config);
switch (response.status) {
case 200:
callback(null, response.data);
break;
case 207:
callback(null, response.data);
break;
case 401:
case 470:
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, response.data);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
break;
default:
debug('Homebridge Status failed %s:%s Status: %s ', ipAddress, port, response.status, body, response.data);
callback(new Error('Homebridge Status failed'));
}
}).catch(function (err) {
// Response s/b 200 OK
debug('HAPstatus-catch', err);
debug('Homebridge Status failed %s:%s', ipAddress, port, body, err.message);
callback(err);
});
}
/**
* Destroy and shutdown HAPNodeJSClient - Used by testing
*/
async destroy() {
clearInterval(this.discoveryTimer);
clearInterval(populateCacheTimeout);
bonjour.destroy();
}
}

@@ -198,3 +587,3 @@

});
setTimeout(function () {
populateCacheTimeout = setTimeout(function () {
// debug('Timeout:');

@@ -219,122 +608,8 @@ browser.stop();

/**
* HAPNodeJSClient.prototype.RegisterPin - Register pin numbers ()
*
* @class
* @param {type} key Unique identifier of homebridge instance (ip:port or deviceID)
* @param {type} pin Homebridge PIN
* @return {type} bool updated
*/
HAPNodeJSClient.prototype.RegisterPin = function (key, pin) {
if (!key || (key in pins && pins[key] === pin)) {
return false;
}
key = key.toLowerCase();
pins[key] = pin;
debug('Registered/updated PIN for `%s`: %s', key, pin);
return true;
};
/**
* HAPNodeJSClient.prototype.HAPaccessories - Returns an array of all homebridge instances, and the accessories for each.
*
* @class
* @param {type} callback description
* @return {type} description
*/
HAPNodeJSClient.prototype.HAPaccessories = function (callback) {
// This is a callback as in the future may need to call something
callback(discovered);
};
/**
* HAPNodeJSClient.prototype.mdnsCache
*
* @returns mdnsCacheObject
*/
HAPNodeJSClient.prototype.mdnsCache = function () {
return mdnsCache;
};
// curl -X PUT http://127.0.0.1:51826/characteristics --header "Content-Type:Application/json"
// --header "authorization: 031-45-154" --data "{ \"characteristics\": [{ \"aid\": 2, \"iid\": 9, \"value\": 0}] }"
/**
* HAPNodeJSClient.prototype.HAPcontrolByDeviceID - Send a characteristic PUT Message to a particular homebridge instance
*
* @param {type} deviceID deviceID of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPcontrolByDeviceID = function (deviceID, body, callback) {
_mdnsLookup(deviceID, function (err, instance) {
if (err) {
callback(err);
} else {
HAPNodeJSClient.prototype.HAPcontrol.call(this, instance.host, instance.port, body, function (err, response) {
if (err) {
_mdnsError(deviceID);
}
callback(err, response);
}, instance);
}
}.bind(this));
};
/**
* HAPNodeJSClient.prototype.HAPcontrol - Send a characteristic PUT Message to a particular homebridge instance
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPcontrol = function (ipAddress, port, body, callback, instance) {
axios({
eventBus: this._eventBus,
method: 'PUT',
url: instance.url + '/characteristics',
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
data: body,
validateStatus: function (status) {
return true; // Resolve only if the status code is less than 500
}
}).then(function (response) {
// debug('HAPcontrol-then', response.status, response.statusText, response.headers, response.data, response.config);
switch (response.status) {
case 204:
callback(null, null);
break;
case 207:
callback(null, response.data);
break;
case 401:
case 470:
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, response.data);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
break;
default:
debug('Homebridge Control failed %s:%s Status: %s ', ipAddress, port, response.status, body, response.data);
callback(new Error('Homebridge control failed'));
}
}).catch(function (err) {
// Response s/b 200 OK
debug('HAPcontrol-catch', err);
debug('Homebridge Control failed %s:%s', ipAddress, port, body, err.message);
callback(err);
});
};
/**
* _reconnectServer - Reconnect to event server

@@ -426,289 +701,11 @@ *

/**
* HAPNodeJSClient.prototype.HAPeventByDeviceID - Send a characteristic PUT Message to a particular homebridge instance, this maintains a socket connection for use in returning Events
*
* @param {type} deviceID deviceID homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPeventByDeviceID = function (deviceID, body, callback) {
// console.log('This-0', this);
_mdnsLookup(deviceID, function (err, instance) {
// debug('This-1', instance);
if (err) {
callback(err);
} else {
hapRequest({
eventBus: this._eventBus,
method: 'PUT',
deviceID: deviceID,
url: instance.url + '/characteristics',
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(deviceID),
'connection': 'keep-alive'
},
body: body
}, function (err, response) {
// Response s/b 200 OK
if (err) {
debug('Homebridge event reg failed %s:%s', instance.host, instance.port, body, err.message);
_mdnsError(deviceID);
callback(err);
} else if (response.statusCode !== 207 && response.statusCode !== 204) {
if (response.statusCode === 401 || response.statusCode === 470) {
debug('Homebridge auth failed, invalid PIN %s', _findPinByKey(deviceID), deviceID, body, err, response.body);
_mdnsError(deviceID);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(deviceID)));
} else {
debug('Homebridge event reg failed %s:%s Status: %s ', deviceID, response.statusCode, body, err, response.body);
_mdnsError(deviceID);
callback(new Error('Homebridge event reg failed'));
}
} else {
var rsp;
if (!this.eventRegistry[deviceID]) {
this.eventRegistry[deviceID] = [];
}
// debug('1', JSON.parse(body).characteristics);
this.eventRegistry[deviceID] = this.eventRegistry[deviceID].concat(JSON.parse(body).characteristics);
// debug('2', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[deviceID].sort((a, b) => (JSON.stringify(a) > JSON.stringify(b)) ? 1 : ((JSON.stringify(b) > JSON.stringify(a)) ? -1 : 0));
// debug('3', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[deviceID] = Array.from(new Set(this.eventRegistry[deviceID].map(JSON.stringify))).map(JSON.parse);
// debug('4', JSON.stringify(this.eventRegistry[key]));
try {
rsp = JSON.parse(response.body);
} catch (ex) {
debug('Homebridge Response Failed %s:%s', deviceID, response.statusCode, response.statusMessage);
debug('Homebridge Response Failed %s:%s', deviceID, response.body, ex);
callback(new Error(ex));
return;
}
callback(null, rsp);
}
}.bind(this));
}
}.bind(this));
module.exports = {
HAPNodeJSClient: HAPNodeJSClient
};
/**
* HAPNodeJSClient.prototype.HAPevent - Send a characteristic PUT Message to a particular homebridge instance, this maintains a socket connection for use in returning Events
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPevent = function (ipAddress, port, body, callback, instance) {
hapRequest({
eventBus: this._eventBus,
method: 'PUT',
url: instance.url + '/characteristics',
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
body: body
}, function (err, response) {
// Response s/b 200 OK
if (err) {
debug('Homebridge event reg failed %s:%s', ipAddress, port, body, err.message);
callback(err);
} else if (response.statusCode !== 207 && response.statusCode !== 204) {
if (response.statusCode === 401 || response.statusCode === 470) {
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, err, response.body);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
} else {
debug('Homebridge event reg failed %s:%s Status: %s ', ipAddress, port, response.statusCode, body, err, response.body);
callback(new Error('Homebridge event reg failed'));
}
} else {
var rsp;
var key = ipAddress + ':' + port;
if (!this.eventRegistry[key]) {
this.eventRegistry[key] = [];
}
// debug('1', JSON.parse(body).characteristics);
this.eventRegistry[key] = this.eventRegistry[key].concat(JSON.parse(body).characteristics);
// debug('2', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[key].sort((a, b) => (JSON.stringify(a) > JSON.stringify(b)) ? 1 : ((JSON.stringify(b) > JSON.stringify(a)) ? -1 : 0));
// debug('3', JSON.stringify(this.eventRegistry[key]));
this.eventRegistry[key] = Array.from(new Set(this.eventRegistry[key].map(JSON.stringify))).map(JSON.parse);
// debug('4', JSON.stringify(this.eventRegistry[key]));
try {
rsp = JSON.parse(response.body);
} catch (ex) {
debug('Homebridge Response Failed %s:%s', ipAddress, port, response.statusCode, response.statusMessage);
debug('Homebridge Response Failed %s:%s', ipAddress, port, response.body, ex);
callback(new Error(ex));
return;
}
callback(null, rsp);
}
}.bind(this));
};
/**
* HAPNodeJSClient.prototype.HAPresourceByDeviceID - Send a characteristic PUT Message to a particular homebridge instance using resource interface, ie camera
*
* @param {type} DeviceID DeviceID of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPresourceByDeviceID = function (deviceID, body, callback) {
// console.log('This-0', this);
_mdnsLookup(deviceID, function (err, instance) {
// console.log('This-1', this);
if (err) {
callback(err);
} else {
HAPNodeJSClient.prototype.HAPresource.call(this, instance.host, instance.port, body, function (err, response) {
if (err) {
_mdnsError(deviceID);
}
callback(err, response);
}, instance);
}
}.bind(this));
};
/**
* HAPNodeJSClient.prototype.HAPresource - Send a characteristic PUT Message to a particular homebridge instance using resource interface, ie camera
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body An array of HomeKit characteristic updates, [{ \"aid\": 2, \"iid\": 9, \"value\": 0}]
* @param {type} callback Callback to execute upon completion of characteristic setting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPresource = function (ipAddress, port, body, callback, instance) {
axios({
eventBus: this._eventBus,
method: 'POST',
url: instance.url + '/resource',
timeout: this.reqTimeout,
responseType: 'arraybuffer',
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
data: body,
validateStatus: function (status) {
return true; // Resolve only if the status code is less than 500
}
}).then(function (response) {
// debug('HAPcontrol-then', response.status, response.statusText, response.headers, response.config);
switch (response.status) {
case 200:
callback(null, response.data);
break;
case 401:
case 470:
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, response.data);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
break;
default:
debug('Homebridge Resource failed %s:%s Status: %s ', ipAddress, port, response.status, body, response.data);
callback(new Error('Homebridge Resource failed'));
}
}).catch(function (err) {
// Response s/b 200 OK
debug('HAPcontrol-catch', err);
debug('Homebridge Resource failed %s:%s', ipAddress, port, body, err.message);
callback(err);
});
};
/**
* HAPNodeJSClient.prototype.HAPstatusByDeviceID - Get current status for characteristics
*
* @param {type} deviceID deviceID of homebridge instance
* @param {type} body description
* @param {type} callback Callback to execute upon completion of characteristic getting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPstatusByDeviceID = function (deviceID, body, callback) {
// console.log('This-0', this);
_mdnsLookup(deviceID, function (err, instance) {
// console.log('This-1', this);
if (err) {
callback(err);
} else {
HAPNodeJSClient.prototype.HAPstatus.call(this, instance.host, instance.port, body, function (err, response) {
if (err) {
_mdnsError(deviceID);
}
callback(err, response);
}, instance);
}
}.bind(this));
};
/**
* HAPNodeJSClient.prototype.HAPstatus - Get current status for characteristics
*
* @param {type} ipAddress IP Address of homebridge instance
* @param {type} port Port of homebridge instance
* @param {type} body description
* @param {type} callback Callback to execute upon completion of characteristic getting, function(err, response)
*/
HAPNodeJSClient.prototype.HAPstatus = function (ipAddress, port, body, callback, instance) {
axios({
eventBus: this._eventBus,
method: 'GET',
url: instance.url + '/characteristics' + body,
timeout: this.reqTimeout,
headers: {
'Content-Type': 'Application/json',
'authorization': _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port),
'connection': 'keep-alive'
},
validateStatus: function (status) {
return true; // Resolve only if the status code is less than 500
}
}).then(function (response) {
// debug('HAPstatus-then', response.status, response.statusText, response.headers, response.data, response.config);
switch (response.status) {
case 200:
callback(null, response.data);
break;
case 207:
callback(null, response.data);
break;
case 401:
case 470:
debug('Homebridge auth failed, invalid PIN %s %s:%s', _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port), ipAddress, port, body, response.data);
callback(new Error('Homebridge auth failed, invalid PIN ' + _findPinByKey(instance ? instance.deviceID : ipAddress + ':' + port)));
break;
default:
debug('Homebridge Status failed %s:%s Status: %s ', ipAddress, port, response.status, body, response.data);
callback(new Error('Homebridge Status failed'));
}
}).catch(function (err) {
// Response s/b 200 OK
debug('HAPstatus-catch', err);
debug('Homebridge Status failed %s:%s', ipAddress, port, body, err.message);
callback(err);
});
};
function _getAccessories(instance, callback) {

@@ -715,0 +712,0 @@ // debug('_getAccessories()', filter, instance.url + '/accessories');

@@ -313,2 +313,5 @@ const { _responseLineRegex } = require('./lib/httpParser');

});
afterAll(async () => {
await homebridges.destroy();
}, 30000);
});
{
"name": "hap-node-client",
"version": "0.2.8-beta.0",
"version": "0.2.8-beta.1",
"description": "Client for Hap-NodeJS",

@@ -15,2 +15,4 @@ "main": "HAPNodeJSClient.js",

"devDependencies": {
"@types/jest": "^29.5.10",
"@types/node": "^20.10.0",
"documentation": "^14.0.3",

@@ -37,3 +39,3 @@ "hap-nodejs": "^0.11.2",

"ignore": [],
"exec": "jest",
"exec": "jest --detectOpenHandles",
"signal": "SIGTERM",

@@ -40,0 +42,0 @@ "env": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc