mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-07-02 01:51:38 +00:00
Refactor homeassistant configuration out of devices.js. #45
This commit is contained in:
@@ -12,6 +12,9 @@ install:
|
||||
- npm install
|
||||
|
||||
script:
|
||||
- npm run verify-homeassistant-mapping
|
||||
|
||||
after_script:
|
||||
- ".travis/docker.sh"
|
||||
- ".travis/wiki.sh"
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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 = {
|
||||
@@ -15,28 +12,24 @@ 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',
|
||||
@@ -44,7 +37,6 @@ const devices = {
|
||||
description: 'Aqara single key wired wall switch',
|
||||
supports: 'on/off',
|
||||
ep: {'': 2},
|
||||
homeassistant: [homeassistant.switch]
|
||||
},
|
||||
'lumi.ctrl_neutral2': {
|
||||
model: 'QBKG03LM',
|
||||
@@ -52,77 +44,66 @@ const devices = {
|
||||
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
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+32
-10
@@ -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}/`;
|
||||
@@ -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),
|
||||
};
|
||||
|
||||
+2
-1
@@ -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",
|
||||
|
||||
+4
-2
@@ -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();
|
||||
@@ -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';
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user