Skip to content

Commit

Permalink
add HmIPW-FIO6 (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
hobbyquaker committed Jan 2, 2020
1 parent 8fc8b64 commit dd53a37
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
185 changes: 185 additions & 0 deletions homematic-devices/hmipw-fio6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/* eslint-disable no-new */

const Accessory = require('./lib/accessory');

function addInputService(type, name, dp) {
let service;
let actualValue;

switch (type) {
case 'Door':
case 'Window':
service = this.addService(type, name, type);

service.update('PositionState', 2);

service.get('CurrentPosition', dp, value => {
actualValue = value ? 100 : 0;
service.update('TargetPosition', actualValue);
return actualValue;
});

service.get('TargetPosition', dp, value => {
actualValue = value ? 100 : 0;
service.update('TargetPosition', actualValue);
return actualValue;
});

service.set('TargetPosition', (value, callback) => {
callback();
setTimeout(() => {
service.update('CurrentPosition', actualValue);
service.update('TargetPosition', actualValue);
service.update('PositionState', 2);
}, 20);
});

break;

default:
this.addService('ContactSensor', name)
.get('ContactSensorState', dp, (value, c) => {
return value ? c.CONTACT_NOT_DETECTED : c.CONTACT_DETECTED;
});
}
}

function addOutputService(type, dp, name) {
switch (type) {
case 'ValveIrrigation':
// intentional fallthrough
case 'Valve': {
const service = this.addService('Valve', name, type);

service.update('ValveType', type === 'ValveIrrigation' ? 1 : 0);

service
.get('Active', dp, val => val ? 1 : 0)
.get('InUse', dp, val => val ? 1 : 0)
.set('Active', dp, val => {
service.update('InUse', val);
return Boolean(val);
});
break;
}

case 'Lightbulb':
// intentional fallthrough
case 'Fan':
// intentional fallthrough
case 'Outlet':
// intentional fallthrough
default:
this.addService(type, name, type === 'Switch' ? '' : type)
.get('On', dp)
.set('On', dp);
}
}

class AccSingleOutputService extends Accessory {
init(config, node) {
const {ccu} = node;
const dp = config.iface + '.' + config.accChannel + '.STATE';
const name = ccu.channelNames[config.accChannel];
const type = this.option('', 'type') || 'Switch';

node.debug(config.accChannel + ' ' + type + ' ' + this.option('', 'type'));

addOutputService.call(this, type, dp, name);
}
}

class AccSingleInputService extends Accessory {
init(config) {
const dp = config.iface + '.' + config.accChannel + '.STATE';
const {name} = config;
const type = this.option('', 'type');
addService.call(this, type, name, dp);
}
}

class AccMultiService extends Accessory {
init(config, node) {
const {ccu} = node;
const channels = config.description.CHILDREN;

for (let i = 1; i < 7; i++) {
const ch = config.description.ADDRESS + ':' + i;
if (!this.option(i)) {
continue;
}

const dp = config.deviceAddress + ':' + i + '.STATE';
const name = node.ccu.channelNames[ch];
const type = this.option(i, 'type');

addInputService.call(this, type, name, dp);
}

for (let i = 8; i < (channels.length - 2); i += 4) {
for (let vi = 0; vi < 3; vi++) {
const channelNumber = i + vi;
const ch = channels[channelNumber];
if (vi === 0 && !this.option(channelNumber)) {
continue;
} else if (vi !== 0 && !this.option(channelNumber, 'enabled')) {
continue;
}

const name = ccu.channelNames[ch];
const dp = config.iface + '.' + ch + '.STATE';
const type = this.option(channelNumber, 'type') || 'Switch';

node.debug(channelNumber + ' ' + type + ' ' + this.option(channelNumber, 'type'));

addOutputService.call(this, type, dp, name);
}
}
}
}

module.exports = class HmipwFio {
constructor(config, node) {
const {ccu} = node;
this.node = node;
this.ccu = ccu;
this.config = config;
if (this.option('SingleAccessory')) {
new AccMultiService(config, node);
} else {
const channels = config.description.CHILDREN;
for (let i = 1; i < 7; i++) {
const ch = config.description.ADDRESS + ':' + i;
if (!this.option(ch)) {
continue;
}

const name = ccu.channelNames[ch];

const chConfig = Object.assign({}, config, {accChannel: ch, name});
chConfig.description = Object.assign({}, config.description, {ADDRESS: ch});

new AccSingleInputService(chConfig, node);
}

for (let i = 8; i < (channels.length - 2); i += 4) {
for (let vi = 0; vi < 3; vi++) {
const channelNumber = i + vi;
const ch = channels[channelNumber];
if (vi === 0 && !this.option(channelNumber)) {
continue;
} else if (vi !== 0 && !this.option(channelNumber, 'enabled')) {
continue;
}

const name = ccu.channelNames[ch];

const chConfig = Object.assign({}, config, {accChannel: ch, name});
chConfig.description = Object.assign({}, config.description, {ADDRESS: ch});

new AccSingleOutputService(chConfig, node);
}
}
}
}
};
6 changes: 6 additions & 0 deletions nodes/redmatic-homekit-homematic-devices.html
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,12 @@
addVirtualChannels(addr, 2, channelCount - 2, 4, {type: switchTypes});
break;

case 'hmipw-fio6':
addOption(addr, 'SingleAccessory');
addChannels(addr, 1, 6, {type: ['ContactSensor', 'Door', 'Window']});
addVirtualChannels(addr, 8, channelCount - 3, 4, {type: switchTypes});
break;

case 'hmipw-dri16':
case 'hmipw-dri32':
addOption(addr, 'SingleAccessory');
Expand Down

0 comments on commit dd53a37

Please sign in to comment.