UNPKG

homebridge-websocket

Version:
270 lines (216 loc) 8.48 kB
'use strict'; var util = require('util'); var Utils = require('./lib/utils.js').Utils; var WebsocketAccessory = require('./lib/accessory.js').Accessory; var Websocket = require('./lib/websocket.js').Websocket; var Accessory, Service, Characteristic, UUIDGen; var cachedAccessories = 0; var platform_name = "websocket"; var plugin_name = "homebridge-" + platform_name; var storagePath; module.exports = function(homebridge) { console.log("homebridge API version: " + homebridge.version); Accessory = homebridge.platformAccessory; Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; UUIDGen = homebridge.hap.uuid; // Universally Unique IDentifier storagePath = homebridge.user.storagePath(); homebridge.registerPlatform(plugin_name, platform_name, WebsocketPlatform, true); } function WebsocketPlatform(log, config, api) { this.log = log; this.accessories = {}; this.hap_accessories = {}; this.log.debug("storagePath = %s", storagePath); this.log.debug("config = %s", JSON.stringify(config)); if (typeof(config) !== "undefined" && config !== null) { this.port = config.port || {"port": 4050}; } else { this.log.error("config undefined or null!"); this.log("storagePath = %s", storagePath); process.exit(1); } var plugin_version = Utils.readPluginVersion(); this.log("%s v%s", plugin_name, plugin_version); var params = { "log": this.log, "plugin_name": plugin_name, "port": this.port, "accessories": this.accessories, "Characteristic": Characteristic, "addAccessory": this.addAccessory.bind(this), "removeAccessory": this.removeAccessory.bind(this), "getAccessories": this.getAccessories.bind(this) } this.Websocket = new Websocket(params); Utils.read_npmVersion(plugin_name, function(npm_version) { if (npm_version > plugin_version) { this.log("A new version %s is avaiable", npm_version); } }.bind(this)); if (api) { this.api = api; this.api.on('didFinishLaunching', function() { this.log("Plugin - DidFinishLaunching"); this.Websocket.startServer(); this.log.debug("Number of cached Accessories: %s", cachedAccessories); this.log("Number of Accessories: %s", Object.keys(this.accessories).length); }.bind(this)); //this.log.debug("WebsocketPlatform %s", JSON.stringify(this.accessories)); } } WebsocketPlatform.prototype.addAccessory = function(accessoryDef) { var name = accessoryDef.name; var ack, message; var isValid; var service_type = accessoryDef.service; var manufacturer = accessoryDef.manufacturer; var model = accessoryDef.model; var serialnumber = accessoryDef.serialnumber; var firmwarerevision = accessoryDef.firmwarerevision; var service_name; if (!this.accessories[name]) { var uuid = UUIDGen.generate(name); var newAccessory = new Accessory(name, uuid); newAccessory.reachable = true; newAccessory.context.service_name = accessoryDef.service; //this.log.debug("addAccessory UUID = %s", newAccessory.UUID); var i_accessory = new WebsocketAccessory(this.buildParams(accessoryDef)); isValid = i_accessory.addService(newAccessory); if (isValid) { i_accessory.configureAccessory(newAccessory); this.accessories[name] = i_accessory; this.hap_accessories[name] = newAccessory; this.api.registerPlatformAccessories(plugin_name, platform_name, [newAccessory]); ack = true; message = "accessory '" + name + "' is added."; } else { ack = false; message = "service '" + accessoryDef.service + "' undefined."; } } else { ack = false; message = "name '" + name + "' is already used."; } this.log("addAccessory %s", message); this.Websocket.sendAck(ack, message); if (ack) { var now = new Date().toISOString().slice(0,16); var plugin_version = Utils.readPluginVersion(); var plugin_v = "v" + plugin_version; if (typeof manufacturer === "undefined") { manufacturer = plugin_name; } if (typeof model === "undefined") { model = plugin_v; } if (typeof serialnumber === "undefined") { serialnumber = now; } if (typeof firmwarerevision === "undefined") { firmwarerevision = plugin_version; } this.setAccessoryInformation({"name":name,"manufacturer":manufacturer,"model":model,"serialnumber":serialnumber,"firmwarerevision":firmwarerevision}, false); } } WebsocketPlatform.prototype.setAccessoryInformation = function(accessory) { this.log.debug("WebsocketPlatform.setAccessoryInformation %s", JSON.stringify(accessory)); var message; var ack; var name = accessory.name; if (typeof this.hap_accessories[name] === "undefined") { ack = false; message = "accessory '" + name + "' undefined."; } else { var service = this.hap_accessories[name].getService(Service.AccessoryInformation); if (typeof accessory.manufacturer !== "undefined") { service.setCharacteristic(Characteristic.Manufacturer, accessory.manufacturer); ack = true; } if (typeof accessory.model !== "undefined") { service.setCharacteristic(Characteristic.Model, accessory.model); ack = true; } if (typeof accessory.serialnumber !== "undefined") { service.setCharacteristic(Characteristic.SerialNumber, accessory.serialnumber); ack = true; } if (typeof accessory.firmwarerevision !== "undefined") { service.setCharacteristic(Characteristic.FirmwareRevision, accessory.firmwarerevision); ack = true; } if (ack) { message = "accessory '" + name + "', accessoryinformation is set."; } else { message = "accessory '" + name + "', accessoryinforrmation properties undefined."; } } this.Websocket.sendAck(ack, message); } WebsocketPlatform.prototype.configureAccessory = function(accessory) { //this.log.debug("configureAccessory %s", JSON.stringify(accessory.services, null, 2)); cachedAccessories++; var name = accessory.displayName; var uuid = accessory.UUID; var accessoryDef = {}; accessoryDef.name = name; accessoryDef.service = accessory.context.service_name; if (this.accessories[name]) { this.log.error("configureAccessory %s UUID %s already used.", name, uuid); process.exit(1); } accessory.reachable = true; var i_accessory = new WebsocketAccessory(this.buildParams(accessoryDef)); i_accessory.configureAccessory(accessory); this.accessories[name] = i_accessory; this.hap_accessories[name] = accessory; } WebsocketPlatform.prototype.removeAccessory = function(name) { var ack, message; if (typeof(this.accessories[name]) !== "undefined") { this.log.debug("removeAccessory '%s'", name); this.api.unregisterPlatformAccessories(plugin_name, platform_name, [this.hap_accessories[name]]); delete this.accessories[name]; delete this.hap_accessories[name]; ack = true; message = "accessory '" + name + "' is removed."; } else { ack = false; message = "accessory '" + name + "' not found."; } this.log("removeAccessory %s", message); this.Websocket.sendAck(ack, message); } WebsocketPlatform.prototype.getAccessories = function(name) { var accessories = {}; var def = {}; var service, characteristics; switch (name) { case "all": for (var k in this.accessories) { //this.log("getAccessories %s", JSON.stringify(this.accessories[k], null, 2)); service = this.accessories[k].service_name; characteristics = this.accessories[k].i_value; def = {"service": service, "characteristics": characteristics}; accessories[k] = def; } break; default: service = this.accessories[name].service_name; characteristics = this.accessories[name].i_value; def = {"service": service, "characteristics": characteristics}; accessories[name] = def; } //this.log("getAccessory %s", JSON.stringify(accessories, null, 2)); this.Websocket.sendAccessories(accessories); } WebsocketPlatform.prototype.buildParams = function (accessoryDef) { var params = { "accessoryDef": accessoryDef, "log": this.log, "Service": Service, "Characteristic": Characteristic, "Websocket": this.Websocket } //this.log.debug("configureAccessories %s", JSON.stringify(params.accessory_config)); return params; }