UNPKG

homebridge-mqtt-phicomm-dc1-powerstrip

Version:

A Homebridge plugin to create a power strip for Phicomm DC1 through MQTT.

179 lines (149 loc) 5.66 kB
var mqtt = require('mqtt') var Service, Characteristic, HomebridgeAPI, UUIDGen; var that; module.exports = function(homebridge) { Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; HomebridgeAPI = homebridge; UUIDGen = homebridge.hap.uuid; homebridge.registerAccessory("homebridge-mqtt-Phicomm-DC1", "mqttPhicommDC1", PowerStrip); } function PowerStrip(log, config) { this.log = log; this.config = config; this.name = config.name; this.services = []; this.ids = []; if (!config) { return; } if (!this.name) { this.log("\x1b[31mName not specified!\x1b[0m"); return; } else if (!config.mqtt) { this.log("\x1b[31mMQTT config not specified!\x1b[0m"); return; } else if (!config.mqtt.host || !config.mqtt.port) { this.log("\x1b[31mYou need to specify the MQTT host and port!\x1b[0m"); return; } else if (!config.topics || (!config.topics.getOn && !config.topics.setOn)) { this.log("\x1b[31mYou need to specify the topics!\x1b[0m"); return; } // TODO Allow SSL. var mqttOptions = { port: config.mqtt.port, clientId: 'homebridge_' + this.name, username: config.mqtt.username, password: config.mqtt.password, reconnectPeriod: config.mqtt.reconnectInterval || 2000, connectTimeout: config.mqtt.connectTimeout || 10000 } this.mqttClient = mqtt.connect('mqtt://' + config.mqtt.host, mqttOptions); this.mqttClient.on('message', this.mqttMessage); this.mqttClient.on('connect', this.mqttConnect); this.mqttClient.on('error', this.mqttError); this.mqttErrorCount = 0; this.maxMqttErrorCount = config.mqtt.maxErrorCount || 10; var informationService = new Service.AccessoryInformation(); informationService .setCharacteristic(Characteristic.Manufacturer, 'Phicomm') .setCharacteristic(Characteristic.Model, 'DC1') .setCharacteristic(Characteristic.SerialNumber, config.serial || "SN02311D6F200") .setCharacteristic(Characteristic.FirmwareRevision, "1.0.0"); for (let i = 0; i < 4; i++) { if (config.ids && config.ids[i]) { this.ids.push(config.ids[i]); } else { this.ids.push((i + 1).toString()); } let uuid = UUIDGen.generate(this.name + i); let name; if (this.config.names && this.config.names[i]) { name = this.config.names[i]; } else { name = this.name + "开关" + (i + 1); } let switchService = new Service.Outlet(name, uuid); switchService.getCharacteristic(Characteristic.On) .on('set', this.setOn.bind(this, i)); this.services.push(switchService); } this.services.push(informationService); that = this; } PowerStrip.prototype.mqttConnect = function() { that.log("Successful conection to " + that.config.mqtt.host + ":" + that.config.mqtt.port); that.mqttGetOnTopics = []; if(that.config.topics.getOn) { for (i = 0; i < 4; i++) { let topic = that.config.topics.getOn.replace(/{id}/, that.ids[i]); that.mqttClient.subscribe(topic, {'qos': that.config.mqtt.qos || 1}); that.mqttGetOnTopics.push([topic, i]); } } if (that.config.topics.retrieve) { if (that.config.topics.retrieve.notify) { if (that.config.topics.retrieve.get) { for (i = 0; i < 4; i++) { let topic = that.config.topics.retrieve.get.replace(/{id}/, that.ids[i]); that.mqttClient.subscribe(topic, {'qos': that.config.mqtt.qos || 1}); that.mqttGetOnTopics.push([topic, i]); } } for (i = 0; i < 4; i++) { let topic = that.config.topics.retrieve.notify.replace(/{id}/, that.ids[i]); that.mqttClient.publish(topic, that.config.topics.retrieve.message || '', {'qos': that.config.mqtt.qos || 1}); } } else { that.log("\x1b[31mYou need to specify the notify topic to retrieve the state!\x1b[0m"); } } } PowerStrip.prototype.mqttError = function(err) { that.log("\x1b[31mAn error has ocurred while connecting to mqtt broker: " + err + "\x1b[0m"); that.mqttErrorCount++; if (that.mqttErrorCount >= that.maxMqttErrorCount) { that.mqttClient.end(); } } PowerStrip.prototype.mqttMessage = function(topic, msg, packet) { if (that.checkValueInArrayOfArrays(topic, that.mqttGetOnTopics)) { let id = that.checkValueInArrayOfArrays(topic, that.mqttGetOnTopics)[1]; if (msg == (that.config.onValue || "true")) { that.services[id].getCharacteristic(Characteristic.On).updateValue(true); } else if (msg == (that.config.offValue || "false")) { that.services[id].getCharacteristic(Characteristic.On).updateValue(false); } else { that.log("\x1b[31mThe received value on the getOn topic (" + msg + ") is not one of the accepted values, state cannot be set.\x1b[0m"); } } } PowerStrip.prototype.setOn = function (id, on, callback) { if (this.config.topics.setOn) { let topic = this.config.topics.setOn.replace(/{id}/, this.ids[id]); if (on) { this.mqttClient.publish(topic, this.config.onValue || "true", {'qos': that.config.mqtt.qos || 1}); } else { this.mqttClient.publish(topic, this.config.offValue || "false", {'qos': that.config.mqtt.qos || 1}); } callback(); } else { this.log("\x1b[31msetOn topic has not been specified so the state can't be set\x1b[0m"); callback(on); } } PowerStrip.prototype.getServices = function() { return this.services; }; PowerStrip.prototype.checkValueInArrayOfArrays = function(value, array) { let arrayToReturn = null; array.forEach(i => { i.forEach((j, n, arr) => { if (j == value) { arrayToReturn = arr; } }); }); return arrayToReturn; }