Skip to content

Commit

Permalink
Tuya: Add support for tuya closable sensors
Browse files Browse the repository at this point in the history
  • Loading branch information
mzanetti committed Nov 25, 2023
1 parent e39b814 commit 4f9d36c
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 15 deletions.
14 changes: 0 additions & 14 deletions zigbeegeneric/integrationpluginzigbeegeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,20 +345,6 @@ void IntegrationPluginZigbeeGeneric::createConnections(Thing *thing)

if (thing->thingClassId() == doorSensorThingClassId) {
connectToIasZoneInputCluster(thing, endpoint, "closed", true);
ZigbeeClusterIasZone *iasZoneCluster = endpoint->inputCluster<ZigbeeClusterIasZone>(ZigbeeClusterLibrary::ClusterIdIasZone);
if (!iasZoneCluster) {
qCWarning(dcZigbeeGeneric()) << "Could not find IAS zone cluster on" << thing << endpoint;
} else {
if (iasZoneCluster->hasAttribute(ZigbeeClusterIasZone::AttributeZoneStatus)) {
qCDebug(dcZigbeeGeneric()) << thing << iasZoneCluster->zoneStatus();
ZigbeeClusterIasZone::ZoneStatusFlags zoneStatus = iasZoneCluster->zoneStatus();
thing->setStateValue(doorSensorClosedStateTypeId, !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm1) && !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm2));
}
connect(iasZoneCluster, &ZigbeeClusterIasZone::zoneStatusChanged, thing, [=](ZigbeeClusterIasZone::ZoneStatusFlags zoneStatus, quint8 extendedStatus, quint8 zoneId, quint16 delays) {
qCDebug(dcZigbeeGeneric()) << "Zone status changed to:" << zoneStatus << extendedStatus << zoneId << delays;
thing->setStateValue(doorSensorClosedStateTypeId, !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm1) && !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm2));
});
}
}

if (thing->thingClassId() == motionSensorThingClassId) {
Expand Down
10 changes: 9 additions & 1 deletion zigbeetuya/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ This plugin adds support for ZigBee devices by Tuya.

## Supported Things

* Smart plugs with energy metering (TS011 plugs)
* Smart plugs with energy metering
* PIR motion sensors
* Mm Wave presence sensors
* Vibration sensors
* H&T sensors
* H&T Display sensors
* AirHouseKeeper
* Smoke sensors
* Door/Window sensors
21 changes: 21 additions & 0 deletions zigbeetuya/descriptors/_TZ3000_7d8yme6f.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--> ZigbeeNode(0x1577, A4:C1:38:EB:34:5E:C9:DB, _TZ3000_7d8yme6f (0x1141), TS0203, End device, RxOn:false)
ZigbeeNodeEndpoint(0x01, Zigbee::ZigbeeProfileHomeAutomation, Zigbee::HomeAutomationDeviceIasZone)
Manufacturer: "_TZ3000_7d8yme6f"
Model "TS0203"
Input clusters ( 4 )
- ZigbeeCluster(0x0000, Basic, Server)
- ZigbeeClusterAttribute(0x0004, ZigbeeDataType(Character string, _TZ3000_7d8yme6f))
- ZigbeeClusterAttribute(0x0005, ZigbeeDataType(Character string, TS0203))
- ZigbeeCluster(0x0001, PowerConfiguration, Server)
- ZigbeeCluster(0x0003, Identify, Server)
- ZigbeeCluster(0x0500, IasZone, Server)
- ZigbeeClusterAttribute(0x0000, ZigbeeDataType(16-bit bitmap, 0x04 0x00))
Output clusters ( 8 )
- ZigbeeCluster(0x0008, LevelControl, Client)
- ZigbeeCluster(0x000a, Time, Client)
- ZigbeeCluster(0x0019, OtaUpgrade, Client)
- ZigbeeCluster(0x0004, Groups, Client)
- ZigbeeCluster(0x0005, Scenes, Client)
- ZigbeeCluster(0x0006, OnOff, Client)
- ZigbeeCluster(0x1000, TouchlinkCommissioning, Client)
- ZigbeeCluster(0x0003, Identify, Client)
20 changes: 20 additions & 0 deletions zigbeetuya/integrationpluginzigbeetuya.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ bool IntegrationPluginZigbeeTuya::handleNode(ZigbeeNode *node, const QUuid &/*ne
return true;
}

if (match(node, "TS0203", {"_TZ3000_7d8yme6f"})) {
// Implements IAS Zone spec, but doesn't reply to ZoneType attribute, thus not handled properly by generic plugin
ZigbeeNodeEndpoint *endpoint = node->getEndpoint(0x01);
configurePowerConfigurationInputClusterAttributeReporting(endpoint);
bindCluster(endpoint, ZigbeeClusterLibrary::ClusterIdIasZone);
configureIasZoneInputClusterAttributeReporting(endpoint);
enrollIasZone(endpoint, 0x42);
createThing(closableSensorThingClassId, node);
return true;
}
return false;
}

Expand Down Expand Up @@ -667,6 +677,16 @@ void IntegrationPluginZigbeeTuya::createConnections(Thing *thing)

});
}

if (info->thing()->thingClassId() == closableSensorThingClassId) {
ZigbeeNodeEndpoint *endpoint = node->getEndpoint(1);
if (!endpoint) {
qCWarning(dcZigbeeTuya()) << "Unable to find endpoint 1 on node" << node;
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Unable to find endpoint 1 on Zigbee node."));
return;
}
connectToIasZoneInputCluster(thing, endpoint, "closed", true);
}
}

void IntegrationPluginZigbeeTuya::executeAction(ThingActionInfo *info)
Expand Down
80 changes: 80 additions & 0 deletions zigbeetuya/integrationpluginzigbeetuya.json
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,86 @@
"defaultValue": false
}
]
},
{
"id": "82a859f0-41ed-4a53-93b0-260a1435ac75",
"name": "closableSensor",
"displayName": "Door/window sensor",
"createMethods": ["auto"],
"interfaces": ["closablesensor", "battery", "wirelessconnectable"],
"paramTypes": [
{
"id": "06a60993-2ce7-484d-9ffd-13020be8fa78",
"name": "ieeeAddress",
"displayName": "IEEE adress",
"type": "QString",
"defaultValue": "00:00:00:00:00:00:00:00"
},
{
"id": "7850cdee-7d65-48f9-a08a-4cabe9c20594",
"name": "networkUuid",
"displayName": "Zigbee network UUID",
"type": "QString",
"defaultValue": ""
}
],
"stateTypes": [
{
"id": "6d4523c2-66f1-4fbf-b0d9-bd11a1920b50",
"name": "closed",
"displayName": "Closed",
"displayNameEvent": "Opened or closed",
"type": "bool",
"defaultValue": false
},
{
"id": "948bc2da-23fb-44fd-a74c-c917bf657bf0",
"name": "tampered",
"displayName": "Tampered",
"displayNameEvent": "Tampered",
"type": "bool",
"defaultValue": false
},
{
"id": "34a8f7f1-19f8-47be-a1b2-4d7ea52fee1e",
"name": "batteryLevel",
"displayName": "Battery level",
"displayNameEvent": "Battery level changed",
"type": "int",
"minValue": 0,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 50
},
{
"id": "455e1ebc-5534-4053-8db3-c0b6b79f8c41",
"name": "batteryCritical",
"displayName": "Battery critical",
"displayNameEvent": "Battery critical changed",
"type": "bool",
"defaultValue": false
},
{
"id": "10d8aa94-943e-40f6-a10e-0ac77bcdecd3",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected or disconnected",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "4ef57e47-2b83-4d41-8cfb-21bf2f5ee62d",
"name": "signalStrength",
"displayName": "Signal strength",
"displayNameEvent": "Signal strength changed",
"type": "uint",
"minValue": 0,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0
}
]
}
]
}
Expand Down
3 changes: 3 additions & 0 deletions zigbeetuya/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
],
"categories": [
"socket",
"sensor",
"door",
"energy"
]
}

0 comments on commit 4f9d36c

Please sign in to comment.