@@ -286,6 +286,7 @@ static const SupportedDevice supportedDevices[] = {
286
286
{ VENDOR_XIAOMI, "lumi.plug", xiaomiMacPrefix }, // Xiaomi smart plugs (router)
287
287
{ VENDOR_XIAOMI, "lumi.switch.b1naus01", xiaomiMacPrefix }, // Xiaomi Aqara ZB3.0 Smart Wall Switch Single Rocker WS-USC03
288
288
// { VENDOR_XIAOMI, "lumi.curtain", jennicMacPrefix}, // Xiaomi curtain controller (router) - exposed only as light
289
+ { VENDOR_XIAOMI, "lumi.curtain.acn002", lumiMacPrefix}, // Xiaomi roller shade driver E1
289
290
{ VENDOR_XIAOMI, "lumi.curtain.hagl04", xiaomiMacPrefix}, // Xiaomi B1 curtain controller
290
291
{ VENDOR_XIAOMI, "lumi.remote.cagl01", xiaomiMacPrefix }, // Xiaomi Aqara T1 Cube MFKZQ11LM
291
292
{ VENDOR_XIAOMI, "lumi.sensor_magnet.agl02", xiaomiMacPrefix}, // Xiaomi Aqara T1 open/close sensor MCCGQ12LM
@@ -496,7 +497,7 @@ static const SupportedDevice supportedDevices[] = {
496
497
{ VENDOR_ALERTME, "SLT3", computimeMacPrefix }, // Hive thermostat
497
498
{ VENDOR_DANFOSS, "TRV001", silabs2MacPrefix }, // Hive thermostat (From Danfoss)
498
499
{ VENDOR_SUNRICHER, "45127", silabs2MacPrefix }, // Namron 1/2/4-ch remote controller
499
- { VENDOR_SUNRICHER, "S57003", silabs2MacPrefix }, // SLC 4-ch remote controller
500
+ { VENDOR_SUNRICHER, "S57003", silabs2MacPrefix }, // SLC 4-ch remote controller
500
501
{ VENDOR_SENGLED_OPTOELEC, "E13-", zhejiangMacPrefix }, // Sengled PAR38 Bulbs
501
502
{ VENDOR_SENGLED_OPTOELEC, "E1D-", zhejiangMacPrefix }, // Sengled contact sensor
502
503
{ VENDOR_SENGLED_OPTOELEC, "E1E-", zhejiangMacPrefix }, // Sengled Smart Light Switch
@@ -2432,7 +2433,7 @@ void DeRestPluginPrivate::addLightNode(const deCONZ::Node *node)
2432
2433
}
2433
2434
if (node->nodeDescriptor().manufacturerCode() == VENDOR_KEEN_HOME || // Keen Home Vent
2434
2435
node->nodeDescriptor().manufacturerCode() == VENDOR_JENNIC || // Xiaomi lumi.ctrl_neutral1, lumi.ctrl_neutral2
2435
- node->nodeDescriptor().manufacturerCode() == VENDOR_XIAOMI || // Xiaomi lumi.curtain.hagl04
2436
+ node->nodeDescriptor().manufacturerCode() == VENDOR_XIAOMI || // Xiaomi lumi.curtain.hagl04, lumi.curtain.acn002
2436
2437
node->nodeDescriptor().manufacturerCode() == VENDOR_EMBER || // atsmart Z6-03 switch + Heiman plug + Tuya stuff
2437
2438
(!node->nodeDescriptor().isNull() && node->nodeDescriptor().manufacturerCode() == VENDOR_NONE) || // Climax Siren
2438
2439
node->nodeDescriptor().manufacturerCode() == VENDOR_DEVELCO || // Develco Smoke sensor with siren
@@ -3971,6 +3972,11 @@ LightNode *DeRestPluginPrivate::updateLightNode(const deCONZ::NodeEvent &event)
3971
3972
updated = true;
3972
3973
setLightNodeStaticCapabilities(lightNode);
3973
3974
enqueueEvent({lightNode->prefix(), item->descriptor().suffix, lightNode->id(), item, lightNode->address().ext()});
3975
+
3976
+ {
3977
+ Q_Q(DeRestPlugin);
3978
+ emit q->nodeUpdated(lightNode->address().ext(), QLatin1String("vendor"), str);
3979
+ }
3974
3980
}
3975
3981
}
3976
3982
else if (ia->id() == 0x0005) // Model identifier
@@ -4014,6 +4020,11 @@ LightNode *DeRestPluginPrivate::updateLightNode(const deCONZ::NodeEvent &event)
4014
4020
setLightNodeStaticCapabilities(lightNode);
4015
4021
enqueueEvent({lightNode->prefix(), item->descriptor().suffix, lightNode->id(), item, lightNode->address().ext()});
4016
4022
}
4023
+
4024
+ {
4025
+ Q_Q(DeRestPlugin);
4026
+ emit q->nodeUpdated(lightNode->address().ext(), QLatin1String("modelid"), str);
4027
+ }
4017
4028
}
4018
4029
else if (ia->id() == 0x0006) // Date code
4019
4030
{
@@ -4029,6 +4040,11 @@ LightNode *DeRestPluginPrivate::updateLightNode(const deCONZ::NodeEvent &event)
4029
4040
updated = true;
4030
4041
}
4031
4042
item->setValue(str); // always needed to refresh set timestamp
4043
+
4044
+ {
4045
+ Q_Q(DeRestPlugin);
4046
+ emit q->nodeUpdated(lightNode->address().ext(), QLatin1String("version"), str);
4047
+ }
4032
4048
}
4033
4049
}
4034
4050
else if (ia->id() == 0x4000) // Software build identifier
@@ -5752,7 +5768,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ::
5752
5768
{
5753
5769
fpDoorLockSensor.inClusters.push_back(DOOR_LOCK_CLUSTER_ID);
5754
5770
}
5755
-
5771
+
5756
5772
fpAirQualitySensor.inClusters.push_back(ci->id());
5757
5773
fpAlarmSensor.inClusters.push_back(ci->id());
5758
5774
fpBatterySensor.inClusters.push_back(ci->id());
@@ -5794,11 +5810,6 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ::
5794
5810
{
5795
5811
fpBatterySensor.inClusters.push_back(ci->id());
5796
5812
}
5797
- if (node->nodeDescriptor().manufacturerCode() == VENDOR_XIAOMI &&
5798
- modelId.startsWith(QLatin1String("lumi.curtain.hagl04")))
5799
- {
5800
- fpBatterySensor.inClusters.push_back(ci->id());
5801
- }
5802
5813
if ((node->nodeDescriptor().manufacturerCode() == VENDOR_AXIS || node->nodeDescriptor().manufacturerCode() == VENDOR_MMB) &&
5803
5814
(modelId == QLatin1String("Gear")) && (i->endpoint() == 0x01))
5804
5815
{
@@ -6463,6 +6474,10 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ::
6463
6474
fpSwitch.inClusters.push_back(ci->id());
6464
6475
fpTemperatureSensor.inClusters.push_back(ci->id());
6465
6476
fpThermostatSensor.inClusters.push_back(ci->id());
6477
+ if (modelId.startsWith(QLatin1String("lumi.curtain")))
6478
+ {
6479
+ fpBatterySensor.inClusters.push_back(ci->id());
6480
+ }
6466
6481
}
6467
6482
}
6468
6483
break;
@@ -6692,11 +6707,11 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ::
6692
6707
checkSensorNodeReachable(sensor);
6693
6708
}
6694
6709
}
6695
-
6710
+
6696
6711
//ZHAAncillaryControl
6697
6712
if (fpAncillaryControlSensor.hasOutCluster(IAS_ACE_CLUSTER_ID))
6698
6713
{
6699
-
6714
+
6700
6715
fpAncillaryControlSensor.endpoint = i->endpoint();
6701
6716
fpAncillaryControlSensor.deviceId = i->deviceId();
6702
6717
fpAncillaryControlSensor.profileId = i->profileId();
@@ -6844,7 +6859,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ::
6844
6859
checkSensorNodeReachable(sensor);
6845
6860
}
6846
6861
}
6847
-
6862
+
6848
6863
// ZHAMoisture
6849
6864
if (fpMoistureSensor.hasInCluster(SOIL_MOISTURE_CLUSTER_ID))
6850
6865
{
@@ -7040,6 +7055,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ::
7040
7055
7041
7056
// ZHABattery
7042
7057
if (fpBatterySensor.hasInCluster(POWER_CONFIGURATION_CLUSTER_ID) ||
7058
+ fpBatterySensor.hasInCluster(XIAOMI_CLUSTER_ID) ||
7043
7059
fpBatterySensor.hasInCluster(TUYA_CLUSTER_ID))
7044
7060
{
7045
7061
fpBatterySensor.endpoint = i->endpoint();
@@ -7309,7 +7325,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi
7309
7325
sensorNode.addItem(DataTypeInt16, RStateTemperature);
7310
7326
item = sensorNode.addItem(DataTypeInt16, RConfigOffset);
7311
7327
item->setValue(0);
7312
-
7328
+
7313
7329
if (R_GetProductId(&sensorNode).startsWith(QLatin1String("Tuya_SEN")))
7314
7330
{
7315
7331
// Enable reporting in "blind mode"
@@ -7781,11 +7797,19 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi
7781
7797
{
7782
7798
clusterId = POWER_CONFIGURATION_CLUSTER_ID;
7783
7799
}
7800
+ else if (sensorNode.fingerPrint().hasInCluster(XIAOMI_CLUSTER_ID))
7801
+ {
7802
+ clusterId = XIAOMI_CLUSTER_ID;
7803
+ }
7784
7804
else if (sensorNode.fingerPrint().hasInCluster(TUYA_CLUSTER_ID))
7785
7805
{
7786
7806
clusterId = TUYA_CLUSTER_ID;
7787
7807
}
7788
7808
sensorNode.addItem(DataTypeUInt8, RStateBattery);
7809
+ if (modelId.startsWith(QLatin1String("lumi.curtain.")))
7810
+ {
7811
+ sensorNode.addItem(DataTypeBool, RStateCharging);
7812
+ }
7789
7813
}
7790
7814
else if (sensorNode.type().endsWith(QLatin1String("Time")))
7791
7815
{
@@ -8972,7 +8996,7 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
8972
8996
{
8973
8997
pressure += item2->toNumber();
8974
8998
}
8975
-
8999
+
8976
9000
item->setValue(pressure);
8977
9001
i->updateStateTimestamp();
8978
9002
i->setNeedSaveDatabase(true);
@@ -9223,7 +9247,7 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
9223
9247
{
9224
9248
continue;
9225
9249
}
9226
-
9250
+
9227
9251
// Correct incomplete sensor fingerprint
9228
9252
if (!i->fingerPrint().hasInCluster(BASIC_CLUSTER_ID))
9229
9253
{
@@ -10939,12 +10963,12 @@ bool DeRestPluginPrivate::processZclAttributes(Sensor *sensorNode)
10939
10963
if (item)
10940
10964
{
10941
10965
quint64 sensitivity = item->toNumber();
10942
-
10966
+
10943
10967
if (nd.manufacturerCode() == VENDOR_PHILIPS)
10944
10968
{
10945
10969
deCONZ::ZclAttribute attr(0x0030, deCONZ::Zcl8BitUint, "sensitivity", deCONZ::ZclReadWrite, true);
10946
10970
attr.setValue(sensitivity);
10947
-
10971
+
10948
10972
if (writeAttribute(sensorNode, sensorNode->fingerPrint().endpoint, OCCUPANCY_SENSING_CLUSTER_ID, attr, VENDOR_PHILIPS))
10949
10973
{
10950
10974
sensorNode->setNextReadTime(WRITE_SENSITIVITY, tNow.addSecs(7200));
@@ -10955,7 +10979,7 @@ bool DeRestPluginPrivate::processZclAttributes(Sensor *sensorNode)
10955
10979
{
10956
10980
deCONZ::ZclAttribute attr(XIAOMI_ATTRID_MOTION_SENSITIVITY, deCONZ::Zcl8BitUint, "sensitivity", deCONZ::ZclReadWrite, true);
10957
10981
attr.setValue(sensitivity);
10958
-
10982
+
10959
10983
if (writeAttribute(sensorNode, sensorNode->fingerPrint().endpoint, XIAOMI_CLUSTER_ID, attr, VENDOR_XIAOMI))
10960
10984
{
10961
10985
sensorNode->setNextReadTime(WRITE_SENSITIVITY, tNow.addSecs(3300)); // Default special reporting intervall
@@ -15872,9 +15896,9 @@ void DeRestPluginPrivate::delayedFastEnddeviceProbe(const deCONZ::NodeEvent *eve
15872
15896
{
15873
15897
std::vector<uint16_t> attributes;
15874
15898
auto *item = sensor->item(RConfigSensitivity);
15875
-
15899
+
15876
15900
if (item) { attributes.push_back(XIAOMI_ATTRID_MOTION_SENSITIVITY); }
15877
-
15901
+
15878
15902
if (!attributes.empty() && readAttributes(sensor, sensor->fingerPrint().endpoint, XIAOMI_CLUSTER_ID, attributes, VENDOR_XIAOMI))
15879
15903
{
15880
15904
DBG_Printf(DBG_INFO, "Read 0x%016llX motion sensitivity attribute 0x010C...\n", sensor->address().ext());
0 commit comments