Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for new functionality RTCZCGQ11LM in firmware #53 ('motion_sensitivity' and 'reset_nopresence_status') #3966

Merged
merged 1 commit into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion converters/toZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -2031,7 +2031,7 @@ const converters = {
await entity.read('genBasic', [0x0033], manufacturerOptions.hue);
},
},
RTCGQ13LM_motion_sensitivity: {
aqara_motion_sensitivity: {
key: ['motion_sensitivity'],
convertSet: async (entity, key, value, meta) => {
const lookup = {'low': 1, 'medium': 2, 'high': 3};
Expand Down Expand Up @@ -2074,6 +2074,12 @@ const converters = {
await entity.read('aqaraOpple', [0x0146], manufacturerOptions.xiaomi);
},
},
RTCZCGQ11LM_reset_nopresence_status: {
key: ['reset_nopresence_status'],
convertSet: async (entity, key, value, meta) => {
await entity.write('aqaraOpple', {0x0157: {value: 1, type: 0x20}}, manufacturerOptions.xiaomi);
},
},
ZigUP_lock: {
key: ['led'],
convertSet: async (entity, key, value, meta) => {
Expand Down
14 changes: 10 additions & 4 deletions devices/xiaomi.js
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ module.exports = [
vendor: 'Xiaomi',
description: 'Aqara high precision motion sensor',
fromZigbee: [fz.RTCGQ13LM_occupancy, fz.aqara_opple, fz.battery],
toZigbee: [tz.aqara_detection_interval, tz.RTCGQ13LM_motion_sensitivity],
toZigbee: [tz.aqara_detection_interval, tz.aqara_motion_sensitivity],
exposes: [e.occupancy(), exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']),
exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
.withDescription('Time interval for detecting actions'), e.battery()],
Expand All @@ -910,9 +910,10 @@ module.exports = [
zigbeeModel: ['lumi.motion.ac01'],
model: 'RTCZCGQ11LM',
vendor: 'Xiaomi',
description: 'Aqara Presence Detector FP1 (regions not supported for now)',
description: 'Aqara presence detector FP1 (regions not supported for now)',
fromZigbee: [fz.aqara_opple],
toZigbee: [tz.RTCZCGQ11LM_presence, tz.RTCZCGQ11LM_monitoring_mode, tz.RTCZCGQ11LM_approach_distance],
toZigbee: [tz.RTCZCGQ11LM_presence, tz.RTCZCGQ11LM_monitoring_mode, tz.RTCZCGQ11LM_approach_distance,
tz.aqara_motion_sensitivity, tz.RTCZCGQ11LM_reset_nopresence_status],
exposes: [e.presence().withAccess(ea.STATE_GET),
exposes.enum('presence_event', ea.STATE, ['enter', 'leave', 'left_enter', 'right_leave', 'right_enter', 'left_leave',
'approach', 'away']).withDescription('Presence events: "enter", "leave", "left_enter", "right_leave", ' +
Expand All @@ -921,9 +922,14 @@ module.exports = [
'without considering right and left sides'),
exposes.enum('approach_distance', ea.ALL, ['far', 'medium', 'near']).withDescription('The distance at which the ' +
'sensor detects approaching'),
exposes.numeric('power_outage_count', ea.STATE).withDescription('Number of power outages (since last pairing)')],
exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']).withDescription('Different sensitivities ' +
'means different static human body recognition rate and response speed of occupied'),
exposes.enum('reset_nopresence_status', ea.SET, ['Reset']).withDescription('Reset the status of no presence'),
Koenkk marked this conversation as resolved.
Show resolved Hide resolved
exposes.numeric('power_outage_count', ea.STATE).withDescription('Number of power outages (since last pairing)'),
e.temperature()],
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f});
await endpoint.read('aqaraOpple', [0x0142], {manufacturerCode: 0x115f});
await endpoint.read('aqaraOpple', [0x0144], {manufacturerCode: 0x115f});
await endpoint.read('aqaraOpple', [0x0146], {manufacturerCode: 0x115f});
Expand Down
34 changes: 23 additions & 11 deletions lib/xiaomi.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,19 +213,25 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
payload.illuminance = calibrateAndPrecisionRoundOptions(value, options, 'illuminance');
} else if (['ZNJLBL01LM'].includes(model.model)) {
payload.battery = value;
} else if (['RTCZCGQ11LM'].includes(model.model)) {
payload.presence = {0: false, 1: true, 255: null}[value];
}
break;
case '102':
if (['QBKG25LM', 'QBKG34LM'].includes(model.model)) {
payload.state_right = value === 1 ? 'ON' : 'OFF';
} else if (['RTCZCGQ11LM'].includes(model.model)) {
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
5: 'left_leave', 6: 'approach', 7: 'away', 255: null}[value];
if (meta.device.applicationVersion < 50) {
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
5: 'left_leave', 6: 'approach', 7: 'away', 255: null}[value];
} else {
payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
}
}
break;
case '103':
if (['RTCZCGQ11LM'].includes(model.model)) {
payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected';
payload.monitoring_mode = {0: 'undirected', 1: 'left_right'}[value];
}
break;
case '105':
Expand Down Expand Up @@ -288,7 +294,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
payload.detection_interval = value;
break;
case '268':
if (['RTCGQ13LM'].includes(model.model)) {
if (['RTCGQ13LM', 'RTCZCGQ11LM'].includes(model.model)) {
payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
} else if (['JT-BZ-01AQ/A'].includes(model.model)) {
payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[value];
Expand All @@ -313,19 +319,25 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
payload.gas_density = value; // JT-BZ-01AQ/A
break;
case '322':
payload.presence = value === 1; // RTCZCGQ11LM
if (['RTCZCGQ11LM'].includes(model.model)) {
payload.presence = {0: false, 1: true, 255: null}[value];
}
break;
case '323':
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
5: 'left_leave', 6: 'approach', 7: 'away'}[value]; // RTCZCGQ11LM
if (['RTCZCGQ11LM'].includes(model.model)) {
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
5: 'left_leave', 6: 'approach', 7: 'away'}[value];
}
break;
case '324':
// RTCZCGQ11LM
payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected';
if (['RTCZCGQ11LM'].includes(model.model)) {
payload.monitoring_mode = {0: 'undirected', 1: 'left_right'}[value];
}
break;
case '326':
// RTCZCGQ11LM
payload.approach_distance = {0: 'far', 1: 'medium', 2: 'near'}[value];
if (['RTCZCGQ11LM'].includes(model.model)) {
payload.approach_distance = {0: 'far', 1: 'medium', 2: 'near'}[value];
}
break;
case '331':
payload.linkage_alarm = value === 1; // JT-BZ-01AQ/A
Expand Down