mirror of
https://github.com/mtan93/homebridge.git
synced 2026-03-08 05:31:55 +00:00
more cleanups
handle sonos volume caching added garage door opener started with homematic keymatic (HM-SEC-KEY) even more cleanups :) rgb hue/sat/bri fix added identify for lightbulbs
This commit is contained in:
@@ -20,17 +20,16 @@ var types = require('HAP-NodeJS/accessories/types.js');
|
||||
var util = require('util');
|
||||
|
||||
|
||||
// cached readings from longpoll & query
|
||||
var FHEM_cached = {};
|
||||
|
||||
|
||||
// subscriptions to fhem longpoll evens
|
||||
var FHEM_subscriptions = {};
|
||||
function
|
||||
FHEM_subscribe(characteristic, inform_id, accessory) {
|
||||
FHEM_subscriptions[inform_id] = { 'characteristic': characteristic, 'accessory': accessory };
|
||||
//FHEM_subscriptions[inform_id] = characteristic;
|
||||
}
|
||||
|
||||
// cached readings from longpoll & query
|
||||
var FHEM_cached = {};
|
||||
//var FHEM_internal = {};
|
||||
function
|
||||
FHEM_update(inform_id, value, no_update) {
|
||||
var subscription = FHEM_subscriptions[inform_id];
|
||||
@@ -39,6 +38,18 @@ FHEM_update(inform_id, value, no_update) {
|
||||
|| FHEM_cached[inform_id] === value )
|
||||
return;
|
||||
|
||||
//if( FHEM_internal['.'+subscription.accessory.device+'-homekitID'] == undefined ) {
|
||||
// var info = subscription.characteristic.accessoryController.tcpServer.accessoryInfo;
|
||||
|
||||
// if( info.username ) {
|
||||
// var accessory = subscription.accessory;
|
||||
// var cmd = '{$defs{'+ accessory.device +'}->{homekitID} = "'+info.username+'" if(defined($defs{'+ accessory.device +'}));;}';
|
||||
// //accessory.execute( cmd );
|
||||
|
||||
// FHEM_internal['.'+accessory.device+'-homekitID'] = info.username;
|
||||
// }
|
||||
//}
|
||||
|
||||
FHEM_cached[inform_id] = value;
|
||||
//FHEM_cached[inform_id] = { 'value': value, 'timestamp': Date.now() };
|
||||
console.log(" caching: " + inform_id + ": " + value + " as " + typeof(value) );
|
||||
@@ -118,14 +129,25 @@ function FHEM_startLongpoll(connection) {
|
||||
continue;
|
||||
|
||||
if( reading == 'state') {
|
||||
if( accessory.isWindow ) {
|
||||
if( accessory.mappings.window ) {
|
||||
var level = 50;
|
||||
if( match = value.match(/^(\d+)/ ) )
|
||||
level = parseInt( match[1] );
|
||||
else if( value == 'locked' )
|
||||
level = 0;
|
||||
|
||||
FHEM_update( device+'-level', level );
|
||||
FHEM_update( accessory.mappings.window.informId, level );
|
||||
continue;
|
||||
|
||||
} else if( accessory.mappings.lock ) {
|
||||
var lock = 0;
|
||||
if( value.match( /^locked/ ) )
|
||||
lock = 1;
|
||||
|
||||
if( value.match( /uncertain/ ) )
|
||||
level = 4;
|
||||
|
||||
FHEM_update( accessory.mappings.lock.informId, lock );
|
||||
continue;
|
||||
|
||||
} else if( match = value.match(/dim(\d+)%/ ) ) {
|
||||
@@ -134,7 +156,7 @@ function FHEM_startLongpoll(connection) {
|
||||
FHEM_update( device+'-pct', pct );
|
||||
}
|
||||
|
||||
} else if(reading == accessory.hasRGB) {
|
||||
} else if(accessory.mappings.rgb && reading == accessory.mappings.rgb.reading) {
|
||||
var hsv = FHEM_rgb2hsv(value);
|
||||
var hue = parseInt( hsv[0] * 360 );
|
||||
var sat = parseInt( hsv[1] * 100 );
|
||||
@@ -354,6 +376,9 @@ FHEMPlatform.prototype = {
|
||||
} else if( s.Attributes.model == 'HM-SEC-WIN' ) {
|
||||
accessory = new FHEMAccessory(that.log, that.connection, s);
|
||||
|
||||
} else if( s.Attributes.model == 'HM-SEC-KEY' ) {
|
||||
accessory = new FHEMAccessory(that.log, that.connection, s);
|
||||
|
||||
} else if( s.Internals.TYPE == 'PRESENCE' ) {
|
||||
accessory = new FHEMAccessory(that.log, that.connection, s);
|
||||
|
||||
@@ -396,7 +421,7 @@ FHEMAccessory(log, connection, s) {
|
||||
|
||||
var match;
|
||||
if( match = s.PossibleSets.match(/[\^ ]pct\b/) ) {
|
||||
this.mappings.pct = { reading: 'pct', cmd: 'pct', min: 0, max: 100 };
|
||||
this.mappings.pct = { reading: 'pct', cmd: 'pct' };
|
||||
} else if( match = s.PossibleSets.match(/[\^ ]dim\d+%/) ) {
|
||||
s.hasDim = true;
|
||||
s.pctMax = 100;
|
||||
@@ -418,12 +443,12 @@ FHEMAccessory(log, connection, s) {
|
||||
|
||||
if( s.PossibleSets.match(/[\^ ]rgb\b/) ) {
|
||||
s.isLight = true;
|
||||
s.hasRGB = 'rgb';
|
||||
this.mappings.rgb = { reading: 'rgb', cmd: 'rgb' };
|
||||
if( s.Internals.TYPE == 'SWAP_0000002200000003' )
|
||||
s.hasRGB = '0B-RGBlevel';
|
||||
this.mappings.rgb = { reading: '0B-RGBlevel', cmd: 'rgb' };
|
||||
} else if( s.PossibleSets.match(/[\^ ]RGB\b/) ) {
|
||||
s.isLight = true;
|
||||
s.hasRGB = 'RGB';
|
||||
this.mappings.rgb = { reading: 'RGB', cmd: 'RGB' };
|
||||
}
|
||||
|
||||
if( s.Readings['measured-temp'] )
|
||||
@@ -433,8 +458,11 @@ FHEMAccessory(log, connection, s) {
|
||||
|
||||
if( s.Readings.volume )
|
||||
this.mappings.volume = { reading: 'volume', cmd: 'volume' };
|
||||
else if( s.Readings.Volume )
|
||||
this.mappings.volume = { reading: 'Volume', cmd: 'Volume' };
|
||||
else if( s.Readings.Volume ) {
|
||||
this.mappings.volume = { reading: 'Volume', cmd: 'Volume', nocache: true };
|
||||
if( s.Attributes.generateVolumeEvent == 1 )
|
||||
delete this.mappings.volume.nocache;
|
||||
}
|
||||
|
||||
if( s.Readings.humidity )
|
||||
this.mappings.humidity = { reading: 'humidity' };
|
||||
@@ -453,39 +481,48 @@ FHEMAccessory(log, connection, s) {
|
||||
if( genericType == 'switch' )
|
||||
s.isSwitch = true;
|
||||
|
||||
else if( genericType == 'garage' )
|
||||
this.mappings.garage = { cmdOpen: 'on', cmdClose: 'off' };
|
||||
|
||||
else if( genericType == 'light' )
|
||||
s.isLight = true;
|
||||
|
||||
else if( genericType == 'blind'
|
||||
|| s.Attributes.subType == 'blindActuator' ) {
|
||||
s.isBlind = 'pct';
|
||||
delete this.mappings.pct;
|
||||
this.mappings.blind = { reading: 'pct', cmd: 'pct' };
|
||||
|
||||
} else if( genericType == 'window'
|
||||
|| s.Attributes.model == 'HM-SEC-WIN' ) {
|
||||
s.isWindow = 'level';
|
||||
this.mappings.window = { reading: 'level', cmd: 'level' };
|
||||
|
||||
} else if( genericType == 'lock'
|
||||
|| s.Attributes.model == 'HM-SEC-KEY' ) {
|
||||
this.mappings.lock = { reading: 'lock' };
|
||||
|
||||
} else if( genericType == 'thermostat'
|
||||
|| s.Attributes.subType == 'thermostat' ) {
|
||||
s.isThermostat = true;
|
||||
|
||||
} else if( s.Internals.TYPE == 'CUL_FHTTK' ) {
|
||||
s.isContactSensor = 'Window';
|
||||
this.mappings.contact = { reading: 'Window' };
|
||||
|
||||
} else if( s.Attributes.subType == 'threeStateSensor' ) {
|
||||
s.isContactSensor = 'contact';
|
||||
this.mappings.contact = { reading: 'contact' };
|
||||
|
||||
} else if( s.Internals.TYPE == 'PRESENCE' )
|
||||
s.isOccupancySensor = true;
|
||||
this.mappings.occupancy = { reading: 'state' };
|
||||
|
||||
else if( s.Attributes.model == 'fs20di' )
|
||||
s.isLight = true;
|
||||
|
||||
if( s.PossibleSets.match(/[\^ ]desired-temp\b/) )
|
||||
s.isThermostat = 'desired-temp';
|
||||
this.mappings.thermostat = { reading: 'desired-temp', cmd: 'desired-temp' };
|
||||
else if( s.PossibleSets.match(/[\^ ]desiredTemperature\b/) )
|
||||
s.isThermostat = 'desiredTemperature';
|
||||
this.mappings.thermostat = { reading: 'desiredTemperature', cmd: 'desiredTemperature' };
|
||||
else if( s.isThermostat ) {
|
||||
s.isThermostat = false;
|
||||
delete this.mappings.thermostat;
|
||||
log( s.Internals.NAME + ' is NOT a thermostat. set for target temperature missing' );
|
||||
}
|
||||
|
||||
@@ -509,20 +546,26 @@ FHEMAccessory(log, connection, s) {
|
||||
}
|
||||
}
|
||||
|
||||
if( s.isBlind )
|
||||
log( s.Internals.NAME + ' is blind ['+ s.isBlind +']' );
|
||||
else if( s.isWindow )
|
||||
if( this.mappings.door )
|
||||
log( s.Internals.NAME + ' is door' );
|
||||
else if( this.mappings.garage )
|
||||
log( s.Internals.NAME + ' is garage' );
|
||||
else if( this.mappings.lock )
|
||||
log( s.Internals.NAME + ' is lock ['+ this.mappings.lock.reading +']' );
|
||||
else if( this.mappings.window )
|
||||
log( s.Internals.NAME + ' is window' );
|
||||
else if( s.isThermostat )
|
||||
log( s.Internals.NAME + ' is thermostat ['+ s.isThermostat +']' );
|
||||
else if( s.isContactSensor )
|
||||
log( s.Internals.NAME + ' is contactsensor [' + s.isContactSensor +']' );
|
||||
else if( s.isOccupancySensor )
|
||||
else if( this.mappings.blind )
|
||||
log( s.Internals.NAME + ' is blind ['+ this.mappings.blind.reading +']' );
|
||||
else if( this.mappings.thermostat )
|
||||
log( s.Internals.NAME + ' is thermostat ['+ this.mappings.thermostat.reading +']' );
|
||||
else if( this.mappings.contact )
|
||||
log( s.Internals.NAME + ' is contactsensor [' + this.mappings.contact.reading +']' );
|
||||
else if( this.mappings.occupancy )
|
||||
log( s.Internals.NAME + ' is occupancysensor' );
|
||||
else if( s.hasRGB )
|
||||
log( s.Internals.NAME + ' has RGB [0-' + s.hasRGB +']');
|
||||
else if( this.mappings.rgb )
|
||||
log( s.Internals.NAME + ' has RGB [0-' + this.mappings.rgb.reading +']');
|
||||
else if( this.mappings.pct )
|
||||
log( s.Internals.NAME + ' is dimable [0-'+ this.mappings.pct.max +']' );
|
||||
log( s.Internals.NAME + ' is dimable ['+ this.mappings.pct.reading +']' );
|
||||
else if( s.hasDim )
|
||||
log( s.Internals.NAME + ' is dimable [0-'+ s.pctMax +']' );
|
||||
else if( s.isLight )
|
||||
@@ -530,7 +573,7 @@ FHEMAccessory(log, connection, s) {
|
||||
else
|
||||
log( s.Internals.NAME + ' is switchable' );
|
||||
|
||||
if( this.hasOnOff )
|
||||
if( this.hasOnOff )
|
||||
log( s.Internals.NAME + ' has OnOff [' + this.hasOnOff + ']' );
|
||||
|
||||
if( this.mappings.hue )
|
||||
@@ -573,19 +616,13 @@ FHEMAccessory(log, connection, s) {
|
||||
|
||||
this.hasDim = s.hasDim;
|
||||
this.pctMax = s.pctMax;
|
||||
this.hasRGB = s.hasRGB;
|
||||
|
||||
this.isLight = s.isLight;
|
||||
this.isBlind = s.isBlind;
|
||||
this.isWindow = s.isWindow;
|
||||
this.isThermostat = s.isThermostat;
|
||||
this.isContactSensor = s.isContactSensor;
|
||||
this.isOccupancySensor = s.isOccupancySensor;
|
||||
this.isWindow = s.isWindow;
|
||||
this.isSwitch = s.isSwitch;
|
||||
|
||||
//log( util.inspect(s.Readings) );
|
||||
|
||||
if( this.isBlind || this.isDoor || this.isWindow || this.isThermostat )
|
||||
if( this.mappings.blind || this.mappings.door || this.mappings.garage || this.mappings.window || this.mappings.thermostat )
|
||||
delete this.mappings.onOff;
|
||||
|
||||
var that = this;
|
||||
@@ -598,7 +635,8 @@ FHEMAccessory(log, connection, s) {
|
||||
if( value != undefined ) {
|
||||
var inform_id = that.device +'-'+ reading;
|
||||
that.mappings[key].informId = inform_id;
|
||||
FHEM_cached[inform_id] = value;
|
||||
if( !that.mappings[key].nocache )
|
||||
FHEM_cached[inform_id] = value;
|
||||
}
|
||||
}
|
||||
} );
|
||||
@@ -612,10 +650,10 @@ FHEM_dim_values = [ 'dim06%', 'dim12%', 'dim18%', 'dim25%', 'dim31%', 'dim37%',
|
||||
FHEMAccessory.prototype = {
|
||||
reading2homekit: function(reading,value) {
|
||||
if( reading == 'hue' ) {
|
||||
value = Math.round(value * 360 / this.mappings.hue.max);
|
||||
value = Math.round(value * 360 / this.mappings.hue ? this.mappings.hue.max : 360);
|
||||
|
||||
} else if( reading == 'sat' ) {
|
||||
value = Math.round(value * 100 / this.mappings.sat.max);
|
||||
value = Math.round(value * 100 / this.mappings.sat ? this.mappings.sat.max : 100);
|
||||
|
||||
} else if( reading == 'pct' ) {
|
||||
value = parseInt( value );
|
||||
@@ -628,8 +666,6 @@ FHEMAccessory.prototype = {
|
||||
else
|
||||
value = 2;
|
||||
|
||||
value = parseInt(value);
|
||||
|
||||
} else if(reading == 'motor') {
|
||||
if( value.match(/^opening/))
|
||||
value = 1;
|
||||
@@ -638,16 +674,12 @@ FHEMAccessory.prototype = {
|
||||
else
|
||||
value = 2;
|
||||
|
||||
value = parseInt(value);
|
||||
|
||||
} else if( reading == 'transportState' ) {
|
||||
if( value == 'PLAYING' )
|
||||
value = 1;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
value = parseInt(value);
|
||||
|
||||
} else if( reading == 'volume'
|
||||
|| reading == 'Volume' ) {
|
||||
value = parseInt( value );
|
||||
@@ -658,15 +690,20 @@ FHEMAccessory.prototype = {
|
||||
else
|
||||
value = 0;
|
||||
|
||||
value = parseInt(value);
|
||||
|
||||
} else if( reading == 'Window' ) {
|
||||
if( value.match( /^Closed/ ) )
|
||||
value = 1;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
value = parseInt(value);
|
||||
} else if( reading == 'lock' ) {
|
||||
if( value.match( /^locked/ ) )
|
||||
value = 1;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
if( value.match( /uncertain/ ) )
|
||||
value = 4;
|
||||
|
||||
} else if( reading == 'temperature'
|
||||
|| reading == 'measured-temp'
|
||||
@@ -695,13 +732,11 @@ FHEMAccessory.prototype = {
|
||||
value = 0;
|
||||
else if( value == '000000' )
|
||||
value = 0;
|
||||
else if( value.match( /^[A-D]0$/ ) )
|
||||
else if( value.match( /^[A-D]0$/ ) ) // FIXME: should be handled by event_map now
|
||||
value = 0;
|
||||
else
|
||||
value = 1;
|
||||
|
||||
value = parseInt( value );
|
||||
|
||||
}
|
||||
|
||||
return(value);
|
||||
@@ -721,21 +756,14 @@ FHEMAccessory.prototype = {
|
||||
|
||||
command: function(c,value) {
|
||||
this.log(this.name + " sending command " + c + " with value " + value);
|
||||
if( c == 'on' ) {
|
||||
if( this.PossibleSets.match(/[\^ ]play\b/i) )
|
||||
cmd = "set " + this.device + " play";
|
||||
else if( this.PossibleSets.match(/[\^ ]on\b/) )
|
||||
cmd = "set " + this.device + " on";
|
||||
if( c == 'identify' ) {
|
||||
if( this.type == 'HUEDevice' )
|
||||
cmd = "set " + this.device + "alert select";
|
||||
else
|
||||
this.log(this.name + " Unhandled command! cmd=" + c + ", value=" + value);
|
||||
cmd = "set " + this.device + " toggle;; sleep 1;; set "+ this.device + " toggle";
|
||||
|
||||
} else if( c == 'off' ) {
|
||||
if( this.PossibleSets.match(/[\^ ]pause\b/i) )
|
||||
cmd = "set " + this.device + " pause";
|
||||
else if( this.PossibleSets.match(/[\^ ]off\b/) )
|
||||
cmd = "set " + this.device + " off";
|
||||
else
|
||||
this.log(this.device + " Unhandled command! cmd=" + c + ", value=" + value);
|
||||
} else if( c == 'set' ) {
|
||||
cmd = "set " + this.device + " " + value;
|
||||
|
||||
} else if( c == 'volume' ) {
|
||||
cmd = "set " + this.device + " volume " + value;
|
||||
@@ -776,10 +804,7 @@ FHEMAccessory.prototype = {
|
||||
|
||||
value = FHEM_hsv2rgb( h, s, v );
|
||||
//this.log( this.name + ' rgb : [' + value + ']' );
|
||||
if( this.PossibleSets.match(/[\^ ]RGB\b/) )
|
||||
cmd = "set " + this.device + " RGB " + value;
|
||||
else
|
||||
cmd = "set " + this.device + " rgb " + value;
|
||||
cmd = "set " + this.device + " " + this.mappings.rgb.cmd + " " + value;
|
||||
|
||||
} else if( c == 'hue' ) {
|
||||
value = Math.round(value * this.mappings.hue.max / 360);
|
||||
@@ -790,17 +815,17 @@ FHEMAccessory.prototype = {
|
||||
cmd = "set " + this.device + " sat " + value;
|
||||
|
||||
} else if( c == 'targetTemperature' ) {
|
||||
cmd = "set " + this.device + " " + this.isThermostat + " " + value;
|
||||
cmd = "set " + this.device + " " + this.mappings.thermostat.cmd + " " + value;
|
||||
|
||||
} else if( c == 'targetPosition' ) {
|
||||
if( this.isWindow ) {
|
||||
if( this.mappings.window ) {
|
||||
if( value == 0 )
|
||||
value = 'lock';
|
||||
|
||||
cmd = "set " + this.device + " level " + value;
|
||||
cmd = "set " + this.device + " " + this.mappings.window.cmd + " " + value;
|
||||
|
||||
} else if( this.isBlind )
|
||||
cmd = "set " + this.device + " " + this.isBlind + " " + value;
|
||||
} else if( this.mappings.blind )
|
||||
cmd = "set " + this.device + " " + this.mappings.blind.cmd + " " + value;
|
||||
|
||||
else
|
||||
this.log(this.name + " Unhandled command! cmd=" + c + ", value=" + value);
|
||||
@@ -851,19 +876,22 @@ FHEMAccessory.prototype = {
|
||||
this.log(" not cached" );
|
||||
|
||||
var query_reading = reading;
|
||||
if( reading == 'hue' && !this.mappings.hue && this.hasRGB ) {
|
||||
query_reading = this.hasRGB;
|
||||
if( reading == 'hue' && !this.mappings.hue && this.mappings.rgb ) {
|
||||
query_reading = this.mappings.rgb.reading;
|
||||
|
||||
} else if( reading == 'sat' && !this.mappings.sat && this.hasRGB ) {
|
||||
query_reading = this.hasRGB;
|
||||
} else if( reading == 'sat' && !this.mappings.sat && this.mappings.rgb ) {
|
||||
query_reading = this.mappings.rgb.reading;
|
||||
|
||||
} else if( reading == 'bri' && !this.mappings.pct && this.hasRGB ) {
|
||||
query_reading = this.hasRGB;
|
||||
} else if( reading == 'bri' && !this.mappings.pct && this.mappings.rgb ) {
|
||||
query_reading = this.mappings.rgb.reading;
|
||||
|
||||
} else if( reading == 'pct' && !this.mappings.pct && this.hasDim ) {
|
||||
query_reading = 'state';
|
||||
|
||||
} else if( reading == 'level' && this.isWindow ) {
|
||||
} else if( reading == 'level' && this.mappings.window ) {
|
||||
query_reading = 'state';
|
||||
|
||||
} else if( reading == 'lock' && this.mappings.lock ) {
|
||||
query_reading = 'state';
|
||||
|
||||
}
|
||||
@@ -900,17 +928,28 @@ FHEMAccessory.prototype = {
|
||||
else
|
||||
value = 50;
|
||||
|
||||
} else if(reading == 'hue' && query_reading == that.hasRGB) {
|
||||
} else if( reading == 'lock'
|
||||
&& query_reading == 'state') {
|
||||
|
||||
if( value.match( /^locked/ ) )
|
||||
value = 1;
|
||||
else
|
||||
value = 0;
|
||||
|
||||
if( value.match( /uncertain/ ) )
|
||||
value = 4;
|
||||
|
||||
} else if(reading == 'hue' && query_reading == that.mappings.rgb) {
|
||||
//FHEM_update( that.device+'-'+query_reading, value );
|
||||
|
||||
value = parseInt( FHEM_rgb2hsv(value)[0] * 360 );
|
||||
|
||||
} else if(reading == 'sat' && query_reading == that.hasRGB) {
|
||||
} else if(reading == 'sat' && query_reading == that.mappings.rgb) {
|
||||
//FHEM_update( that.device+'-'+query_reading, value );
|
||||
|
||||
value = parseInt( FHEM_rgb2hsv(value)[1] * 100 );
|
||||
|
||||
} else if(reading == 'bri' && query_reading == that.hasRGB) {
|
||||
} else if(reading == 'bri' && query_reading == that.mappings.rgb) {
|
||||
//FHEM_update( that.device+'-'+query_reading, value );
|
||||
|
||||
value = parseInt( FHEM_rgb2hsv(value)[2] * 100 );
|
||||
@@ -969,14 +1008,17 @@ FHEMAccessory.prototype = {
|
||||
onUpdate: null,
|
||||
perms: ["pr"],
|
||||
format: "string",
|
||||
initialValue: this.serial ? this.serial : "A1S2NASF88EW",
|
||||
initialValue: this.serial ? this.serial : "<unknown>",
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "SN",
|
||||
designedMaxLength: 255
|
||||
},{
|
||||
cType: types.IDENTIFY_CTYPE,
|
||||
onUpdate: null,
|
||||
onUpdate: function(value) {
|
||||
if( this.mappings.onOff )
|
||||
that.command( 'identify' );
|
||||
},
|
||||
perms: ["pw"],
|
||||
format: "bool",
|
||||
initialValue: false,
|
||||
@@ -984,8 +1026,7 @@ FHEMAccessory.prototype = {
|
||||
supportBonjour: false,
|
||||
manfDescription: "Identify Accessory",
|
||||
designedMaxLength: 1
|
||||
}
|
||||
]
|
||||
}];
|
||||
},
|
||||
|
||||
controlCharacteristics: function(that) {
|
||||
@@ -1009,7 +1050,7 @@ FHEMAccessory.prototype = {
|
||||
FHEM_subscribe(characteristic, that.mappings.onOff.informId, that);
|
||||
},
|
||||
onUpdate: function(value) {
|
||||
that.command( value == 0 ? 'off' : 'on' );
|
||||
that.command( 'set', value == 0 ? that.mappings.onOff.cmdOff : that.mappings.onOff.cmdOn );
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query( that.mappings.onOff.reading, function(state){ callback(state) } );
|
||||
@@ -1024,7 +1065,7 @@ FHEMAccessory.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
if( this.mappings.pct && !this.isBlind ) {
|
||||
if( this.mappings.pct ) {
|
||||
cTypes.push({
|
||||
cType: types.BRIGHTNESS_CTYPE,
|
||||
onRegister: function(characteristic) {
|
||||
@@ -1053,6 +1094,7 @@ FHEMAccessory.prototype = {
|
||||
cType: types.BRIGHTNESS_CTYPE,
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
// state is alreadi subscribed from POWER_STATE_CTYPE
|
||||
FHEM_subscribe(characteristic, that.name+'-pct', that);
|
||||
},
|
||||
onUpdate: function(value) { that.delayed('dim', value); },
|
||||
@@ -1099,13 +1141,13 @@ FHEMAccessory.prototype = {
|
||||
designedMinStep: 1,
|
||||
unit: "arcdegrees"
|
||||
});
|
||||
} else if( this.hasRGB ) {
|
||||
} else if( this.mappings.rgb ) {
|
||||
cTypes.push({
|
||||
cType: types.HUE_CTYPE,
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.name+'-hue', that);
|
||||
FHEM_subscribe(characteristic, that.name+'-'+that.hasRGB, that);
|
||||
FHEM_subscribe(characteristic, that.mappings.rgb.informId, that);
|
||||
},
|
||||
onUpdate: function(value) { that.command('H-rgb', value); },
|
||||
onRead: function(callback) {
|
||||
@@ -1208,8 +1250,10 @@ FHEMAccessory.prototype = {
|
||||
cType: types.OUTPUTVOLUME_CTYPE,
|
||||
onUpdate: function(value) { that.delayed('volume', value); },
|
||||
onRegister: function(characteristic) {
|
||||
//characteristic.eventEnabled = true;
|
||||
//FHEM_subscribe(characteristic, that.mappings.volume.informId, that);
|
||||
if( !that.mappings.volume.nocache ) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.mappings.volume.informId, that);
|
||||
}
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query(that.mappings.volume.reading, function(volume){
|
||||
@@ -1230,23 +1274,22 @@ FHEMAccessory.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
if( this.isBlind ) {
|
||||
if( this.mappings.blind ) {
|
||||
cTypes.push({
|
||||
cType: types.WINDOW_COVERING_TARGET_POSITION_CTYPE,
|
||||
onUpdate: function(value) { that.delayed('targetPosition', value, 1500); },
|
||||
//onRegister: function(characteristic) {
|
||||
// characteristic.eventEnabled = true;
|
||||
// FHEM_subscribe(characteristic, that.name+'-'+that.isBlind, that);
|
||||
// FHEM_subscribe(characteristic, that.mappings.blind.informId, that);
|
||||
//},
|
||||
onRead: function(callback) {
|
||||
that.query(that.isBlind, function(pct){
|
||||
that.query(that.mappings.blind.reading, function(pct){
|
||||
callback(pct);
|
||||
});
|
||||
},
|
||||
perms: ["pw","pr","ev"],
|
||||
format: "int",
|
||||
//initialValue: 100,
|
||||
initialValue: FHEM_cached[that.device +'-'+ that.isBlind],
|
||||
initialValue: FHEM_cached[that.mappings.blind.informId],
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Target Blind Position",
|
||||
@@ -1259,16 +1302,16 @@ FHEMAccessory.prototype = {
|
||||
cType: types.WINDOW_COVERING_CURRENT_POSITION_CTYPE,
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.name+'-'+that.isBlind, that);
|
||||
FHEM_subscribe(characteristic, that.mappings.blind.informId, that);
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query(that.isBlind, function(pos){
|
||||
that.query(that.mappings.blind.reading, function(pos){
|
||||
callback(pos);
|
||||
});
|
||||
},
|
||||
perms: ["pr","ev"],
|
||||
format: "int",
|
||||
initialValue: FHEM_cached[that.name+'-'+that.isBlind],
|
||||
initialValue: FHEM_cached[that.mappings.blind.informId],
|
||||
supportEvents: true,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Current Blind Position",
|
||||
@@ -1304,16 +1347,12 @@ FHEMAccessory.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
if( this.isWindow ) {
|
||||
if( this.mappings.window ) {
|
||||
cTypes.push({
|
||||
cType: types.WINDOW_COVERING_TARGET_POSITION_CTYPE,
|
||||
onUpdate: function(value) { that.delayed('targetPosition', value, 1500); },
|
||||
//onRegister: function(characteristic) {
|
||||
// characteristic.eventEnabled = true;
|
||||
// FHEM_subscribe(characteristic, that.name+'-'+that.isBlind, that);
|
||||
//},
|
||||
onRead: function(callback) {
|
||||
that.query(that.isWindow, function(level){
|
||||
that.query(that.mappings.window.reading, function(level){
|
||||
callback(level);
|
||||
});
|
||||
},
|
||||
@@ -1333,17 +1372,16 @@ FHEMAccessory.prototype = {
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.name+'-state', that);
|
||||
FHEM_subscribe(characteristic, that.name+'-'+that.isWindow, that);
|
||||
FHEM_subscribe(characteristic, that.mappings.window.informId, that);
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query(that.isWindow, function(pos){
|
||||
that.query(that.mappings.window.reading, function(pos){
|
||||
callback(pos);
|
||||
});
|
||||
},
|
||||
perms: ["pr","ev"],
|
||||
format: "int",
|
||||
initialValue: 50,
|
||||
//initialValue: FHEM_cached[that.name+'-'+that.isWindow],
|
||||
initialValue: FHEM_cached[that.mappings.window.informId],
|
||||
supportEvents: true,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Current Window Position",
|
||||
@@ -1379,23 +1417,75 @@ FHEMAccessory.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
if( this.mappings.garage ) {
|
||||
cTypes.push({
|
||||
onUpdate: function(value) {
|
||||
that.command( 'set', value == 0 ? that.mappings.garage.cmdOpen : that.mappings.garage.cmdClose );
|
||||
},
|
||||
cType: types.TARGET_DOORSTATE_CTYPE,
|
||||
onRead: function(callback) {
|
||||
callback(1);
|
||||
},
|
||||
perms: ["pw","pr","ev"],
|
||||
format: "int",
|
||||
initialValue: 1,
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Target GarageDoor Position",
|
||||
designedMinValue: 0,
|
||||
designedMaxValue: 1,
|
||||
designedMinStep: 1,
|
||||
designedMaxLength: 1
|
||||
});
|
||||
cTypes.push({
|
||||
cType: types.CURRENT_DOOR_STATE_CTYPE,
|
||||
onRead: function(callback) {
|
||||
callback(4);
|
||||
},
|
||||
perms: ["pr","ev"],
|
||||
format: "int",
|
||||
initialValue: 4,
|
||||
supportEvents: true,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Current GarageDoor State",
|
||||
designedMinValue: 0,
|
||||
designedMaxValue: 4,
|
||||
designedMinStep: 1,
|
||||
designedMaxLength: 1
|
||||
});
|
||||
|
||||
cTypes.push({
|
||||
cType: types.OBSTRUCTION_DETECTED_CTYPE,
|
||||
onRead: function(callback) {
|
||||
callback(false);
|
||||
},
|
||||
perms: ["pr","ev"],
|
||||
format: "bool",
|
||||
initialValue: 0,
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Obstruction Detected",
|
||||
designedMaxLength: 1
|
||||
});
|
||||
}
|
||||
|
||||
//FIXME: parse range and set designedMinValue & designedMaxValue & designedMinStep
|
||||
if( this.isThermostat ) {
|
||||
if( this.mappings.thermostat ) {
|
||||
cTypes.push({
|
||||
cType: types.TARGET_TEMPERATURE_CTYPE,
|
||||
onUpdate: function(value) { that.delayed('targetTemperature', value, 1500); },
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.name+'-'+that.isThermostat, that);
|
||||
FHEM_subscribe(characteristic, that.mappings.thermostat.informId, that);
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query(that.isThermostat, function(temperature){
|
||||
that.query(that.mappings.thermostat.reading, function(temperature){
|
||||
callback(temperature);
|
||||
});
|
||||
},
|
||||
perms: ["pw","pr","ev"],
|
||||
format: "float",
|
||||
initialValue: 20,
|
||||
initialValue: FHEM_cached[that.mappings.thermostat.informId],
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Target Temperature",
|
||||
@@ -1442,21 +1532,21 @@ FHEMAccessory.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
if( this.isContactSensor ) {
|
||||
if( this.mappings.contact ) {
|
||||
cTypes.push({
|
||||
cType: types.CONTACT_SENSOR_STATE_CTYPE,
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.name+'-'+that.isContactSensor, that);
|
||||
FHEM_subscribe(characteristic, that.mappings.contact.informId, that);
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query(that.isContactSensor, function(state){
|
||||
that.query(that.mappings.contact.reading, function(state){
|
||||
callback(state);
|
||||
});
|
||||
},
|
||||
perms: ["pr","ev"],
|
||||
format: "bool",
|
||||
initialValue: 0,
|
||||
initialValue: FHEM_cached[that.mappings.contact.informId],
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Contact State",
|
||||
@@ -1464,21 +1554,21 @@ FHEMAccessory.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
if( this.isOccupancySensor ) {
|
||||
if( this.mappings.occupancy ) {
|
||||
cTypes.push({
|
||||
cType: types.OCCUPANCY_DETECTED_CTYPE,
|
||||
onRegister: function(characteristic) {
|
||||
characteristic.eventEnabled = true;
|
||||
FHEM_subscribe(characteristic, that.name+'-state', that);
|
||||
FHEM_subscribe(characteristic, that.mappings.occupancy.informId, that);
|
||||
},
|
||||
onRead: function(callback) {
|
||||
that.query('state', function(state){
|
||||
that.query(that.mappings.occupancy.reading, function(state){
|
||||
callback(state);
|
||||
});
|
||||
},
|
||||
perms: ["pr","ev"],
|
||||
format: "bool",
|
||||
initialValue: 0,
|
||||
initialValue: FHEM_cached[that.mappings.occupancy.informId],
|
||||
supportEvents: false,
|
||||
supportBonjour: false,
|
||||
manfDescription: "Occupancy State",
|
||||
@@ -1541,17 +1631,19 @@ FHEMAccessory.prototype = {
|
||||
return types.SPEAKER_STYPE;
|
||||
} else if( this.isSwitch ) {
|
||||
return types.SWITCH_STYPE;
|
||||
} else if( this.isBlind ) {
|
||||
return types.WINDOW_COVERING_STYPE;
|
||||
} else if( this.isThermostat ) {
|
||||
return types.THERMOSTAT_STYPE;
|
||||
} else if( this.isWindow ) {
|
||||
} else if( this.mappings.garage ) {
|
||||
return types.GARAGE_DOOR_OPENER_STYPE;
|
||||
} else if( this.mappings.window ) {
|
||||
return types.WINDOW_STYPE;
|
||||
} else if( this.isContactSensor ) {
|
||||
} else if( this.mappings.blind ) {
|
||||
return types.WINDOW_COVERING_STYPE;
|
||||
} else if( this.mappings.thermostat ) {
|
||||
return types.THERMOSTAT_STYPE;
|
||||
} else if( this.mappings.contact ) {
|
||||
return types.CONTACT_SENSOR_STYPE;
|
||||
} else if( this.isOccupancySensor ) {
|
||||
} else if( this.mappings.occupancy ) {
|
||||
return types.OCCUPANCY_SENSOR_STYPE;
|
||||
} else if( this.isLight || this.mappings.pct || this.mappings.hue || this.hasRGB ) {
|
||||
} else if( this.isLight || this.mappings.pct || this.mappings.hue || this.mappings.rgb ) {
|
||||
return types.LIGHTBULB_STYPE;
|
||||
} else if( this.mappings.temperature ) {
|
||||
return types.TEMPERATURE_SENSOR_STYPE;
|
||||
@@ -1591,17 +1683,17 @@ function FHEMdebug_handleRequest(request, response){
|
||||
//console.log( request );
|
||||
|
||||
if( request.url == "/cached" ) {
|
||||
response.write( "<a href='/'>home</a><br>" );
|
||||
response.write( "<a href='/'>home</a><br><br>" );
|
||||
if( FHEM_lastEventTimestamp )
|
||||
response.write( "FHEM_lastEventTime: "+ new Date(FHEM_lastEventTimestamp) +"<br>" );
|
||||
response.write( "FHEM_lastEventTime: "+ new Date(FHEM_lastEventTimestamp) +"<br><br>" );
|
||||
response.end( "cached: " + util.inspect(FHEM_cached).replace(/\n/g, '<br>') );
|
||||
|
||||
} else if( request.url == "/subscriptions" ) {
|
||||
response.write( "<a href='/'>home</a><br>" );
|
||||
response.write( "<a href='/'>home</a><br><br>" );
|
||||
response.end( "subscriptions: " + util.inspect(FHEM_subscriptions, {depth: 4}).replace(/\n/g, '<br>') );
|
||||
|
||||
} else if( request.url == "/persist" ) {
|
||||
response.write( "<a href='/'>home</a><br>" );
|
||||
response.write( "<a href='/'>home</a><br><br>" );
|
||||
var unique = {};
|
||||
Object.keys(FHEM_subscriptions).forEach(function(key) {
|
||||
var characteristic = FHEM_subscriptions[key].characteristic;
|
||||
|
||||
Reference in New Issue
Block a user