Skip to content

Commit

Permalink
Refactor homeassistant configuration out of devices.js. Koenkk#45
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenkk committed May 16, 2018
1 parent b5157e8 commit 4b49b7e
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 39 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ install:
- npm install

script:
- npm run verify-homeassistant-mapping

after_script:
- ".travis/docker.sh"
- ".travis/wiki.sh"

Expand Down
4 changes: 2 additions & 2 deletions lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Controller {
// MQTT discovery of all paired devices on startup.
this.zigbee.getAllClients().forEach((device) => {
if (deviceMapping[device.modelId]) {
homeassistant.discover(device.ieeeAddr, deviceMapping[device.modelId].homeassistant, this.mqtt);
homeassistant.discover(device.ieeeAddr, deviceMapping[device.modelId].model, this.mqtt);
}
});
}
Expand Down Expand Up @@ -127,7 +127,7 @@ class Controller {

// Home Assistant MQTT discovery
if (settings.get().homeassistant) {
homeassistant.discover(device.ieeeAddr, mappedModel.homeassistant, this.mqtt);
homeassistant.discover(device.ieeeAddr, mappedModel.model, this.mqtt);
}

// After this point we cant handle message withoud cid anymore.
Expand Down
24 changes: 0 additions & 24 deletions lib/devices.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
const homeassistant = require('./homeassistant').configurations;

const LED1623G12 = {
model: 'LED1623G12',
vendor: 'IKEA',
description: 'TRADFRI LED bulb E27 1000 lumen, dimmable, opal white',
supports: 'on/off, brightness',
homeassistant: [homeassistant.light_brightness]
};

const devices = {
Expand All @@ -15,114 +12,98 @@ const devices = {
vendor: 'Xiaomi',
description: 'MiJia wireless switch',
supports: 'single, double, triple, quadruple, many and long click',
homeassistant: [homeassistant.sensor_click]
},
'lumi.sensor_switch.aq2': {
model: 'WXKG11LM',
vendor: 'Xiaomi',
description: 'Aqara wireless switch',
supports: 'single, double, triple, quadruple click',
homeassistant: [homeassistant.sensor_click]
},
'lumi.sensor_86sw1\u0000lu': {
model: 'WXKG03LM',
vendor: 'Xiaomi',
description: 'Aqara single key wireless wall switch',
supports: 'single click',
homeassistant: [homeassistant.sensor_click]
},
'lumi.sensor_86sw2\u0000Un': {
model: 'WXKG02LM',
vendor: 'Xiaomi',
description: 'Aqara double key wireless wall switch',
supports: 'left, right and both click',
homeassistant: [homeassistant.sensor_click]
},
'lumi.ctrl_neutral1': {
model: 'QBKG04LM',
vendor: 'Xiaomi',
description: 'Aqara single key wired wall switch',
supports: 'on/off',
ep: {'': 2},
homeassistant: [homeassistant.switch]
},
'lumi.ctrl_neutral2': {
model: 'QBKG03LM',
vendor: 'Xiaomi',
description: 'Aqara double key wired wall switch',
supports: 'l1 and l2 on/off',
ep: {'l1': 2, 'l2': 3},
homeassistant: [homeassistant.switch_l1, homeassistant.switch_l2]
},
'lumi.sens': {
model: 'WSDCGQ01LM',
vendor: 'Xiaomi',
description: 'MiJia temperature & humidity sensor ',
supports: 'temperature and humidity',
homeassistant: [homeassistant.sensor_temperature, homeassistant.sensor_humidity]
},
'lumi.weather': {
model: 'WSDCGQ11LM',
vendor: 'Xiaomi',
description: 'Aqara temperature, humidity and pressure sensor',
supports: 'temperature, humidity and pressure',
homeassistant: [homeassistant.sensor_temperature, homeassistant.sensor_humidity, homeassistant.sensor_pressure]
},
'lumi.sensor_motion': {
model: 'RTCGQ01LM',
vendor: 'Xiaomi',
description: 'MiJia human body movement sensor',
supports: 'occupancy',
homeassistant: [homeassistant.binary_sensor_occupancy]
},
'lumi.sensor_motion.aq2': {
model: 'RTCGQ11LM',
vendor: 'Xiaomi',
description: 'Aqara human body movement and illuminance sensor',
supports: 'occupancy and illuminance',
homeassistant: [homeassistant.binary_sensor_occupancy, homeassistant.sensor_illuminance]
},
'lumi.sensor_magnet': {
model: 'MCCGQ01LM',
vendor: 'Xiaomi',
description: 'MiJia door & window contact sensor',
supports: 'contact',
homeassistant: [homeassistant.binary_sensor_contact]
},
'lumi.sensor_magnet.aq2': {
model: 'MCCGQ11LM',
vendor: 'Xiaomi',
description: 'Aqara door & window contact sensor',
supports: 'contact',
homeassistant: [homeassistant.binary_sensor_contact]
},
'lumi.sensor_wleak.aq1': {
model: 'SJCGQ11LM',
vendor: 'Xiaomi',
description: 'Aqara water leak sensor',
supports: 'water leak true/false',
homeassistant: [homeassistant.binary_sensor_water_leak]
},
'lumi.sensor_cube': {
model: 'MFKZQ01LM',
vendor: 'Xiaomi',
description: 'Mi smart home cube',
supports: 'shake, wakeup, fall, tap, slide, flip180, flip90, rotate_left and rotate_right',
homeassistant: [homeassistant.sensor_action]
},
'lumi.plug': {
model: 'ZNCZ02LM',
description: 'Mi power plug ZigBee',
supports: 'on/off, power measurement',
vendor: 'Xiaomi',
homeassistant: [homeassistant.switch, homeassistant.sensor_power]
},
'lumi.ctrl_86plug': {
model: 'QBCZ11LM',
description: 'Aqara socket Zigbee',
supports: 'on/off, power measurement',
vendor: 'Xiaomi',
homeassistant: [homeassistant.switch, homeassistant.sensor_power]
},

// IKEA
Expand All @@ -131,7 +112,6 @@ const devices = {
vendor: 'IKEA',
description: 'TRADFRI LED bulb E27 980 lumen, dimmable, white spectrum, opal white',
supports: 'on/off, brightness, color temperature',
homeassistant: [homeassistant.light_brightness_colortemp]
},
// LED1623G12 uses 2 model IDs, see https://github.com/Koenkk/zigbee2mqtt/issues/21
'TRADFRI bulb E27 opal 1000lm': LED1623G12,
Expand All @@ -141,21 +121,18 @@ const devices = {
vendor: 'IKEA',
description: 'TRADFRI LED bulb GU10 400 lumen, dimmable, white spectrum',
supports: 'on/off, brightness, color temperature',
homeassistant: [homeassistant.light_brightness_colortemp]
},
'TRADFRI bulb GU10 W 400lm': {
model: 'LED1650R5',
vendor: 'IKEA',
description: 'TRADFRI LED bulb GU10 400 lumen, dimmable',
supports: 'on/off, brightness',
homeassistant: [homeassistant.light_brightness]
},
'TRADFRI bulb E14 WS opal 400lm': {
model: 'LED1536G5',
vendor: 'IKEA',
description: 'TRADFRI LED bulb E14 400 lumen, dimmable, white spectrum, opal white',
supports: 'on/off, brightness, color temperature',
homeassistant: [homeassistant.light_brightness_colortemp]
},

// Philips
Expand All @@ -164,7 +141,6 @@ const devices = {
vendor: 'Philips',
description: 'Hue Go',
supports: 'on/off, brightness, color temperature, color xy',
homeassistant: [homeassistant.light_brightness_colortemp_xy]
},
}

Expand Down
42 changes: 32 additions & 10 deletions lib/homeassistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,29 +172,51 @@ const configurations = {
},
};

// Map homeassitant configurations to devices.
const mapping = {
'WXKG01LM': [configurations.sensor_click],
'WXKG11LM': [configurations.sensor_click],
'WXKG03LM': [configurations.sensor_click],
'WXKG02LM': [configurations.sensor_click],
'QBKG04LM': [configurations.switch],
'QBKG03LM': [configurations.switch_l1, configurations.switch_l2],
'WSDCGQ01LM': [configurations.sensor_temperature, configurations.sensor_humidity],
'WSDCGQ11LM': [configurations.sensor_temperature, configurations.sensor_humidity, configurations.sensor_pressure],
'RTCGQ01LM': [configurations.binary_sensor_occupancy],
'RTCGQ11LM': [configurations.binary_sensor_occupancy, configurations.sensor_illuminance],
'MCCGQ01LM': [configurations.binary_sensor_contact],
'MCCGQ11LM': [configurations.binary_sensor_contact],
'SJCGQ11LM': [configurations.binary_sensor_water_leak],
'MFKZQ01LM': [configurations.sensor_action],
'ZNCZ02LM': [configurations.switch, configurations.sensor_power],
'QBCZ11LM': [configurations.switch, configurations.sensor_power],
'LED1545G12': [configurations.light_brightness_colortemp],
'LED1623G12': [configurations.light_brightness],
'LED1537R6': [configurations.light_brightness_colortemp],
'LED1650R5': [configurations.light_brightness],
'LED1536G5': [configurations.light_brightness_colortemp],
'7146060PH': [configurations.light_brightness_colortemp_xy],
};

// A map of all discoverd devices
const discovered = {};

function discover(deviceID, configs, mqtt) {
function discover(deviceID, model, mqtt) {
// Check if already discoverd and check if there are configs.
if (discovered[deviceID] || !configs) {
if (discovered[deviceID] || !mapping[model]) {
return;
}

const friendlyName = settings.getDevice(deviceID).friendly_name;

configs.forEach((config) => {
mapping[model].forEach((config) => {
const topic = `${config.type}/${deviceID}/${config.object_id}/config`;
const payload = config.discovery_payload;
payload.state_topic = `${settings.get().mqtt.base_topic}/${friendlyName}`;
payload.availability_topic = `${settings.get().mqtt.base_topic}/bridge/state`;

// Set unique names in cases this device produces multiple entities in homeassistant.
if (configs.length > 1) {
payload.name = `${friendlyName}_${config.object_id}`;
} else {
payload.name = friendlyName;
}
payload.name = mapping[model].length > 1 ? `${friendlyName}_${config.object_id}` : friendlyName;

if (payload.command_topic) {
payload.command_topic = `${settings.get().mqtt.base_topic}/${friendlyName}/`;
Expand All @@ -213,6 +235,6 @@ function discover(deviceID, configs, mqtt) {
}

module.exports = {
configurations: configurations,
discover: (deviceID, configs, mqtt) => discover(deviceID, configs, mqtt),
mapping: mapping,
discover: (deviceID, model, mqtt) => discover(deviceID, model, mqtt),
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
],
"scripts": {
"start": "node index.js",
"docgen": "node support/docgen.js"
"docgen": "node support/docgen.js",
"verify-homeassistant-mapping": "node support/verify-homeassistant-mapping.js"
},
"author": "Koen Kanters",
"license": "GPL-3.0",
Expand Down
6 changes: 4 additions & 2 deletions support/docgen.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const zigbee2mqtt = require('../lib/converters/zigbee2mqtt');
const deviceMapping = require('../lib/devices');
const fs = require('fs');
const YAML = require('json2yaml');
const homeassistant = require('../lib/homeassistant');

// Sanity check if all supported devices are in deviceMapping
const supportedDevices = new Set();
Expand Down Expand Up @@ -106,9 +107,10 @@ Object.values(deviceMapping).forEach((device) => {
text += `### ${device.model}\n`;
text += '```yaml\n'

device.homeassistant.forEach((d, i) => {
const configurations = homeassistant.mapping[device.model]
configurations.forEach((d, i) => {
text += homeassistantConfig(d);
if (device.homeassistant.length > 1 && i < device.homeassistant.length - 1) {
if (configurations.length > 1 && i < configurations.length - 1) {
text += '\n';
}
})
Expand Down
13 changes: 13 additions & 0 deletions support/verify-homeassistant-mapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Verify that there are homeassistant mappings for every device.
const devices = require('../lib/devices');
const homeassistant = require('../lib/homeassistant');

let failed = false;
Object.values(devices).forEach((d) => {
if (!homeassistant.mapping[d.model]) {
console.error(`Missing homeassistant mapping for '${d.model}'`);
failed = true;
}
});

process.exit(failed ? 1 : 0);

0 comments on commit 4b49b7e

Please sign in to comment.