Might be stable now for Switches, Dimmers, & Thermostats

Basically, I needed to provide a default value instead of a
`getDefaultValue` function. Keeping with this for a while before trying
battery stats and door sensors again, but I think I figured out my
compliance problems…don’t know how it ever successfully added before,
actually.

Also removed some more cruft from the earlier old-API version and
started laying some groundwork for polling/updating from ZWay.
This commit is contained in:
S'pht'Kr
2015-09-07 19:16:51 +02:00
parent 2c1d9f6efb
commit 78987a775f
+71 -75
View File
@@ -57,6 +57,7 @@ function ZWayServerPlatform(log, config){
this.password = config["password"]; this.password = config["password"];
this.name_overrides = config["name_overrides"]; this.name_overrides = config["name_overrides"];
this.batteryLow = config["battery_low_level"]; this.batteryLow = config["battery_low_level"];
this.pollInterval = config["poll_interval"] || 2;
this.userAgent = "HomeBridge/-1^0.5"; this.userAgent = "HomeBridge/-1^0.5";
this.sessionId = ""; this.sessionId = "";
this.jar = request.jar(new tough.CookieJar()); this.jar = request.jar(new tough.CookieJar());
@@ -66,22 +67,6 @@ ZWayServerPlatform.getVDevTypeKey = function(vdev){
return vdev.deviceType + (vdev.metrics && vdev.metrics.probeTitle ? "." + vdev.metrics.probeTitle : "") return vdev.deviceType + (vdev.metrics && vdev.metrics.probeTitle ? "." + vdev.metrics.probeTitle : "")
} }
ZWayServerPlatform.getVDevServiceTypes = function(vdev){
var typeKey = ZWayServerPlatform.getVDevTypeKey(vdev);
switch (typeKey) {
case "switchBinary":
return [types.SWITCH_STYPE];
case "switchMultilevel":
return [types.LIGHTBULB_STYPE];
case "thermostat":
return [types.THERMOSTAT_STYPE];
case "sensorMultilevel.Temperature":
return [types.TEMPERATURE_SENSOR_STYPE];
case "sensorBinary.Door/Window":
return [types.GARAGE_DOOR_OPENER_STYPE];
}
}
ZWayServerPlatform.prototype = { ZWayServerPlatform.prototype = {
zwayRequest: function(opts){ zwayRequest: function(opts){
@@ -212,6 +197,13 @@ function ZWayServerAccessory(name, dclass, devDesc, platform) {
ZWayServerAccessory.prototype = { ZWayServerAccessory.prototype = {
getVDev: function(vdev){
return this.platform.zwayRequest({
method: "GET",
url: this.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id
})//.then(function());
}
,
command: function(vdev, command, value) { command: function(vdev, command, value) {
return this.platform.zwayRequest({ return this.platform.zwayRequest({
method: "GET", method: "GET",
@@ -237,7 +229,7 @@ ZWayServerAccessory.prototype = {
services.push(new Service.TemperatureSensor(vdev.metrics.title)); services.push(new Service.TemperatureSensor(vdev.metrics.title));
break; break;
case "sensorBinary.Door/Window": case "sensorBinary.Door/Window":
services.push(new Service.GarageDoorOpener(vdev.metrics.title)); //services.push(new Service.GarageDoorOpener(vdev.metrics.title));
break; break;
case "battery.Battery": case "battery.Battery":
services.push(new Service.BatteryService(vdev.metrics.title)); services.push(new Service.BatteryService(vdev.metrics.title));
@@ -316,23 +308,23 @@ ZWayServerAccessory.prototype = {
} }
if(cx instanceof Characteristic.On){ if(cx instanceof Characteristic.On){
cx.getDefaultValue = gdv; cx.zway_getValueFromVDev = function(vdev){
cx.on('get', function(callback, context){ var val = false;
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); if(vdev.metrics.level === "off"){
that.platform.zwayRequest({
method: "GET",
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
var val;
if(result.data.metrics.level === "off"){
val = false; val = false;
} else if(val <= 5) { } else if(vdev.metrics.level <= 5) {
val = false; val = false;
} else if (val > 5) { } else if (vdev.metrics.level > 5) {
val = true; val = true;
} }
callback(false, val); return val;
};
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
this.getVDev(vdev).then(function(result){
debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
callback(false, cx.zway_getValueFromVDev(result.data));
}); });
}.bind(this)); }.bind(this));
cx.on('set', function(powerOn, callback){ cx.on('set', function(powerOn, callback){
@@ -344,15 +336,15 @@ ZWayServerAccessory.prototype = {
} }
if(cx instanceof Characteristic.Brightness){ if(cx instanceof Characteristic.Brightness){
cx.getDefaultValue = gdv; cx.zway_getValueFromVDev = function(vdev){
return vdev.metrics.level;
};
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
that.platform.zwayRequest({ this.getVDev(vdev).then(function(result){
method: "GET", debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id callback(false, cx.zway_getValueFromVDev(result.data));
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
callback(false, result.data.metrics.level);
}); });
}.bind(this)); }.bind(this));
cx.on('set', function(level, callback){ cx.on('set', function(level, callback){
@@ -364,15 +356,15 @@ ZWayServerAccessory.prototype = {
} }
if(cx instanceof Characteristic.CurrentTemperature){ if(cx instanceof Characteristic.CurrentTemperature){
cx.getDefaultValue = gdv; cx.zway_getValueFromVDev = function(vdev){
return vdev.metrics.level;
};
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
that.platform.zwayRequest({ this.getVDev(vdev).then(function(result){
method: "GET", debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id callback(false, cx.zway_getValueFromVDev(result.data));
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
callback(false, result.data.metrics.level);
}); });
}.bind(this)); }.bind(this));
cx.minimumValue = vdev.metrics && vdev.metrics.min !== undefined ? vdev.metrics.min : -40; cx.minimumValue = vdev.metrics && vdev.metrics.min !== undefined ? vdev.metrics.min : -40;
@@ -381,15 +373,15 @@ ZWayServerAccessory.prototype = {
} }
if(cx instanceof Characteristic.TargetTemperature){ if(cx instanceof Characteristic.TargetTemperature){
cx.getDefaultValue = gdv; cx.zway_getValueFromVDev = function(vdev){
return vdev.metrics.level;
};
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
this.platform.zwayRequest({ this.getVDev(vdev).then(function(result){
method: "GET", debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id callback(false, cx.zway_getValueFromVDev(result.data));
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
callback(false, result.data.metrics.level);
}); });
}.bind(this)); }.bind(this));
cx.on('set', function(level, callback){ cx.on('set', function(level, callback){
@@ -405,10 +397,11 @@ ZWayServerAccessory.prototype = {
if(cx instanceof Characteristic.TemperatureDisplayUnits){ if(cx instanceof Characteristic.TemperatureDisplayUnits){
//TODO: Always in °C for now. //TODO: Always in °C for now.
cx.getDefaultValue = function(){ return Characteristic.TemperatureDisplayUnits.CELCIUS; }; cx.getDefaultValue = function(){ return Characteristic.TemperatureDisplayUnits.CELSIUS; };
cx.value = cx.getDefaultValue();
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
callback(false, Characteristic.TemperatureDisplayUnits.CELCIUS); callback(false, Characteristic.TemperatureDisplayUnits.CELSIUS);
}); });
cx.writable = false; cx.writable = false;
return cx; return cx;
@@ -417,6 +410,7 @@ ZWayServerAccessory.prototype = {
if(cx instanceof Characteristic.CurrentHeatingCoolingState){ if(cx instanceof Characteristic.CurrentHeatingCoolingState){
//TODO: Always HEAT for now, we don't have an example to work with that supports another function. //TODO: Always HEAT for now, we don't have an example to work with that supports another function.
cx.getDefaultValue = function(){ return Characteristic.CurrentHeatingCoolingState.HEAT; }; cx.getDefaultValue = function(){ return Characteristic.CurrentHeatingCoolingState.HEAT; };
cx.value = cx.getDefaultValue();
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
callback(false, Characteristic.CurrentHeatingCoolingState.HEAT); callback(false, Characteristic.CurrentHeatingCoolingState.HEAT);
@@ -427,6 +421,7 @@ ZWayServerAccessory.prototype = {
if(cx instanceof Characteristic.TargetHeatingCoolingState){ if(cx instanceof Characteristic.TargetHeatingCoolingState){
//TODO: Always HEAT for now, we don't have an example to work with that supports another function. //TODO: Always HEAT for now, we don't have an example to work with that supports another function.
cx.getDefaultValue = function(){ return Characteristic.TargetHeatingCoolingState.HEAT; }; cx.getDefaultValue = function(){ return Characteristic.TargetHeatingCoolingState.HEAT; };
cx.value = cx.getDefaultValue();
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
callback(false, Characteristic.TargetHeatingCoolingState.HEAT); callback(false, Characteristic.TargetHeatingCoolingState.HEAT);
@@ -436,17 +431,15 @@ ZWayServerAccessory.prototype = {
} }
if(cx instanceof Characteristic.CurrentDoorState){ if(cx instanceof Characteristic.CurrentDoorState){
cx.getDefaultValue = function(){ cx.zway_getValueFromVDev = function(vdev){
return vdev.metrics.level == "off" ? Characteristic.CurrentDoorState.CLOSED : Characteristic.CurrentDoorState.OPEN; return vdev.metrics.level === "off" ? Characteristic.CurrentDoorState.CLOSED : Characteristic.CurrentDoorState.OPEN;
}; };
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
this.platform.zwayRequest({ this.getVDev(vdev).then(function(result){
method: "GET", debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id callback(false, cx.zway_getValueFromVDev(result.data));
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
callback(false, result.data.metrics.level == "off" ? Characteristic.CurrentDoorState.CLOSED : Characteristic.CurrentDoorState.OPEN);
}); });
}.bind(this)); }.bind(this));
} }
@@ -454,6 +447,7 @@ ZWayServerAccessory.prototype = {
if(cx instanceof Characteristic.TargetDoorState){ if(cx instanceof Characteristic.TargetDoorState){
//TODO: We only support this for Door sensors now, so it's a fixed value. //TODO: We only support this for Door sensors now, so it's a fixed value.
cx.getDefaultValue = function(){ return Characteristic.TargetDoorState.CLOSED; }; cx.getDefaultValue = function(){ return Characteristic.TargetDoorState.CLOSED; };
cx.value = cx.getDefaultValue();
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
callback(false, Characteristic.TargetDoorState.CLOSED); callback(false, Characteristic.TargetDoorState.CLOSED);
@@ -465,6 +459,7 @@ ZWayServerAccessory.prototype = {
if(cx instanceof Characteristic.ObstructionDetected){ if(cx instanceof Characteristic.ObstructionDetected){
//TODO: We only support this for Door sensors now, so it's a fixed value. //TODO: We only support this for Door sensors now, so it's a fixed value.
cx.getDefaultValue = function(){ return false; }; cx.getDefaultValue = function(){ return false; };
cx.value = cx.getDefaultValue();
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
callback(false, false); callback(false, false);
@@ -474,29 +469,29 @@ ZWayServerAccessory.prototype = {
} }
if(cx instanceof Characteristic.BatteryLevel){ if(cx instanceof Characteristic.BatteryLevel){
cx.getDefaultValue = gdv; cx.zway_getValueFromVDev = function(vdev){
return vdev.metrics.level;
};
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
that.platform.zwayRequest({ this.getVDev(vdev).then(function(result){
method: "GET", debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id callback(false, cx.zway_getValueFromVDev(result.data));
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
callback(false, result.data.metrics.level);
}); });
}.bind(this)); }.bind(this));
} }
if(cx instanceof Characteristic.StatusLowBattery){ if(cx instanceof Characteristic.StatusLowBattery){
cx.getDefaultValue = function(){ return Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL; }; cx.zway_getValueFromVDev = function(vdev){
return vdev.metrics.level <= that.platform.batteryLow ? Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
};
cx.value = cx.zway_getValueFromVDev(vdev);
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
that.platform.zwayRequest({ this.getVDev(vdev).then(function(result){
method: "GET", debug("Got value: " + cx.zway_getValueFromVDev(result.data) + ", for " + vdev.metrics.title + ".");
url: that.platform.url + 'ZAutomation/api/v1/devices/' + vdev.id callback(false, cx.zway_getValueFromVDev(result.data));
}).then(function(result){
debug("Got value: " + result.data.metrics.level + ", for " + vdev.metrics.title + ".");
callback(false, result.data.metrics.level <= that.platform.batteryLow ? Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
}); });
}.bind(this)); }.bind(this));
} }
@@ -504,6 +499,7 @@ ZWayServerAccessory.prototype = {
if(cx instanceof Characteristic.ChargingState){ if(cx instanceof Characteristic.ChargingState){
//TODO: No known chargeable devices(?), so always return false. //TODO: No known chargeable devices(?), so always return false.
cx.getDefaultValue = function(){ return Characteristic.ChargingState.NOT_CHARGING; }; cx.getDefaultValue = function(){ return Characteristic.ChargingState.NOT_CHARGING; };
cx.value = cx.getDefaultValue();
cx.on('get', function(callback, context){ cx.on('get', function(callback, context){
debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"..."); debug("Getting value for " + vdev.metrics.title + ", characteristic \"" + cx.displayName + "\"...");
callback(false, Characteristic.ChargingState.NOT_CHARGING); callback(false, Characteristic.ChargingState.NOT_CHARGING);