Skip to content

Commit

Permalink
Zigbee2mqtt : Remove duplicate features in getDiscoveredDevices to fi…
Browse files Browse the repository at this point in the history
…x bug on Aqara motion sensor (#2057)
  • Loading branch information
Pierre-Gilles authored Apr 22, 2024
1 parent 40a8ec8 commit 5151c99
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
13 changes: 13 additions & 0 deletions server/services/zigbee2mqtt/lib/getDiscoveredDevices.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ function getDiscoveredDevices(filters = {}) {
devices = devices.filter((device) => device.id === undefined || device.updatable);
}

devices.forEach((device) => {
// Remove features with duplicate external_id
// This code is needed because AQARA motion sensor
// Returns 2 illuminance features and it doesn't work with Gladys
device.features = device.features.reduce((acc, current) => {
const isDuplicate = acc.some((feature) => feature.external_id === current.external_id);
if (!isDuplicate) {
acc.push(current);
}
return acc;
}, []);
});

return devices;
}

Expand Down
28 changes: 28 additions & 0 deletions server/test/services/zigbee2mqtt/lib/getDiscoveredDevices.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const Zigbee2MqttService = require('../../../../services/zigbee2mqtt');
const discoveredDevices = require('./payloads/mqtt_devices_get.json');
const expectedDevicesPayload = require('./payloads/event_device_result.json');

const aqaraWithDuplicateFeatureDevice = require('./payloads/aqara_with_duplicate_feature_mqtt.json');

const gladys = {
job: {
wrapper: (type, func) => {
Expand Down Expand Up @@ -57,6 +59,32 @@ describe('zigbee2mqtt getDiscoveredDevices', () => {
expect(devices).deep.eq(expectedDevicesPayload);
});

it('get discovered devices without duplicate features', async () => {
// PREPARE
gladys.stateManager.get
.onFirstCall()
.returns({ id: 'gladys-id', room_id: 'room_id', name: 'device-name' })
.onSecondCall()
.returns(expectedDevicesPayload[3])
.onThirdCall()
.returns(false);

aqaraWithDuplicateFeatureDevice
.filter((d) => d.supported)
.forEach((device) => {
zigbee2MqttService.device.discoveredDevices[device.friendly_name] = device;
});

// EXECUTE
const devices = zigbee2MqttService.device.getDiscoveredDevices();
const aqaraDevice = devices.find((d) => d.model === 'WSDCGQ11LM');
// ASSERT
expect(aqaraDevice.features.filter((f) => f.category === 'humidity-sensor')).to.have.lengthOf(
1,
'should not have duplicate humidity',
);
});

it('filter discovered devices', async () => {
// PREPARE
gladys.stateManager.get
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
[
{
"date_code": "20161129",
"definition": {
"description": "Aqara temperature, humidity and pressure sensor",
"exposes": [
{
"access": 1,
"description": "Remaining battery in %",
"name": "battery",
"property": "battery",
"type": "numeric",
"unit": "%",
"value_max": 100,
"value_min": 0
},
{
"access": 1,
"description": "Measured temperature value",
"name": "temperature",
"property": "temperature",
"type": "numeric",
"unit": "°C"
},
{
"access": 1,
"description": "Measured relative humidity",
"name": "humidity",
"property": "humidity",
"type": "numeric",
"unit": "%"
},
{
"access": 1,
"description": "Measured relative humidity (duplicate)",
"name": "humidity",
"property": "humidity",
"type": "numeric"
},
{
"access": 7,
"description": "Any binary feature",
"name": "alarm",
"property": "alarm",
"type": "binary",
"value_off": false,
"value_on": true
},
{
"access": 1,
"description": "The measured atmospheric pressure",
"name": "pressure",
"property": "pressure",
"type": "numeric",
"unit": "hPa"
},
{
"access": 1,
"description": "Voltage of the battery in millivolts",
"name": "voltage",
"property": "voltage",
"type": "numeric",
"unit": "mV"
},
{
"access": 1,
"description": "Link quality (signal strength)",
"name": "linkquality",
"property": "linkquality",
"type": "numeric",
"unit": "lqi",
"value_max": 255,
"value_min": 0
}
],
"model": "WSDCGQ11LM",
"supports_ota": false,
"vendor": "Xiaomi"
},
"endpoints": {
"1": {
"bindings": [],
"clusters": {
"input": [
"genBasic",
"genIdentify",
"msTemperatureMeasurement",
"msPressureMeasurement",
"msRelativeHumidity"
],
"output": ["genBasic", "genGroups"]
},
"configured_reportings": []
}
},
"friendly_name": "0x00158d00045b2740",
"ieee_address": "0x00158d00045b2740",
"interview_completed": true,
"interviewing": false,
"manufacturer": "LUMI",
"model_id": "lumi.weather",
"network_address": 23007,
"power_source": "Battery",
"software_build_id": "3000-0001",
"supported": true,
"type": "EndDevice"
}
]

0 comments on commit 5151c99

Please sign in to comment.