mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-29 07:08:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e26ad2aca2 | ||
|
|
eb69ea6808 | ||
|
|
d0242fbd54 | ||
|
|
bd8801698f | ||
|
|
b77be8e673 | ||
|
|
1189d16839 | ||
|
|
b00d4d55fa | ||
|
|
4f7e3a179f | ||
|
|
1bdbeae144 | ||
|
|
48fc7d8d3b | ||
|
|
8ee3158783 | ||
|
|
7d04185f2c | ||
|
|
377e9d50dc | ||
|
|
9628cf2c95 | ||
|
|
4d4a63f913 | ||
|
|
22bed9a347 | ||
|
|
d96c3da8d5 | ||
|
|
6abe7d2fd7 | ||
|
|
a62d6aad91 | ||
|
|
c55691daec | ||
|
|
c9f56f0bbf | ||
|
|
c53c4c894f | ||
|
|
6ae307d893 | ||
|
|
511f9406e2 | ||
|
|
9e63a4646e | ||
|
|
da5ca2f0bf | ||
|
|
ecbee780db | ||
|
|
a604fd6345 | ||
|
|
36e52ba4fb | ||
|
|
f67eeffed6 | ||
|
|
5e55e1655f | ||
|
|
519eb4eecf | ||
|
|
fd3019dce8 | ||
|
|
1ca1be2ea2 | ||
|
|
967bf1083c | ||
|
|
c1e8dd990f | ||
|
|
fcb6c37ef0 | ||
|
|
c9ec198c1f | ||
|
|
a60fdd75dc | ||
|
|
7853f41a0e | ||
|
|
3ed5705253 | ||
|
|
5254eea6e0 | ||
|
|
92e930ede3 | ||
|
|
ac3b924065 | ||
|
|
dd8a55cf08 | ||
|
|
3ae2d2b946 |
+1
-1
@@ -133,7 +133,7 @@ class Controller {
|
||||
logger.debug(
|
||||
`Received zigbee message of type '${message.type}' with data '${JSON.stringify(message.data)}'` +
|
||||
(device ? ` of device '${device.modelId}' (${device.ieeeAddr})` : '') +
|
||||
(message.groupid ? ` with groupID ${message.groupID}` : '') +
|
||||
(message.groupid ? ` with groupID ${message.groupid}` : '') +
|
||||
(message.endpoints && message.endpoints.length ? ` of endpoint ${message.endpoints[0].epId}` : '')
|
||||
);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const pingableDevices = [
|
||||
zigbeeShepherdConverters.devices.find((d) => d.model === 'E11-G13'),
|
||||
];
|
||||
|
||||
const toZigbeeCandidates = ['state'];
|
||||
const toZigbeeCandidates = ['state', 'color', 'color_temp'];
|
||||
|
||||
/**
|
||||
* This extensions pings devices to check if they are online.
|
||||
|
||||
@@ -3,6 +3,7 @@ const settings = require('../util/settings');
|
||||
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
|
||||
const logger = require('../util/logger');
|
||||
const utils = require('../util/utils');
|
||||
const objectAssignDeep = require(`object-assign-deep`);
|
||||
|
||||
const postfixes = utils.getPostfixes();
|
||||
const topicRegex = new RegExp(`^(.+?)(?:/(${postfixes.join('|')}))?/(get|set)(?:/(.+))?`);
|
||||
@@ -120,9 +121,12 @@ class DevicePublish {
|
||||
}
|
||||
|
||||
converters = model.toZigbee;
|
||||
options = model.options || {};
|
||||
|
||||
const deviceSettings = settings.getDevice(entity.ID);
|
||||
options = objectAssignDeep.noMutate({}, model.options, deviceSettings);
|
||||
} else if (entity.type === 'group') {
|
||||
converters = groupConverters;
|
||||
options = objectAssignDeep.noMutate({}, settings.getGroup(entity.ID));
|
||||
}
|
||||
|
||||
// Convert the MQTT message to a Zigbee message.
|
||||
|
||||
@@ -16,6 +16,11 @@ const candidates = {
|
||||
'lightingColorCtrl': {
|
||||
attrs: ['colorTemperature', 'currentX', 'currentY'],
|
||||
},
|
||||
'closuresWindowCovering': {
|
||||
attrs: ['currentPositionLiftPercentage', 'currentPositionTiltPercentage'],
|
||||
reportIntervalMin: 2,
|
||||
reportIntervalMax: 300,
|
||||
},
|
||||
};
|
||||
|
||||
const reportInterval = {
|
||||
|
||||
+11
-4
@@ -137,7 +137,6 @@ class Groups {
|
||||
|
||||
updateDeviceGroup(ID, cmd, groupID) {
|
||||
let payload = null;
|
||||
const orignalCmd = cmd;
|
||||
if (cmd === 'add') {
|
||||
payload = {groupid: groupID, groupname: ''};
|
||||
cmd = 'add';
|
||||
@@ -159,10 +158,18 @@ class Groups {
|
||||
logger.info(`Successfully ${cmd} ${ieeeAddr} to ${groupID}`);
|
||||
|
||||
// Log to MQTT
|
||||
const lookup = {
|
||||
'add': 'device_group_add',
|
||||
'remove': 'device_group_remove',
|
||||
'removeAll': 'device_group_remove_all',
|
||||
};
|
||||
|
||||
this.mqtt.log({
|
||||
device: settings.getDevice(ieeeAddr).friendly_name,
|
||||
group: groupID,
|
||||
action: orignalCmd,
|
||||
type: lookup[cmd],
|
||||
message: {
|
||||
device: settings.getDevice(ieeeAddr).friendly_name,
|
||||
group: groupID,
|
||||
},
|
||||
});
|
||||
|
||||
// Update group cache
|
||||
|
||||
@@ -322,6 +322,21 @@ const configurations = {
|
||||
state_topic: false,
|
||||
},
|
||||
},
|
||||
'cover_position_tilt': {
|
||||
type: 'cover',
|
||||
object_id: 'cover',
|
||||
discovery_payload: {
|
||||
state_topic: false,
|
||||
command_topic: true,
|
||||
set_position_topic: true,
|
||||
set_position_template: '{ "position": {{ position }} }',
|
||||
tilt_command_topic: true,
|
||||
position_topic: true,
|
||||
value_template: '{{ value_json.position }}',
|
||||
tilt_status_topic: true,
|
||||
tilt_status_template: '{{ value_json.tilt }}',
|
||||
},
|
||||
},
|
||||
|
||||
// Lock
|
||||
'lock': {
|
||||
@@ -388,12 +403,15 @@ const switchWithPostfix = (postfix) => {
|
||||
const mapping = {
|
||||
'WXKG01LM': [configurations.sensor_click, configurations.sensor_battery],
|
||||
'WXKG11LM': [configurations.sensor_click, configurations.sensor_battery],
|
||||
'WXKG12LM': [configurations.sensor_click, configurations.sensor_battery],
|
||||
'WXKG12LM': [configurations.sensor_click, configurations.sensor_battery, configurations.sensor_action],
|
||||
// BREAKING_IMPROVEMENT: only use sensor_click for WXKG03LM (action hold -> click hold)
|
||||
'WXKG03LM': [configurations.sensor_click, configurations.sensor_battery, configurations.sensor_action],
|
||||
'WXKG02LM': [configurations.sensor_click, configurations.sensor_battery],
|
||||
'QBKG04LM': [configurations.switch, configurations.sensor_click, configurations.sensor_action],
|
||||
'QBKG03LM': [switchWithPostfix('left'), switchWithPostfix('right'), configurations.sensor_click],
|
||||
'QBKG03LM': [
|
||||
switchWithPostfix('left'), switchWithPostfix('right'), configurations.sensor_click,
|
||||
configurations.sensor_temperature,
|
||||
],
|
||||
'WSDCGQ01LM': [configurations.sensor_temperature, configurations.sensor_humidity, configurations.sensor_battery],
|
||||
'WSDCGQ11LM': [
|
||||
configurations.sensor_temperature, configurations.sensor_humidity, configurations.sensor_pressure,
|
||||
@@ -435,6 +453,7 @@ const mapping = {
|
||||
'BY 185 C': [configurations.light_brightness_colortemp_colorxy],
|
||||
'9290012573A': [configurations.light_brightness_colortemp_colorxy],
|
||||
'LED1624G9': [configurations.light_brightness_colorxy],
|
||||
'LED1837R5': [configurations.light_brightness],
|
||||
'73742': [configurations.light_brightness_colortemp],
|
||||
'73740': [configurations.light_brightness_colortemp],
|
||||
'73739': [configurations.light_brightness_colortemp_colorxy],
|
||||
@@ -496,6 +515,7 @@ const mapping = {
|
||||
'FB56+ZSW05HG1.2': [configurations.switch],
|
||||
'72922-A': [configurations.switch],
|
||||
'AC03642': [configurations.light_brightness_colortemp],
|
||||
'AC08560': [configurations.light_brightness],
|
||||
'DNCKATSW002': [switchWithPostfix('left'), switchWithPostfix('right')],
|
||||
'DNCKATSW003': [switchWithPostfix('left'), switchWithPostfix('right'), switchWithPostfix('center')],
|
||||
'DNCKATSW004': [
|
||||
@@ -505,6 +525,7 @@ const mapping = {
|
||||
'BY 165': [configurations.light_brightness],
|
||||
'ZLED-2709': [configurations.light_brightness],
|
||||
'8718696548738': [configurations.light_brightness_colortemp],
|
||||
'915005587401': [configurations.light_brightness_colortemp],
|
||||
'4052899926110': [configurations.light_brightness_colortemp_colorxy],
|
||||
'Z01-CIA19NAE26': [configurations.light_brightness],
|
||||
'E11-N1EA': [configurations.light_brightness_colortemp_colorxy],
|
||||
@@ -553,7 +574,11 @@ const mapping = {
|
||||
'PSS-23ZBS': [configurations.switch],
|
||||
'HS1SA': [configurations.binary_sensor_smoke, configurations.binary_sensor_battery_low],
|
||||
'Z01-A19NAE26': [configurations.light_brightness_colortemp],
|
||||
'AC01353010G': [configurations.binary_sensor_occupancy, configurations.sensor_temperature],
|
||||
'Z01-A60EAE27': [configurations.light_brightness_colortemp],
|
||||
'AC01353010G': [
|
||||
configurations.binary_sensor_occupancy, configurations.sensor_temperature,
|
||||
configurations.binary_sensor_battery_low,
|
||||
],
|
||||
'SP 120': [configurations.switch, configurations.sensor_power],
|
||||
'RB 248 T': [configurations.light_brightness_colortemp],
|
||||
'HS3SA': [configurations.binary_sensor_smoke, configurations.binary_sensor_battery_low],
|
||||
@@ -562,10 +587,9 @@ const mapping = {
|
||||
'HS1-WL-E': [configurations.binary_sensor_water_leak],
|
||||
'421786': [configurations.light_brightness],
|
||||
'ICZB-IW11D': [configurations.light_brightness],
|
||||
'HGZB-01A': [configurations.light_brightness],
|
||||
'3321-S': [configurations.binary_sensor_contact, configurations.sensor_temperature],
|
||||
'ZPIR-8000': [configurations.binary_sensor_occupancy],
|
||||
'ZCTS-808': [configurations.binary_sensor_contact],
|
||||
'ZCTS-808': [configurations.binary_sensor_contact, configurations.sensor_battery],
|
||||
'ZNLDP12LM': [configurations.light_brightness_colortemp],
|
||||
'D1821': [configurations.light_brightness_colortemp_colorxy],
|
||||
'ZNCLDJ11LM': [configurations.cover_position, configurations.sensor_cover],
|
||||
@@ -590,7 +614,7 @@ const mapping = {
|
||||
'D1532': [configurations.light_brightness],
|
||||
'AV2010/32': [],
|
||||
'HGZB-07A': [configurations.light_brightness_colortemp_colorxy],
|
||||
'E1524': [configurations.sensor_action],
|
||||
'E1524/E1810': [configurations.sensor_action, configurations.sensor_battery],
|
||||
'GL-C-006/GL-C-009': [configurations.light_brightness_colortemp],
|
||||
'100.424.11': [configurations.light_brightness_colortemp],
|
||||
'AC0251100NJ': [configurations.sensor_action, configurations.sensor_battery],
|
||||
@@ -621,6 +645,7 @@ const mapping = {
|
||||
'YRD426NRSC': [configurations.lock, configurations.sensor_battery],
|
||||
'E1743': [configurations.sensor_click, configurations.sensor_battery],
|
||||
'LED1732G11': [configurations.light_brightness_colortemp],
|
||||
'LED1736G9': [configurations.light_brightness_colortemp],
|
||||
'RB 265': [configurations.light_brightness],
|
||||
'9290019758': [
|
||||
configurations.binary_sensor_occupancy, configurations.sensor_temperature,
|
||||
@@ -652,7 +677,6 @@ const mapping = {
|
||||
],
|
||||
'9290018195': [configurations.light_brightness],
|
||||
'HGZB-04D': [configurations.light_brightness],
|
||||
'HGZB-02A': [configurations.light_brightness],
|
||||
'HGZB-043': [switchWithPostfix('top'), switchWithPostfix('bottom'), switchWithPostfix('center')],
|
||||
'NCZ-3043-HA': [
|
||||
configurations.binary_sensor_occupancy, configurations.sensor_temperature,
|
||||
@@ -691,9 +715,14 @@ const mapping = {
|
||||
'HGZB-1S': [configurations.switch, configurations.sensor_click],
|
||||
'HGZB-045': [configurations.switch, configurations.sensor_click],
|
||||
'HGZB-43': [switchWithPostfix('top'), switchWithPostfix('bottom'), switchWithPostfix('center')],
|
||||
'HGZB-01A/02A': [configurations.switch],
|
||||
'HGZB-01A': [configurations.switch],
|
||||
'HGZB-02A': [configurations.light_brightness],
|
||||
'MCT-350 SMA': [configurations.binary_sensor_contact],
|
||||
'3310-S': [configurations.sensor_temperature, configurations.sensor_battery],
|
||||
'IM6001-WLP01': [
|
||||
configurations.sensor_temperature, configurations.binary_sensor_water_leak,
|
||||
configurations.sensor_battery,
|
||||
],
|
||||
'3315-S': [
|
||||
configurations.sensor_temperature, configurations.binary_sensor_water_leak,
|
||||
configurations.sensor_battery,
|
||||
@@ -724,6 +753,7 @@ const mapping = {
|
||||
'45853GE': [configurations.switch, configurations.sensor_power],
|
||||
'50064': [configurations.light_brightness_colortemp],
|
||||
'9290011998B': [configurations.light_brightness_colortemp],
|
||||
'9290022167': [configurations.light_brightness_colortemp],
|
||||
'4096730U7': [configurations.light_brightness_colortemp],
|
||||
'RB 278 T': [configurations.light_brightness],
|
||||
'3315-G': [
|
||||
@@ -797,9 +827,72 @@ const mapping = {
|
||||
'ZNMS12LM': [
|
||||
configurations.sensor_action, configurations.binary_sensor_lock, configurations.binary_sensor_lock_reverse,
|
||||
],
|
||||
'ZNMS13LM': [
|
||||
configurations.sensor_action, configurations.binary_sensor_lock, configurations.binary_sensor_lock_reverse,
|
||||
],
|
||||
'12050': [configurations.switch, configurations.sensor_power],
|
||||
'ROB_200-004-0': [configurations.light_brightness],
|
||||
'RH3040': [configurations.sensor_battery, configurations.binary_sensor_occupancy],
|
||||
'DZ4743-00B': [configurations.switch],
|
||||
'GLSK3ZB-1711': [configurations.switch],
|
||||
'GLSK3ZB-1712': [switchWithPostfix('top'), switchWithPostfix('bottom')],
|
||||
'GLSK3ZB-1713': [switchWithPostfix('top'), switchWithPostfix('center'), switchWithPostfix('bottom')],
|
||||
'GLSK6ZB-1714': [
|
||||
switchWithPostfix('top_left'), switchWithPostfix('bottom_left'),
|
||||
switchWithPostfix('top_right'), switchWithPostfix('bottom_right'),
|
||||
],
|
||||
'GLSK6ZB-1715': [
|
||||
switchWithPostfix('top_left'), switchWithPostfix('center_left'), switchWithPostfix('bottom_left'),
|
||||
switchWithPostfix('top_right'), switchWithPostfix('bottom_right'),
|
||||
],
|
||||
'GLSK6ZB-1716': [
|
||||
switchWithPostfix('top_left'), switchWithPostfix('center_left'), switchWithPostfix('bottom_left'),
|
||||
switchWithPostfix('top_right'), switchWithPostfix('center_right'), switchWithPostfix('bottom_right'),
|
||||
],
|
||||
'3306431P7': [configurations.light_brightness_colortemp],
|
||||
'AC08559': [configurations.light_brightness_colortemp],
|
||||
'LVS-ZB15S': [configurations.switch],
|
||||
'LZL4BWHL01': [configurations.sensor_action],
|
||||
'2AJZ4KPKEY': [configurations.sensor_click, configurations.sensor_battery],
|
||||
'2AJZ4KPFT': [configurations.sensor_temperature, configurations.sensor_humidity, configurations.sensor_battery],
|
||||
'TT001ZAV20': [configurations.sensor_temperature, configurations.sensor_humidity, configurations.sensor_battery],
|
||||
'ZM-CSW002-D': [switchWithPostfix('l1'), switchWithPostfix('l2'), configurations.sensor_power],
|
||||
'LVS-SN10ZW': [configurations.sensor_battery, configurations.binary_sensor_occupancy],
|
||||
'LVS-ZB15R': [configurations.switch],
|
||||
'TH1123ZB': [configurations.thermostat],
|
||||
'Zen-01-W': [configurations.thermostat],
|
||||
'9290022166': [configurations.light_brightness_colortemp_colorxy],
|
||||
'PM-C140-ZB': [configurations.sensor_power, configurations.switch],
|
||||
'ptvo.switch': [
|
||||
switchWithPostfix('bottom_left'), switchWithPostfix('bottom_right'), switchWithPostfix('top_left'),
|
||||
switchWithPostfix('top_right'), switchWithPostfix('center'),
|
||||
],
|
||||
'DIYRuZ_R4_5': [
|
||||
switchWithPostfix('bottom_left'), switchWithPostfix('bottom_right'), switchWithPostfix('top_left'),
|
||||
switchWithPostfix('top_right'), switchWithPostfix('center'),
|
||||
],
|
||||
'DIYRuZ_KEYPAD20': [],
|
||||
'DTB190502A1': [],
|
||||
'RF 263': [configurations.light_brightness],
|
||||
'F-WTR-UK-V2': [
|
||||
configurations.sensor_temperature, configurations.binary_sensor_water_leak, configurations.sensor_battery,
|
||||
],
|
||||
'HS1CG-M': [configurations.binary_sensor_gas],
|
||||
'LVS-SN10ZW_SN11': [configurations.sensor_battery, configurations.binary_sensor_occupancy],
|
||||
'B00TN589ZG': [configurations.light_brightness],
|
||||
'PSB19-SW27': [configurations.light_brightness],
|
||||
'S1': [configurations.switch],
|
||||
'S2': [switchWithPostfix('l1'), switchWithPostfix('l2')],
|
||||
'D1': [configurations.light_brightness],
|
||||
'J1': [configurations.cover_position_tilt],
|
||||
'73741': [configurations.light_brightness_colortemp_colorxy],
|
||||
'ZA806SQ1TCF': [configurations.light_brightness_colortemp],
|
||||
'RF 265': [configurations.light_brightness],
|
||||
'ZNCZ03LM': [configurations.switch, configurations.sensor_power],
|
||||
'17436/30/P7': [configurations.light_brightness],
|
||||
'9290018187B': [configurations.light_brightness_colortemp_colorxy],
|
||||
'1741830P7': [configurations.light_brightness_colortemp_colorxy],
|
||||
'Z3-1BRL': [configurations.sensor_action, configurations.sensor_brightness],
|
||||
};
|
||||
|
||||
Object.keys(mapping).forEach((key) => {
|
||||
@@ -873,6 +966,10 @@ class HomeAssistant {
|
||||
payload.position_topic = stateTopic;
|
||||
}
|
||||
|
||||
if (payload.tilt_status_topic) {
|
||||
payload.tilt_status_topic = stateTopic;
|
||||
}
|
||||
|
||||
// Set json_attributes_topic for types which support this
|
||||
// https://github.com/Koenkk/zigbee2mqtt/issues/840
|
||||
if (['binary_sensor', 'sensor', 'lock', 'climate', 'fan'].includes(config.type)) {
|
||||
@@ -933,6 +1030,12 @@ class HomeAssistant {
|
||||
payload.set_position_topic = payload.command_topic;
|
||||
}
|
||||
|
||||
if (payload.tilt_command_topic && payload.command_topic) {
|
||||
// Home Assistant does not support templates to set tilt (as of 2019-08-17),
|
||||
// so we (have to) use a subtopic.
|
||||
payload.tilt_command_topic = payload.command_topic + '/tilt';
|
||||
}
|
||||
|
||||
if (payload.mode_state_topic) {
|
||||
payload.mode_state_topic = stateTopic;
|
||||
}
|
||||
@@ -965,8 +1068,10 @@ class HomeAssistant {
|
||||
if (device.hasOwnProperty('homeassistant')) {
|
||||
const add = (obj) => {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
if (['number', 'string'].includes(typeof obj[key])) {
|
||||
if (['number', 'string', 'boolean'].includes(typeof obj[key])) {
|
||||
payload[key] = obj[key];
|
||||
} else if (typeof obj[key] === 'object' && obj[key] === null) {
|
||||
delete payload[key];
|
||||
} else if (key === 'device' && typeof obj[key] === 'object') {
|
||||
Object.keys(obj['device']).forEach((key) => {
|
||||
payload['device'][key] = obj['device'][key];
|
||||
|
||||
+14
-11
@@ -11,6 +11,7 @@ class NetworkMap {
|
||||
|
||||
// Subscribe to topic.
|
||||
this.topic = `${settings.get().mqtt.base_topic}/bridge/networkmap`;
|
||||
this.topicRoutes = `${settings.get().mqtt.base_topic}/bridge/networkmap/routes`;
|
||||
|
||||
// Bind
|
||||
this.raw = this.raw.bind(this);
|
||||
@@ -31,13 +32,15 @@ class NetworkMap {
|
||||
|
||||
onMQTTConnected() {
|
||||
this.mqtt.subscribe(this.topic);
|
||||
this.mqtt.subscribe(this.topicRoutes);
|
||||
}
|
||||
|
||||
onMQTTMessage(topic, message) {
|
||||
message = message.toString();
|
||||
|
||||
if (topic === this.topic && this.supportedFormats.hasOwnProperty(message)) {
|
||||
this.zigbee.networkScan((result)=> {
|
||||
const includeRoutes = (topic === this.topicRoutes) ? 1: 0;
|
||||
if ((topic === this.topic || topic === this.topicRoutes) &&
|
||||
this.supportedFormats.hasOwnProperty(message)) {
|
||||
this.zigbee.networkScan(includeRoutes, (result)=> {
|
||||
const converted = this.supportedFormats[message](this.zigbee, result);
|
||||
this.mqtt.publish(`bridge/networkmap/${message}`, converted, {});
|
||||
});
|
||||
@@ -107,8 +110,8 @@ class NetworkMap {
|
||||
devStyle = `style="rounded, filled", fillcolor="${colors.fill.router}", ` +
|
||||
`fontcolor="${colors.font.router}"`;
|
||||
} else {
|
||||
devStyle = `style="rounded, dashed, filled", fillcolor="${colors.fill.enddevice}", `
|
||||
+ `fontcolor="${colors.font.enddevice}"`;
|
||||
devStyle = `style="rounded, dashed, filled", fillcolor="${colors.fill.enddevice}", ` +
|
||||
`fontcolor="${colors.font.enddevice}"`;
|
||||
}
|
||||
|
||||
// Add the device with its labels to the graph as a node.
|
||||
@@ -121,13 +124,13 @@ class NetworkMap {
|
||||
*/
|
||||
topology.links.filter((e) => (e.sourceIeeeAddr === device.ieeeAddr) || (e.SourceNwkAddr === device.nwkAddr))
|
||||
.forEach((e) => {
|
||||
const lineStyle = (device.type=='EndDevice') ? 'penwidth=1, '
|
||||
: (!e.routes.length) ? 'penwidth=0.5, ' : 'penwidth=2, ';
|
||||
const lineWeight = (!e.routes.length) ? `weight=0, color="${colors.line.inactive}", `
|
||||
: `weight=1, color="${colors.line.active}", `;
|
||||
const lineStyle = (device.type=='EndDevice') ? 'penwidth=1, ' : (!e.routes.length) ?
|
||||
'penwidth=0.5, ' : 'penwidth=2, ';
|
||||
const lineWeight = (!e.routes.length) ? `weight=0, color="${colors.line.inactive}", ` :
|
||||
`weight=1, color="${colors.line.active}", `;
|
||||
const textRoutes = e.routes.map((r) => `0x${r.toString(16)}`);
|
||||
const lineLabels = (!e.routes.length) ? `label="${e.lqi}"`
|
||||
: `label="${e.lqi}\\n[${textRoutes.join(']\\n[')}]"`;
|
||||
const lineLabels = (!e.routes.length) ? `label="${e.lqi}"` :
|
||||
`label="${e.lqi}\\n[${textRoutes.join(']\\n[')}]"`;
|
||||
text += ` "${device.ieeeAddr}" -> "${e.targetIeeeAddr}"`;
|
||||
text += ` [${lineStyle}${lineWeight}${lineLabels}]\n`;
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const zclId = require('zigbee-herdsman/dist/zcl-id');
|
||||
const Zcl = require('zigbee-herdsman/dist/zcl');
|
||||
|
||||
const OneJanuary2000 = new Date('January 01, 2000 00:00:00').getTime();
|
||||
|
||||
@@ -37,8 +37,8 @@ class ExtensionResponder {
|
||||
|
||||
readResponse(message, endpoint) {
|
||||
const clusterID = message.clusterid;
|
||||
const cluster = zclId.cluster(clusterID).key;
|
||||
const attributes = message.zclMsg.payload.map((p) => zclId.attr(message.clusterid, p.attrId));
|
||||
const cluster = Zcl.getClusterLegacy(clusterID).key;
|
||||
const attributes = message.zclMsg.payload.map((p) => Zcl.getAttributeLegacy(message.clusterid, p.attrId));
|
||||
const response = [];
|
||||
|
||||
attributes.forEach((attribute) => {
|
||||
@@ -59,7 +59,7 @@ class ExtensionResponder {
|
||||
attrId: attrId,
|
||||
status: 0,
|
||||
attrData: value,
|
||||
dataType: zclId.attrType(cId, attrId).value,
|
||||
dataType: Zcl.getAttributeTypeLegacy(cId, attrId).value,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -118,6 +118,16 @@ function getSettings() {
|
||||
return _settings;
|
||||
}
|
||||
|
||||
function get() {
|
||||
const _settings = objectAssignDeep.noMutate(defaults, getSettings());
|
||||
|
||||
if (!_settings.whitelist) {
|
||||
_settings.whitelist = [];
|
||||
}
|
||||
|
||||
return _settings;
|
||||
}
|
||||
|
||||
function writeRead() {
|
||||
write();
|
||||
_settings = read();
|
||||
@@ -377,7 +387,7 @@ function resolveEntity(ID) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
get: () => objectAssignDeep.noMutate(defaults, getSettings()),
|
||||
get: () => get(),
|
||||
write: () => write(),
|
||||
set: (path, value) => set(path, value),
|
||||
|
||||
|
||||
+3
-3
@@ -29,7 +29,7 @@ function toLocalISOString(dDate) {
|
||||
|
||||
const postfixes = [
|
||||
'left', 'right', 'center', 'bottom_left', 'bottom_right', 'l1', 'l2',
|
||||
'top_left', 'top_right', 'white', 'rgb', 'system', 'top', 'bottom',
|
||||
'top_left', 'top_right', 'white', 'rgb', 'system', 'top', 'bottom', 'center_left', 'center_right',
|
||||
];
|
||||
|
||||
function flatten(arr) {
|
||||
@@ -39,7 +39,7 @@ function flatten(arr) {
|
||||
}
|
||||
|
||||
const forceEndDevice = flatten(
|
||||
['QBKG03LM', 'QBKG04LM']
|
||||
['QBKG03LM', 'QBKG04LM', 'ZNMS13LM']
|
||||
.map((model) => zigbeeShepherdConverters.devices.find((d) => d.model === model))
|
||||
.map((mappedModel) => mappedModel.zigbeeModel));
|
||||
|
||||
@@ -91,7 +91,7 @@ function getZigbee2mqttVersion(callback) {
|
||||
|
||||
if (err) {
|
||||
try {
|
||||
commitHash = require('../.hash.json').hash;
|
||||
commitHash = require('../../.hash.json').hash;
|
||||
} catch (error) {
|
||||
commitHash = 'unknown';
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Based on: https://github.com/zigbeer/zapp-cie
|
||||
*/
|
||||
|
||||
const Ziee = require('zigbee-herdsman/dist/ziee');
|
||||
const Zive = require('zigbee-herdsman/dist/zive');
|
||||
const Ziee = require('zigbee-herdsman/dist/deprecated/ziee');
|
||||
const Zive = require('zigbee-herdsman/dist/deprecated/zive');
|
||||
const cieClusters = new Ziee();
|
||||
// Direction-Value 1: input, 2: output, 3: input/output
|
||||
|
||||
|
||||
+16
-14
@@ -6,7 +6,7 @@ const utils = require('./util/utils');
|
||||
const ZigbeeQueue = require('./util/zigbeeQueue');
|
||||
const cieApp = require('./zapp/cie');
|
||||
const objectAssignDeep = require('object-assign-deep');
|
||||
const zclId = require('zigbee-herdsman/dist/zcl-id');
|
||||
const Zcl = require('zigbee-herdsman/dist/zcl');
|
||||
|
||||
const advancedSettings = settings.get().advanced;
|
||||
|
||||
@@ -308,8 +308,8 @@ class Zigbee {
|
||||
return (friendlyName ? friendlyName : ID);
|
||||
}
|
||||
|
||||
networkScan(callback) {
|
||||
logger.info('Starting network scan...');
|
||||
networkScan(includeRoutes, callback) {
|
||||
logger.info(`Starting network scan includeRoutes='${includeRoutes}'...`);
|
||||
const lqiScanList = new Set();
|
||||
const rtgScanList = new Set();
|
||||
const linkMap = [];
|
||||
@@ -374,7 +374,7 @@ class Zigbee {
|
||||
});
|
||||
// Remove from scan list and if both lists are done return the completed network map
|
||||
lqiScanList.delete(targetIeeeAddr);
|
||||
if (lqiScanList.size === 0 && rtgScanList === 0) {
|
||||
if (lqiScanList.size === 0 && rtgScanList.size === 0) {
|
||||
logger.info('Network scan completed');
|
||||
collateMap();
|
||||
} else {
|
||||
@@ -436,14 +436,16 @@ class Zigbee {
|
||||
queueCallback(error);
|
||||
});
|
||||
});
|
||||
rtgScanList.add(dev.ieeeAddr);
|
||||
this.queue.push(dev.ieeeAddr, (queueCallback) => {
|
||||
this.shepherd.controller.request('ZDO', 'mgmtRtgReq', {dstaddr: dev.nwkAddr, startindex: 0},
|
||||
(error, rsp, ieeeAddr, nwkAddr) => {
|
||||
processRtgResponse(error, rsp, dev.ieeeAddr, dev.nwkAddr);
|
||||
queueCallback(error);
|
||||
});
|
||||
});
|
||||
if (includeRoutes) {
|
||||
rtgScanList.add(dev.ieeeAddr);
|
||||
this.queue.push(dev.ieeeAddr, (queueCallback) => {
|
||||
this.shepherd.controller.request('ZDO', 'mgmtRtgReq', {dstaddr: dev.nwkAddr, startindex: 0},
|
||||
(error, rsp, ieeeAddr, nwkAddr) => {
|
||||
processRtgResponse(error, rsp, dev.ieeeAddr, dev.nwkAddr);
|
||||
queueCallback(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for all device scans before forcing map with whatever results are already in
|
||||
@@ -613,8 +615,8 @@ class Zigbee {
|
||||
report(ep, cluster, attributes) {
|
||||
const friendlyName = this.getDeviceFriendlyName(ep.device.ieeeAddr);
|
||||
const cfgArr = attributes.map((attribute) => {
|
||||
const attrId = zclId.attr(cluster, attribute.attr).value;
|
||||
const dataType = zclId.attrType(cluster, attribute.attr).value;
|
||||
const attrId = Zcl.getAttributeLegacy(cluster, attribute.attr).value;
|
||||
const dataType = Zcl.getAttributeTypeLegacy(cluster, attribute.attr).value;
|
||||
return {
|
||||
direction: 0,
|
||||
attrId,
|
||||
|
||||
Generated
+7848
-1149
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zigbee2mqtt",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"description": "Zigbee to MQTT bridge using zigbee-shepherd",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -43,8 +43,8 @@
|
||||
"rimraf": "*",
|
||||
"semver": "*",
|
||||
"winston": "2.4.2",
|
||||
"zigbee-herdsman": "0.1.16",
|
||||
"zigbee-shepherd-converters": "10.1.4",
|
||||
"zigbee-herdsman": "0.5.7",
|
||||
"zigbee-shepherd-converters": "10.2.5",
|
||||
"deep-diff": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -947,6 +947,45 @@ describe('DevicePublish', () => {
|
||||
{color: {x: 0.701, y: 0.299}});
|
||||
});
|
||||
|
||||
it('Should use transition when enabled', async () => {
|
||||
zigbee.publish.mockClear();
|
||||
publishEntityState.mockClear();
|
||||
zigbee.getDevice = () => ({modelId: 'LCT001'});
|
||||
jest.spyOn(settings, 'getDevice').mockReturnValue({transition: 20});
|
||||
const msg = {'brightness': 200};
|
||||
devicePublish.onMQTTMessage('zigbee2mqtt/0x00000020/set', JSON.stringify(msg));
|
||||
expect(zigbee.publish).toHaveBeenCalledTimes(1);
|
||||
expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl');
|
||||
expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff');
|
||||
expect(zigbee.publish.mock.calls[0][5]).toStrictEqual({level: 200, transtime: 200});
|
||||
});
|
||||
|
||||
it('Should use transition when color temp', async () => {
|
||||
zigbee.publish.mockClear();
|
||||
publishEntityState.mockClear();
|
||||
zigbee.getDevice = () => ({modelId: 'LCT001'});
|
||||
jest.spyOn(settings, 'getDevice').mockReturnValue({transition: 20});
|
||||
const msg = {'color_temp': 200};
|
||||
devicePublish.onMQTTMessage('zigbee2mqtt/0x00000020/set', JSON.stringify(msg));
|
||||
expect(zigbee.publish).toHaveBeenCalledTimes(1);
|
||||
expect(zigbee.publish.mock.calls[0][2]).toBe('lightingColorCtrl');
|
||||
expect(zigbee.publish.mock.calls[0][3]).toBe('moveToColorTemp');
|
||||
expect(zigbee.publish.mock.calls[0][5]).toStrictEqual({colortemp: 200, transtime: 200});
|
||||
});
|
||||
|
||||
it('Message transition should overrule options transition', async () => {
|
||||
zigbee.publish.mockClear();
|
||||
publishEntityState.mockClear();
|
||||
zigbee.getDevice = () => ({modelId: 'LCT001'});
|
||||
jest.spyOn(settings, 'getDevice').mockReturnValue({transition: 20});
|
||||
const msg = {'brightness': 200, 'transition': 10};
|
||||
devicePublish.onMQTTMessage('zigbee2mqtt/0x00000020/set', JSON.stringify(msg));
|
||||
expect(zigbee.publish).toHaveBeenCalledTimes(1);
|
||||
expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl');
|
||||
expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff');
|
||||
expect(zigbee.publish.mock.calls[0][5]).toStrictEqual({level: 200, transtime: 100});
|
||||
});
|
||||
|
||||
it('Should set state with brightness before color', async () => {
|
||||
zigbee.publish.mockClear();
|
||||
publishEntityState.mockClear();
|
||||
|
||||
Reference in New Issue
Block a user