Socket
Socket
Sign inDemoInstall

iobroker.comfoairq

Package Overview
Dependencies
74
Maintainers
2
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.2 to 0.0.3

291

io-package.json
{
"common": {
"name": "comfoairq",
"version": "0.0.2",
"version": "0.0.3",
"news": {
"0.0.3": {
"en": "Bugfixes",
"de": "Bugfixes"
},
"0.0.2": {

@@ -21,4 +25,4 @@ "en": "First connection",

"desc": {
"en": "Zehnder ComfoAirQ over ComfoConnect LAN C",
"de": "Zehnder ComfoAirQ über ComfoConnect LAN C"
"en": "Zehnder ComfoAirQ over ComfoConnect LAN C (e.g. Q350)",
"de": "Zehnder ComfoAirQ über ComfoConnect LAN C (z.B. Q350)"
},

@@ -54,3 +58,6 @@ "authors": [

},
"native": {},
"native": {
"pin": "0000",
"port": "56747"
},
"objects": [],

@@ -78,4 +85,280 @@ "instanceObjects": [

"native": {}
},
{
"_id": "version",
"type": "channel",
"common": {
"name": "Version information"
},
"native": {}
},
{
"_id": "version.comfonet",
"type": "state",
"common": {
"name": "ComfoNET version",
"role": "value",
"type": "string",
"read": true,
"write": false
},
"native": {}
},
{
"_id": "version.gateway",
"type": "state",
"common": {
"name": "Gateway version",
"role": "value",
"type": "string",
"read": true,
"write": false
},
"native": {}
},
{
"_id": "version.serial",
"type": "state",
"common": {
"name": "Serial number",
"role": "value",
"type": "string",
"read": true,
"write": false
},
"native": {}
},
{
"_id": "command",
"type": "channel",
"common": {
"name": "Commands"
},
"native": {}
},
{
"_id": "command.fanModeAway",
"type": "state",
"common": {
"name": "Fan Mode Away",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanModeLow",
"type": "state",
"common": {
"name": "Fan Mode Low",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanModeMedium",
"type": "state",
"common": {
"name": "Fan Mode Medium",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanModeHigh",
"type": "state",
"common": {
"name": "Fan Mode High",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanBoost10m",
"type": "state",
"common": {
"name": "Fan Boost 10 minutes",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanBoost20m",
"type": "state",
"common": {
"name": "Fan Boost 20 minutes",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanBoost30m",
"type": "state",
"common": {
"name": "Fan Boost 30 minutes",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.fanBoostEnd",
"type": "state",
"common": {
"name": "Fan Boost end",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.modeAuto",
"type": "state",
"common": {
"name": "Mode Auto",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.modeManual",
"type": "state",
"common": {
"name": "Mode Auto",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.ventmodeSupply",
"type": "state",
"common": {
"name": "Vent mode Supply",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.ventmodeBalance",
"type": "state",
"common": {
"name": "Vent mode Balance",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.tempprofNormal",
"type": "state",
"common": {
"name": "Temperature profile normal",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.tempprofCool",
"type": "state",
"common": {
"name": "Temperature profile cool",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.tempprofWarm",
"type": "state",
"common": {
"name": "Temperature profile warm",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.bypassOn",
"type": "state",
"common": {
"name": "Bypass on",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.bypassOff",
"type": "state",
"common": {
"name": "Bypass off",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "command.bypassAuto",
"type": "state",
"common": {
"name": "Bypass auto",
"role": "button",
"type": "boolean",
"read": false,
"write": true
},
"native": {}
},
{
"_id": "sensor",
"type": "channel",
"common": {
"name": "Sensor"
},
"native": {}
}
]
}

@@ -7,5 +7,4 @@ /* jshint -W097 */

const utils = require('@iobroker/adapter-core');
const comfoconnect = require('node-comfoairq/lib/comfoconnect');
const comfoconnect = require('comfoairq');
const adapterName = require('./package.json').name.split('.').pop();
const util = require('util');

@@ -23,4 +22,42 @@ class Comfoairq extends utils.Adapter {

this.connected = false;
this.uuid = '20200428000000000000000009080408';
this.deviceName = 'iobroker';
this.zehnder = null;
this.sensors = [];
this.sensorUnits = {
117: '%',
118: '%',
119: 'm³/h',
120: 'm³/h',
121: 'rpm',
122: 'rpm',
128: 'W',
129: 'kWh',
130: 'kWh',
144: 'kWh',
145: 'kWh',
146: 'W',
192: 'days',
209: '°C',
213: 'W',
214: 'kWh',
215: 'kWh',
216: 'W',
217: 'kWh',
218: 'kWh',
221: '°C',
227: '%',
274: '°C',
275: '°C',
276: '°C',
290: '%',
291: '%',
292: '%',
294: '%'
};
this.on('ready', this.onReady.bind(this));

@@ -32,43 +69,145 @@ this.on('stateChange', this.onStateChange.bind(this));

async onReady() {
const that = this;
this.setState('info.connection', false, true);
this.zehnder = new comfoconnect(
{
"pin": parseInt(this.config.pin),
"uuid" : "20200428000000000000000009080408",
"device" : "iobroker",
"multicast": "192.168.1.255",
"comfoair": this.config.host,
"comfoUuid": this.config.uuid,
"debug": true,
"logger": this.log.debug
// Get active sensors by configuration
for (const key of Object.keys(this.config)) {
if (key.indexOf('sensor_') === 0 && this.config[key]) {
this.sensors.push(Number(key.slice(7)));
}
);
}
this.log.debug('register receive handler...');
this.zehnder.on('receive', (data) => {
that.log.debug('received: ' + JSON.stringify(data));
/*
this.getForeignObjectAsync('system.adapter.' + this.namespace).then(data => {
this.log.debug('Current configuration: ' + JSON.stringify(data));
});
*/
this.log.debug('register disconnect handler...');
this.zehnder.on('disconnect', (reason) => {
if (reason.state == 'OTHER_SESSION') {
that.log.warn('Other session started');
if (this.config.host && this.config.port && this.config.uuid) {
if (this.sensors.length > 0) {
this.log.debug('Active sensors by configuration: ' + JSON.stringify(this.sensors));
this.zehnder = new comfoconnect(
{
'uuid' : this.uuid,
'device' : this.deviceName,
'comfoair': this.config.host,
'port': Number(this.config.port),
'comfouuid': this.config.uuid,
'pin': parseInt(this.config.pin),
'debug': false,
'logger': this.log.debug
}
);
this.log.debug('register receive handler...');
this.zehnder.on('receive', async (data) => {
this.log.debug('received: ' + JSON.stringify(data));
if (data && data.result.error == 'OK') {
if (data.kind == 40) { // 40 = CnRpdoNotification
const sensorId = data.result.data.pdid;
const sensorName = data.result.data.name;
const sensorNameClean = this.cleanNamespace(sensorName.replace('SENSOR', ''));
const sensorValue = data.result.data.data;
const unit = Object.prototype.hasOwnProperty.call(this.sensorUnits, sensorId) ? this.sensorUnits[sensorId] : '';
await this.setObjectNotExistsAsync('sensor.' + sensorNameClean, {
type: 'state',
common: {
name: sensorName + ' (' + sensorId + ')',
type: 'string',
role: 'value',
unit: unit,
read: true,
write: false
},
native: {}
});
this.setState('sensor.' + sensorNameClean, {val: sensorValue, ack: true});
} else if (data.kind == 68) { // 68 = VersionConfirm
this.setState('version.comfonet', {val: data.result.data.comfoNetVersion, ack: true});
this.setState('version.serial', {val: data.result.data.serialNumber, ack: true});
this.setState('version.gateway', {val: data.result.data.gatewayVersion, ack: true});
}
}
});
this.log.debug('register disconnect handler...');
this.zehnder.on('disconnect', (reason) => {
if (reason.state == 'OTHER_SESSION') {
this.log.warn('Other session started: ' + JSON.stringify(reason));
}
this.setState('info.connection', false, true);
});
this.log.debug('register the app...');
const registerAppResult = await this.zehnder.RegisterApp();
this.log.debug('registerAppResult: ' + JSON.stringify(registerAppResult));
// Start the session
this.log.debug('startSession');
const startSessionResult = await this.zehnder.StartSession(true);
this.log.debug('startSessionResult:' + JSON.stringify(startSessionResult));
for (let i = 0; i < this.sensors.length; i++) {
const registerResult = await this.zehnder.RegisterSensor(this.sensors[i]);
this.log.debug('Registered sensor "' + this.sensors[i] + '" with result: ' + JSON.stringify(registerResult));
}
this.zehnder.VersionRequest();
this.setState('info.connection', true, true);
this.connected = true;
this.subscribeStates('*');
} else {
this.log.warn('No active sensors found in configuration - stopping');
}
});
} else {
// Dicover Zehnder devices
this.log.warn('Device information not configured - starting discovery');
this.log.debug('register the app...');
let result = await this.zehnder.RegisterApp();
this.log.debug('registerAppResult: ' + JSON.stringify(result));
this.zehnder = new comfoconnect(
{
'uuid' : this.uuid,
'device' : this.deviceName,
'port': Number(this.config.port),
'debug': false,
'logger': this.log.debug
}
);
try {
const discoverResult = await this.zehnder.discover('172.16.255.255');
this.log.info('Device discovery finished: ' + JSON.stringify(discoverResult));
} catch (ex) {
this.log.error('error while discovery: ' + JSON.stringify(ex));
}
}
}
cleanNamespace(id) {
return id
.trim()
.replace(/\s/g, '_') // Replace whitespaces with underscores
.replace(/[^\p{Ll}\p{Lu}\p{Nd}]+/gu, '_') // Replace not allowed chars with underscore
.replace(/[_]+$/g, '') // Remove underscores end
.replace(/^[_]+/g, '') // Remove underscores beginning
.replace(/_+/g, '_') // Replace multiple underscores with one
.toLowerCase()
.replace(/_([a-z])/g, (m, w) => {
return w.toUpperCase();
});
}
onUnload(callback) {
try {
//await this.zehnder.CloseSession();
this.zehnder.CloseSession();
this.zehnder = null;
this.setState('info.connection', false, true);
callback();

@@ -86,8 +225,105 @@ } catch (e) {

onStateChange(id, state) {
if (state) {
// The state was changed
this.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
} else {
// The state was deleted
this.log.info(`state ${id} deleted`);
if (id && state && !state.ack) {
this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
if (this.connected) {
const matches = id.match(new RegExp(this.namespace + '.command.([a-zA-Z0-9]+)'));
if (matches) {
const command = matches[1];
switch (command) {
case 'fanModeAway':
this.log.debug('Sending command: FAN_MODE_AWAY');
this.zehnder.SendCommand(1, 'FAN_MODE_AWAY');
break;
case 'fanModeLow':
this.log.debug('Sending command: FAN_MODE_LOW');
this.zehnder.SendCommand(1, 'FAN_MODE_LOW');
break;
case 'fanModeMedium':
this.log.debug('Sending command: FAN_MODE_MEDIUM');
this.zehnder.SendCommand(1, 'FAN_MODE_MEDIUM');
break;
case 'fanModeHigh':
this.log.debug('Sending command: FAN_MODE_HIGH');
this.zehnder.SendCommand(1, 'FAN_MODE_HIGH');
break;
case 'fanBoost10m':
this.log.debug('Sending command: FAN_BOOST_10M');
this.zehnder.SendCommand(1, 'FAN_BOOST_10M');
break;
case 'fanBoost20m':
this.log.debug('Sending command: FAN_BOOST_20M');
this.zehnder.SendCommand(1, 'FAN_BOOST_20M');
break;
case 'fanBoost30m':
this.log.debug('Sending command: FAN_BOOST_30M');
this.zehnder.SendCommand(1, 'FAN_BOOST_30M');
break;
case 'fanBoostEnd':
this.log.debug('Sending command: FAN_BOOST_END');
this.zehnder.SendCommand(1, 'FAN_BOOST_END');
break;
case 'modeAuto':
this.log.debug('Sending command: MODE_AUTO');
this.zehnder.SendCommand(1, 'MODE_AUTO');
break;
case 'modeManual':
this.log.debug('Sending command: MODE_MANUAL');
this.zehnder.SendCommand(1, 'MODE_MANUAL');
break;
case 'ventmodeSupply':
this.log.debug('Sending command: VENTMODE_SUPPLY');
this.zehnder.SendCommand(1, 'VENTMODE_SUPPLY');
break;
case 'ventmodeBalance':
this.log.debug('Sending command: VENTMODE_BALANCE');
this.zehnder.SendCommand(1, 'VENTMODE_BALANCE');
break;
case 'tempprofNormal':
this.log.debug('Sending command: TEMPPROF_NORMAL');
this.zehnder.SendCommand(1, 'TEMPPROF_NORMAL');
break;
case 'tempprofCool':
this.log.debug('Sending command: TEMPPROF_COOL');
this.zehnder.SendCommand(1, 'TEMPPROF_COOL');
break;
case 'tempprofWarm':
this.log.debug('Sending command: TEMPPROF_WARM');
this.zehnder.SendCommand(1, 'TEMPPROF_WARM');
break;
case 'bypassOn':
this.log.debug('Sending command: BYPASS_ON');
this.zehnder.SendCommand(1, 'BYPASS_ON');
break;
case 'bypassOff':
this.log.debug('Sending command: BYPASS_OFF');
this.zehnder.SendCommand(1, 'BYPASS_OFF');
break;
case 'bypassAuto':
this.log.debug('Sending command: BYPASS_AUTO');
this.zehnder.SendCommand(1, 'BYPASS_AUTO');
break;
}
}
}
}

@@ -94,0 +330,0 @@ }

13

package.json
{
"name": "iobroker.comfoairq",
"version": "0.0.2",
"description": "Connect your Zehnder ComfoAirQ over ComfoConnect LAN C",
"version": "0.0.3",
"description": "ioBroker ComfoAirQ Adapter",
"author": {

@@ -12,2 +12,5 @@ "name": "Matthias Kleine",

"keywords": [
"ioBroker",
"Smart Home",
"home automation",
"KWL",

@@ -20,7 +23,7 @@ "Zehnder",

"type": "git",
"url": "git@github.com:klein0r/ioBroker.comfoairq.git"
"url": "https://github.com/klein0r/ioBroker.comfoairq"
},
"dependencies": {
"@iobroker/adapter-core": "^2.4.0",
"node-comfoairq": "^0.5.2"
"comfoairq": "^0.6.1"
},

@@ -42,3 +45,3 @@ "devDependencies": {

"gulp": "^4.0.2",
"mocha": "^8.0.1",
"mocha": "^8.2.1",
"proxyquire": "^2.1.3",

@@ -45,0 +48,0 @@ "sinon": "^9.0.2",

@@ -17,2 +17,6 @@ ![Logo](admin/comfoairq.png)

*Tested with ComfoAirQ 350*
**Important:** ComfoConnect LAN C supports just 1 single client. You cannot use the ComfoControl App and the ioBroker adapter at the same time!
## Credits

@@ -22,3 +26,3 @@

* herrJones (https://github.com/herrJones/node-comfoairq)
* Jan Van Belle (https://github.com/herrJones/node-comfoairq)
* Michael Arnauts (https://github.com/michaelarnauts/comfoconnect)

@@ -29,2 +33,10 @@ * Marco Hoyer (https://github.com/marco-hoyer/zcan) and its forks on github (djwlindenaar, decontamin4t0R)

### 0.0.3
* (klein0r) Subscribe to sensors
* (klein0r) Units for sensor values
* (klein0r) Get version information
* (klein0r) Control fan speed
* (klein0r) Control fan boost
### 0.0.2

@@ -31,0 +43,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc