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

Adds support for _TZE200_3towulqd using Tuya Cluster #735

Closed
wants to merge 2 commits into from
Closed
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
173 changes: 173 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3075,6 +3075,179 @@
}
]
},
{
"id": "motion_sensor_2_tuya_cluster",
"name": {
"en": "Motion Sensor (Tuya Cluster)"
},
"class": "sensor",
"platforms": [
"local"
],
"connectivity": [
"zigbee"
],
"capabilities": [
"measure_battery",
"measure_luminance",
"alarm_motion",
"alarm_battery"
],
"energy": {
"batteries": [
"CR2450"
]
},
"images": {
"large": "/drivers/motion_sensor_2_tuya_cluster/assets/images/large.png",
"small": "/drivers/motion_sensor_2_tuya_cluster/assets/images/small.png"
},
"zigbee": {
"manufacturerName": [
"_TZE200_3towulqd"
],
"productId": [
"TS0601"
],
"endpoints": {
"1": {
"clusters": [
0,
61184
],
"bindings": [
25,
10
]
}
},
"learnmode": {
"image": "/drivers/motion_sensor_2_tuya_cluster/assets/icon.svg",
"instruction": {
"en": "Use a pin to press the reset button for aprox 5 seconds until the LED blinks."
}
}
},
"settings": [
{
"id": "batteryThreshold",
"type": "number",
"label": {
"en": "Battery Low Alarm Voltage Threshold (%)"
},
"hint": {
"en": "This setting determines the threshold before a battery alarm is given."
},
"value": 20,
"attr": {
"step": 1,
"min": 1,
"max": 99
}
},
{
"type": "group",
"label": {
"en": "Device settings (confirm with quickly inserting pin into device)"
},
"children": [
{
"id": "pirSensitivity",
"type": "dropdown",
"value": "2",
"label": {
"en": "Pir Sensitivity"
},
"values": [
{
"id": "0",
"label": {
"en": "Low"
}
},
{
"id": "1",
"label": {
"en": "Middle"
}
},
{
"id": "2",
"label": {
"en": "High"
}
}
]
},
{
"id": "intervalTime",
"type": "dropdown",
"value": "2",
"hint": {
"en": "Version 2.0.1 and above"
},
"label": {
"en": "Light Sense Interval Time"
},
"values": [
{
"id": "0",
"label": {
"en": "Low"
}
},
{
"id": "1",
"label": {
"en": "Middle"
}
},
{
"id": "2",
"label": {
"en": "High"
}
}
]
},
{
"id": "keepTime",
"type": "dropdown",
"value": "0",
"label": {
"en": "Keep time"
},
"values": [
{
"id": "0",
"label": {
"en": "10S"
}
},
{
"id": "1",
"label": {
"en": "30S"
}
},
{
"id": "2",
"label": {
"en": "60S"
}
},
{
"id": "3",
"label": {
"en": "120S"
}
}
]
}
]
}
]
},
{
"id": "outdoor_2_socket",
"name": {
Expand Down
49 changes: 49 additions & 0 deletions drivers/motion_sensor_2_tuya_cluster/assets/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 112 additions & 0 deletions drivers/motion_sensor_2_tuya_cluster/device.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const TuyaSpecificCluster = require('../../lib/TuyaSpecificCluster');
const TuyaSpecificClusterDevice = require('../../lib/TuyaSpecificClusterDevice');
const { Cluster } = require('zigbee-clusters');

Cluster.addCluster(TuyaSpecificCluster);

const dataPoints = {
pir_state: 1,
battery_percentage: 4,
interval_time: 102,
pir_sensitivity: 9,
pir_time: 10,
illuminance_value: 12
}

const dataTypes = {
value: 2, // [ 4 byte value ]
enum: 4, // [ 0-255 ]
};

const getDataValue = (dpValue) => {
switch (dpValue.datatype) {
case dataTypes.value:
return parseInt(dpValue.data.toString('hex'), 16);
case dataTypes.enum:
return dpValue.data[0];
}
}

class motion_sensor_2_tuya_cluster extends TuyaSpecificClusterDevice {
async onNodeInit({ zclNode }) {
this.enableDebug();
this.printNode();

zclNode.endpoints[1].clusters[TuyaSpecificCluster.NAME]
.on('response', this.updateData.bind(this))
}

updateData(data) {
const value = getDataValue(data);
this.log(`DP: ${data.dp} - Value: ${value}`)
switch (data.dp) {
case dataPoints.pir_state:
const motion = value === 0
this.log(`Motion status: ${motion}`);
this.setCapabilityValue('alarm_motion', motion).catch(this.error);
break;
case dataPoints.illuminance_value:
this.log(`Illuminance: ${value}`);
this.setCapabilityValue('measure_luminance', value).catch(this.error);
break;
case dataPoints.battery_percentage:
const batteryThreshold = this.getSetting('batteryThreshold') || 20;
const batteryAlarm = value < batteryThreshold
this.log(`Battery: ${value}`);
this.setCapabilityValue('measure_battery', value).catch(this.error);
this.setCapabilityValue('alarm_battery', batteryAlarm).catch(this.error);
break;
case dataPoints.pir_sensitivity:
this.log(`PIR Sensitivity: ${value}`);
break;
case dataPoints.pir_time:
this.log(`PIR Time: ${value}`);
break;
default:
this.log(`Unrecognized DP: ${data.dp}`);
}
}

async onSettings({ newSettings, changedKeys }) {
if (changedKeys.includes('batteryThreshold')) {
const batteryThreshold = newSettings.batteryThreshold;
this.setBatteryThreshold(batteryThreshold);
}
if (changedKeys.includes('pirSensitivity')) {
const pirSensitivity = newSettings.pirSensitivity;
this.setPIRSensitivity(pirSensitivity);
}
if (changedKeys.includes('keepTime')) {
const keepTime = newSettings.keepTime;
this.setKeepTime(keepTime);
}
if (changedKeys.includes('intervalTime')) {
const intervalTime = newSettings.intervalTime;
this.setIntervalTime(intervalTime);
}
}

async setBatteryThreshold(batteryThreshold) {
this.log(`Setting Battery Threshold: ${batteryThreshold}`);
const battery = this.getCapabilityValue('measure_battery');
const batteryAlarm = battery < batteryThreshold;
this.setCapabilityValue('alarm_battery', batteryAlarm).catch(this.error);
}

async setPIRSensitivity(pirSensitivity) {
this.log(`Setting PIR Sensitivity: ${pirSensitivity}`);
this.writeEnum(dataPoints.pir_sensitivity, pirSensitivity).catch(this.error);
}

async setKeepTime(keepTime) {
this.log(`Setting Keep Time: ${keepTime}`);
this.writeEnum(dataPoints.pir_time, keepTime).catch(this.error);
}

async setIntervalTime(intervalTime) {
this.log(`Setting Interval Time: ${intervalTime}`);
this.writeEnum(dataPoints.interval_time, intervalTime).catch(this.error);
}
}

module.exports = motion_sensor_2_tuya_cluster;
38 changes: 38 additions & 0 deletions drivers/motion_sensor_2_tuya_cluster/driver.compose.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"id": "motion_sensor_2_tuya_cluster",
"name": {
"en": "Motion Sensor (Tuya Cluster)"
},
"class": "sensor",
"platforms": ["local"],
"connectivity": ["zigbee"],
"capabilities": [
"measure_battery",
"measure_luminance",
"alarm_motion",
"alarm_battery"
],
"energy": {
"batteries": ["CR2450"]
},
"images": {
"large": "{{driverAssetsPath}}/images/large.png",
"small": "{{driverAssetsPath}}/images/small.png"
},
"zigbee": {
"manufacturerName": ["_TZE200_3towulqd"],
"productId": ["TS0601"],
"endpoints": {
"1": {
"clusters": [0, 61184],
"bindings": [25, 10]
}
},
"learnmode": {
"image": "{{driverAssetsPath}}/icon.svg",
"instruction": {
"en": "Use a pin to press the reset button for aprox 5 seconds until the LED blinks."
}
}
}
}
Loading