Skip to content

Commit

Permalink
Merge pull request #23 from Devirex/master
Browse files Browse the repository at this point in the history
  • Loading branch information
justme-1968 authored Aug 14, 2024
2 parents ba95f82 + 74efb10 commit 96a6b4f
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 66 deletions.
49 changes: 47 additions & 2 deletions lib/fhem.js
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,12 @@ FHEMDevice.prototype.unsubscribe = function(mapping, characteristic) {
if( mapping === undefined ) {
for( let characteristic_type in this.mappings ) {
var mapping = this.mappings[characteristic_type];
FHEM_unsubscribe(this, mapping.informId, characteristic);
if( characteristic_type === "ModeController"){
for( var key in mapping.instance)
FHEM_unsubscribe(this, mapping.instance[key].informId, characteristic);
}else{
FHEM_unsubscribe(this, mapping.informId, characteristic);
}
}

} else if( typeof mapping === 'object' ) {
Expand Down Expand Up @@ -1063,6 +1068,20 @@ FHEMDevice.prototype.fromHomebridgeMapping = function(homebridgeMapping) {
return;
}

if( 'ModeController' in homebridgeMapping){
var mcs = {};
if(!Array.isArray(homebridgeMapping.ModeController)){
homebridgeMapping.ModeController = [homebridgeMapping.ModeController];
}
homebridgeMapping.ModeController.forEach(function (ModeController){
var name = ModeController.asset.split(":")[0];
var obj = { [name] : ModeController};
Object.assign(mcs, obj);
})
var obj = { "instance" : mcs };
homebridgeMapping.ModeController = obj;
}

//FIXME: handle multiple identical characteristics in this.mappings and in homebridgeMapping ?
if( 1 )
this.mappings = homebridgeMapping;
Expand Down Expand Up @@ -1189,6 +1208,20 @@ FHEMDevice.prototype.fromHomebridgeMapping = function(homebridgeMapping) {
}
}
}

if( 'ModeController' in this.mappings){
var mcs = {};
if(!Array.isArray(this.mappings.ModeController)){
this.mappings.ModeController = [this.mappings.ModeController];
}
this.mappings.ModeController.forEach(function (ModeController){
var name = ModeController.asset.split(":")[0];
var obj = { [name] : ModeController};
Object.assign(mcs, obj);
})
var obj = { "instance" : mcs };
this.mappings.ModeController = obj;
}
}

FHEMDevice.prototype.prepare = function(mapping) {
Expand Down Expand Up @@ -1353,9 +1386,13 @@ FHEM.prototype.updateAlexaDevice = function() {
this.xxx.fromHomebridgeMapping( this.alexa_device.Attributes.alexaMapping );
for( let characteristic_type in this.xxx.mappings ) {
var mappings = this.xxx.mappings[characteristic_type];

if( characteristic_type === "ModeController")
mappings = Object.values(mappings.instance)

if( !Array.isArray(mappings) )
mappings = [mappings];

for( let mapping of mappings ) {
var device = this.device;
if( mapping.device === undefined )
Expand Down Expand Up @@ -2649,6 +2686,10 @@ FHEMDevice(platform, s) {
this.log.info( s.Internals.NAME + ' has' );
for( let characteristic_type in this.mappings ) {
var mappings = this.mappings[characteristic_type];

if( characteristic_type === "ModeController")
mappings = Object.values(mappings.instance)

if( !Array.isArray(mappings) )
mappings = [mappings];

Expand Down Expand Up @@ -2740,6 +2781,10 @@ FHEMDevice(platform, s) {
// prepare mapping internals
for( let characteristic_type in this.mappings ) {
var mappings = this.mappings[characteristic_type];

if( characteristic_type === "ModeController")
mappings = Object.values(mappings.instance)

if( !Array.isArray(mappings) )
mappings = [mappings];

Expand Down
170 changes: 106 additions & 64 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,15 @@ Server.prototype.addDevice = function(device, fhem) {

this.devices[device.device.toLowerCase()] = device;

for( let characteristic_type in device.mappings )
device.subscribe( device.mappings[characteristic_type] );
for( let characteristic_type in device.mappings ){
if (characteristic_type === 'ModeController'){
(Object.values(device.mappings[characteristic_type].instance)).forEach(function (mode){
device.subscribe( mode );
})
}else{
device.subscribe( device.mappings[characteristic_type] );
}
}

if( device.alexaRoom ) {
device.alexaRoom = device.alexaRoom.toLowerCase().replace( /\+/g, ' ' );
Expand Down Expand Up @@ -2376,7 +2383,8 @@ var handler = function(event, callback) {
break;

case NAMESPACE_ModeController:
response = handleModeController.bind(this)(event);
//response = handleModeController.bind(this)(event);
response = handleMode.bind(this)(event);
break;

default:
Expand Down Expand Up @@ -3390,69 +3398,82 @@ function deviceToEndpoints(device) {
);
}

if( device.isOfType('mode') && mappings.ModeController ) {
var mapping = mappings.ModeController;
d.capabilities.push( {
"type": "AlexaInterface",
"interface": NAMESPACE_ModeController,
"instance": instanceForMode(device, mapping),
"version": "3",
"properties": {
"supported": [
{ "name": "mode" },
],
"proactivelyReported": device.proactiveEvents,
"retrievable": true,
"nonControllable": false
},
"capabilityResources": {
"friendlyNames": [
{
"@type": "text",
"value": {
"text": mapping.mode || "mode",
"locale": mapping.locale || "de-DE"
}
}
]
},
"configuration": {
"ordered": (mapping.ordered?true:false) || false,
"supportedModes": [
]
},
"semantics": {
}
}
);


if( typeof mapping.value2homekit === 'object' ) {
let modes = [];
for( let from of Object.keys(mapping.value2homekit) ) {
let to = mapping.value2homekit[from];
modes.push( {
"value": valueForMode(device, mapping, from),
"modeResources": {
"friendlyNames": [
{
"@type": "text",
"value": {
"text": to,
"locale": mapping.locale || "de-DE"
}
}
]
if( mappings.ModeController ) {
for (var keys of Object.keys(mappings.ModeController.instance)) {
log.debug(keys + " -> " + mappings.ModeController.instance[keys])
var instance = mappings.ModeController.instance[keys];
var assets = [];
var asset = instance.asset.split(':')
var a_name = asset[0];
assets.push({
"@type": "asset",
"value": {
"assetId": "Alexa.Setting." + a_name,
}
})
asset.forEach(function(fname,i){
if(i > 0){
log.debug("Index:" + i);
var a_utterance = fname;
assets.push({
"@type": "text",
"value": {
"text": a_utterance,
"locale" : instance.locale,
}
})
}
})

var modes = [];
instance.values.forEach(function(mode){
var mode = mode.split(':');
var m_name = mode[0];
var fnames = [];
mode.forEach(function(fname, i){
if(i > 0){
var m_utterance = fname;
fnames.push({
"@type": "text",
"value": {
"text": m_utterance,
"locale": instance.locale,
}
})
}
});
modes.push ({
"value": a_name + "." + m_name,
"modeResources": {
"friendlyNames": fnames
}
} );
}
let configuration = d.capabilities[d.capabilities.length-1].configuration;
configuration.supportedModes = modes;
//log.error(d.capabilities);
}
});

if( !d.displayCategories.length )
d.displayCategories.push ( 'OTHER' );
});
d.capabilities.push({
"type": "AlexaInterface",
"interface": NAMESPACE_ModeController,
"instance": device.device + "." + a_name,
"version": "3",
"properties": {
"supported": [
{
"name" : "mode"
}
],
"retrievable": true,
"proactivelyReported": device.proactiveEvents,
"nonControllable": false
},
"capabilityResources": {
"friendlyNames": assets
},
"configuration" : {
"ordered": false,
"supportedModes": modes
}
});
}
}

if( mappings.Hue || mappings.RGB ) {
Expand Down Expand Up @@ -4147,6 +4168,27 @@ var handleModeController = function(event) {

}// handleModeController

var handleMode = function(event) {
var device = this.devices[event.directive.endpoint.cookie.device.toLowerCase()];
if( !device )
return createError(ERROR3_NO_SUCH_ENDPOINT, undefined, event);
var instance = event.directive.header.instance.split('.')[1];
var mode = event.directive.payload.mode.split('.')[1];
var mapping = Object.assign({}, device.mappings.ModeController, device.mappings.ModeController.instance[instance]);
delete mapping.instance;
device.command( mapping, mode );

var header = createHeader("Alexa", "Response", event);
var context = {
"properties": []
};
var endpoint = { "scope": event.directive.endpoint.scope, "endpointId": event.directive.endpoint.endpointId};

return { "context": context, "event": { "header": header, "endpoint": endpoint , "payload": {} } };
}// handleModeController



var handleThermostatController = function(event) {
var device = this.devices[event.directive.endpoint.cookie.device.toLowerCase()];
if( !device )
Expand Down

0 comments on commit 96a6b4f

Please sign in to comment.