homebridge-punt
Version:
Fhem-Gateway and Accessory-Simulator Plugin for Homebridge
210 lines (165 loc) • 5.83 kB
JavaScript
;
var util = require('util');
var path = require('path');
var Utils = require('./utils.js').Utils;
var port, plugin_name, gateway;
var connection, latest;
var accessories;
var Characteristic;
var WebSocketServer = require('ws').Server,
http = require('http'),
express = require('express'),
app = express();
module.exports = {
Simulator: Simulator
}
function Simulator(log, p_config, _plugin_name, _accessories, _Characteristic) {
this.log = log;
port = p_config.simulator.port || {"port": "4080"};
gateway = p_config.gateway;
plugin_name = _plugin_name;
accessories = _accessories;
Characteristic = _Characteristic;
this.ws;
connection = false;
}
Simulator.prototype.startServer = function() {
var public_index = path.join(__dirname, '../public/simulator');
app.use(express.static(public_index));
var public_dir = path.join(__dirname, '../public');
app.use(express.static(public_dir));
var server = http.createServer(app);
server.listen(port, function() {
this.log("Simulator is running on port %s", server.address().port);
}.bind(this));
var wss = new WebSocketServer({server: server});
wss.on('connection', function(ws) {
this.ws = ws;
connection = true;
this.log("Simulator client ip %s connected", ws.upgradeReq.connection.remoteAddress);
latest = Utils.get_npmVersion(plugin_name);
this.refresh("all");
this.data = {"type": "info", "spec":
{
"plugin": plugin_name,
"version": Utils.getPluginVersion(),
"latest": latest,
"port": port
}
};
this.sendData(this.data);
ws.on('open', function open() {
this.log("Simulator open");
}.bind(this));
ws.on('close', function close() {
this.log("Simulator client ip %s disconnected", ws.upgradeReq.connection.remoteAddress);
connection = false;
}.bind(this));
ws.on('message', function message(data) {
//this.log.debug("Simulator received: %s", data);
var data = JSON.parse(data);
this.setValue(data);
}.bind(this));
}.bind(this));
}
Simulator.prototype.setValue = function(data) {
var value;
var t_characteristic = data.characteristic;
var uuid = data.uuid;
var name = accessories[uuid].name;
//this.log.debug("Simulator.onmessage: %s %s %s", name, t_characteristic, data.value);
var sc = accessories[uuid].service.getCharacteristic(Characteristic[t_characteristic]);
//this.log.debug("Simulator.onmessage: %s %s", name, JSON.stringify(sc));
if( typeof(sc) !== "undefined") {
switch (sc.props.format) {
case "bool":
value = (data.value == 0 || data.value == false) ? false : true;
//value = data.value;
break;
case "int":
case "uint8":
case "uint16":
case "unit32":
value = parseInt(data.value);
break;
case "float":
value = parseFloat(data.value);
break;
default:
// string, tlv8,
value = undefined;
this.log.warn("Simulator.setValue %s %s %s %s", name, t_characteristic, data.value, JSON.stringify(sc.props));
}
if (typeof(value) !== "undefined") { // && value != accessories[uuid].i_value[t_characteristic]) {
//this.log.debug("Simulator.setValue %s %s %s", name t_characteristic, data.value);
accessories[uuid].save_and_setValue("simulator", t_characteristic, value);
}
}
else {
this.log.warn("Simulator.setValue %s %s undefined, refresh the Browser", name, t_characteristic);
}
}
Simulator.prototype.get = function(uuid, t_characteristic, callback, context) {
//this.log.debug("Simulator.get %s %s", t_characteristic, name);
if (!gateway.run) {
callback(null, accessories[uuid].i_value[t_characteristic]);
}
}
Simulator.prototype.set = function(uuid, t_characteristic, value, callback, context) {
//this.log.debug("Simulator.set %s %s %s", t_characteristic, name, value);
if (!gateway.run) {
//accessories[uuid].i_value[t_characteristic] = value;
callback();
}
}
Simulator.prototype.characteristic_change = function(uuid, objValue) {
//this.log.debug("Simulator.characteristic_change %s %s %s", name, JSON.stringify(objValue));
var c = objValue.characteristic.displayName.replace(/\s/g, "");
var value = objValue.newValue;
if (accessories[uuid]) {
value = (c == "On") ? Utils.n2b(value) : value;
accessories[uuid].i_value[c] = value;
//this.log.debug("Simulator.c_change %s %s %s %s", name, accessories[uuid].name, c, value);
this.refresh(uuid, c);
}
}
Simulator.prototype.delete_content = function() {
var data = {"type": "command", "cmd_type": "delete"};
this.sendData(data);
}
Simulator.prototype.refresh = function(uuid, c) {
var data = {"type": "accessory", "accessories": {}};
if (uuid == "all") {
this.delete_content();
for (var k in accessories) {
var c = Object.keys(accessories[k].i_value)[0];
data.accessories[k] = this.extract(k, c);
}
}
else {
data.accessories[uuid] = this.extract(uuid, c);
}
this.sendData(data);
}
Simulator.prototype.extract = function(uuid, c) {
var a = accessories[uuid];
var i_data = {
"name": a.name,
"uuid": uuid,
"type": a.i_device.type,
"service_name": a.service_name,
"value": a.i_value,
"props": a.i_props
};
//this.log.debug("Simulator.extract %s %s %s", name, a.name, JSON.stringify(a.i_props));
return i_data;
}
Simulator.prototype.sendData = function(data) {
if (connection && this.ws.OPEN) {
var j_data = JSON.stringify(data);
//this.log.debug("Simulator.sendData %s", j_data);
this.ws.send(j_data, function ack(error) {
if (error) this.log("Simulator %s", error);
}.bind(this));
}
}