diff --git a/drivers/radar_sensor/assets/icon.svg b/drivers/radar_sensor/assets/icon.svg index 6b782cde74..21dca2e848 100644 --- a/drivers/radar_sensor/assets/icon.svg +++ b/drivers/radar_sensor/assets/icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/drivers/smoke_temp_humid_sensor/assets/icon.svg b/drivers/smoke_temp_humid_sensor/assets/icon.svg new file mode 100644 index 0000000000..a73c95942e --- /dev/null +++ b/drivers/smoke_temp_humid_sensor/assets/icon.svg @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/drivers/smoke_temp_humid_sensor/assets/images/large.png b/drivers/smoke_temp_humid_sensor/assets/images/large.png new file mode 100644 index 0000000000..58e2e661ed Binary files /dev/null and b/drivers/smoke_temp_humid_sensor/assets/images/large.png differ diff --git a/drivers/smoke_temp_humid_sensor/assets/images/small.png b/drivers/smoke_temp_humid_sensor/assets/images/small.png new file mode 100644 index 0000000000..d31bf8ed3e Binary files /dev/null and b/drivers/smoke_temp_humid_sensor/assets/images/small.png differ diff --git a/drivers/smoke_temp_humid_sensor/device.js b/drivers/smoke_temp_humid_sensor/device.js new file mode 100644 index 0000000000..3817a1be9c --- /dev/null +++ b/drivers/smoke_temp_humid_sensor/device.js @@ -0,0 +1,132 @@ +'use strict'; + +const {Cluster} = require('zigbee-clusters'); +const TuyaSpecificCluster = require('../../lib/TuyaSpecificCluster'); +const TuyaSpecificClusterDevice = require('../../lib/TuyaSpecificClusterDevice'); +const { V1_SMOKE_DATA_POINTS } = require('../../lib/TuyaDataPoints'); + +Cluster.addCluster(TuyaSpecificCluster); + +const dataPoints = { + tsSmokeAlarm: V1_SMOKE_DATA_POINTS.smokeAlarm, // 0=Smoke Alarm On, 1=Smoke Alarm Off + tsTamperAlert: 4, // not used in this version + tsBatteryState: V1_SMOKE_DATA_POINTS.batteryState, // dp14 0=20% 1=50% 2=90% [dp=14] battery low value 2 (FULL) + tsTemperature: V1_SMOKE_DATA_POINTS.temperature, //*10 + tsHumidity: V1_SMOKE_DATA_POINTS.humidity // % + } + +const dataTypes = { + raw: 0, // [ bytes ] + bool: 1, // [0/1] + value: 2, // [ 4 byte value ] + string: 3, // [ N byte string ] + enum: 4, // [ 0-255 ] + bitmap: 5, // [ 1,2,4 bytes ] as bits +}; + +const convertMultiByteNumberPayloadToSingleDecimalNumber = (chunks) => { + let value = 0; + + for (let i = 0; i < chunks.length; i++) { + value = value << 8; + value += chunks[i]; + } + + return value; +}; + +const getDataValue = (dpValue) => { + switch (dpValue.datatype) { + case dataTypes.raw: + return dpValue.data; + case dataTypes.bool: + return dpValue.data[0] === 1; + case dataTypes.value: + return convertMultiByteNumberPayloadToSingleDecimalNumber(dpValue.data); + case dataTypes.string: + let dataString = ''; + for (let i = 0; i < dpValue.data.length; ++i) { + dataString += String.fromCharCode(dpValue.data[i]); + } + return dataString; + case dataTypes.enum: + return dpValue.data[0]; + case dataTypes.bitmap: + return convertMultiByteNumberPayloadToSingleDecimalNumber(dpValue.data); + } +} + +class smoke_temp_humid extends TuyaSpecificClusterDevice { + async onNodeInit({zclNode}) { + + this.printNode(); + + this.addCapability("measure_temperature"); + this.addCapability("measure_humidity"); + this.addCapability("measure_battery"); + + zclNode.endpoints[1].clusters.tuya.on("response", value => this.updatePosition(value)); + } + + async updatePosition(data) { + const dp = data.dp; + const value = getDataValue(data); + switch (dp) { + case dataPoints.tsSmokeAlarm: + this.log("present state: "+ value); + var smokeAlarm = value === 0 ? true : false; + this.setCapabilityValue('alarm_smoke', Boolean(smokeAlarm)).catch(this.error); + break; + + case dataPoints.tsTamperAlert: + this.setCapabilityValue('alarm_tamper', Boolean(value)).catch(this.error); + break; + + case dataPoints.tsBatteryState: + + switch (value) { + case 0: + var batteryPerc = 20; + var batAlarm = value === 0 ? true : false; + this.log("measure_battery | powerConfiguration - batteryPercentageRemaining (%): ", batteryPerc); + this.setCapabilityValue('alarm_battery', batAlarm).catch(this.error); + case 1: + var batteryPerc = 50; + this.log("measure_battery | powerConfiguration - batteryPercentageRemaining (%): ", batteryPerc); + case 2: + var batteryPerc = 90; + this.log("measure_battery | powerConfiguration - batteryPercentageRemaining (%): ", batteryPerc); + break; + } + + this.setCapabilityValue('measure_battery', batteryPerc).catch(this.error); + + break; + + case dataPoints.tsTemperature: // Temperature ( x10 ) + const temperatureOffset = this.getSetting('temperature_offset') || 0; + + this.log('Meaured Temperature is ', (value / 10.0), ' C (', value, ')'); + this.setCapabilityValue('measure_temperature',value / 10.0 + temperatureOffset).catch(this.error); + break; + + case dataPoints.tsHumidity: // Humidity Level + const humidityOffset = this.getSetting('humidity_offset') || 0; + + this.log('Mearured Humidity Level is ', value, ' %RH (', value, ')'); + this.setCapabilityValue('measure_humidity',value + humidityOffset).catch(this.error); + break; + + default: + this.log('dp value', dp, value) + } + } + + onDeleted() { + this.log("Smoke sensor removed") + } + +} + +module.exports = smoke_temp_humid; + diff --git a/drivers/smoke_temp_humid_sensor/driver.compose.json b/drivers/smoke_temp_humid_sensor/driver.compose.json new file mode 100644 index 0000000000..f97dd40eed --- /dev/null +++ b/drivers/smoke_temp_humid_sensor/driver.compose.json @@ -0,0 +1,44 @@ +{ + "id": "smoke_temp_humid", + "name": { + "en": "Smoke Temp Humid Sensor" + }, + "class": "sensor", + "platforms": ["local"], + "connectivity": ["zigbee"], + "capabilities": [ + "measure_battery", + "alarm_smoke", + "alarm_battery", + "measure_humidity", + "measure_temperature" + ], + "energy": { + "batteries": ["AAA","AAA"] + }, + "images": { + "large": "{{driverAssetsPath}}/images/large.png", + "small": "{{driverAssetsPath}}/images/small.png" + }, + "zigbee": { + "manufacturerName": [ + "_TZE284_gyzlwu5q" + ], + "productId": [ + "TS0601" + ], + "endpoints": { + "1": { + "clusters": [0, 4, 5, 61184, 60672], + "bindings": [4, 5, 61184] + } + }, + "learnmode": { + "image": "{{driverAssetsPath}}/icon.svg", + "instruction": { + "en": "Press the coms-button for 5 seconds until LED blinks." + } + } + } + +} diff --git a/drivers/smoke_temp_humid_sensor/driver.settings.compose.json b/drivers/smoke_temp_humid_sensor/driver.settings.compose.json new file mode 100644 index 0000000000..c0aa70e812 --- /dev/null +++ b/drivers/smoke_temp_humid_sensor/driver.settings.compose.json @@ -0,0 +1,45 @@ +[ + { + "id": "temperature_offset", + "type": "number", + "label": { + "en": "Temperature offset (°C)", + "nl": "Temperatuur correctie (°C)", + "it": "Offset della temperatura (°C)" + }, + "hint": { + "en": "Set a value to compensate a temperature offset.\nRange: -10 - 10, step size 0.1, \ndefault: 0 [°C]", + "nl": "Stel een correctiewaarde in voor de temperatuur.\nBereik: -10 - 10, stap grootte 0.1, \nstandaard: 0 [°C]", + "it": "Imposta un valore per compensare lo scostamento della temperatura.\nRange: -10 - 10, step ze 0.1, \ndefault: 0 [°C]", + "sv": "Ange ett värde för att korrigera felaktig temperatur.\nIntervall: -10 - 10, steg om 0.1, \nstandard: 0 [°C]" + }, + "value": 0, + "attr": { + "min": -10, + "max": 10, + "step": 0.1 + } + }, + { + "id": "humidity_offset", + "type": "number", + "label": { + "en": "Humidity offset (%)", + "nl": "Luchtvochtigheids compensatie (%)", + "it": "Offset dell'umidità (%)", + "sv": "Fuktighetskorrigering (%)" + }, + "hint": { + "en": "Set a correction to compensate a humidity offset.\nRange: -10 - 10, step size 1, \ndefault: 0 [%]", + "nl": "Stel een correctiewaarde in om een Luchtvochtigheids verschil te compenseren.\nBereik: -10 - 10, stap grootte 1, \nstandaard: 0 [%]", + "it": "Imposta un valore per compensare lo scostamento dell'umidità.\nRange: -10 - 10, step size 1, \ndefault: 0 [%]", + "sv":"Ange ett värde för att korrigera felaktig fuktighet.\nIntervall: -10 - 10, steg om 1, \nstandard: 0 [%]" + }, + "value": 0, + "attr": { + "min": -10, + "max": 10, + "step": 1 + } + } +] \ No newline at end of file diff --git a/drivers/tuya_dummy_device/assets/icon.svg b/drivers/tuya_dummy_device/assets/icon.svg deleted file mode 100644 index 8f2ff5d25c..0000000000 --- a/drivers/tuya_dummy_device/assets/icon.svg +++ /dev/null @@ -1,115 +0,0 @@ - - - -image/svg+xml - - - - \ No newline at end of file diff --git a/drivers/tuya_dummy_device/assets/images/large.png b/drivers/tuya_dummy_device/assets/images/large.png deleted file mode 100644 index d7c498d64b..0000000000 Binary files a/drivers/tuya_dummy_device/assets/images/large.png and /dev/null differ diff --git a/drivers/tuya_dummy_device/assets/images/small.png b/drivers/tuya_dummy_device/assets/images/small.png deleted file mode 100644 index b64b85462c..0000000000 Binary files a/drivers/tuya_dummy_device/assets/images/small.png and /dev/null differ diff --git a/drivers/tuya_dummy_device/device.js b/drivers/tuya_dummy_device/device.js deleted file mode 100644 index 006d98bf24..0000000000 --- a/drivers/tuya_dummy_device/device.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict'; - -const { debug, Cluster } = require('zigbee-clusters'); -const TuyaSpecificCluster = require('../../lib/TuyaSpecificCluster'); - -// Add custom cluster handling for Tuya-specific messages -Cluster.addCluster(TuyaSpecificCluster); - -class TuyaDiagnosticDevice extends require('homey-zigbeedriver').ZigBeeDevice { - - async onNodeInit({ zclNode }) { - this.printNode(); -/* debug(true); - this.enableDebug(); */ - - // Attach event listeners to log incoming data from Tuya clusters - zclNode.endpoints[1].clusters.tuya.on("reporting", async (value) => { - await this.processDatapoint(value); - }); - - zclNode.endpoints[1].clusters.tuya.on("response", async (value) => { - await this.processDatapoint(value); - }); - } - - async processDatapoint(data) { - const dp = data.dp; - const dataType = data.datatype; - let parsedValue; - - // Parse the datapoint value based on the Tuya data types - switch (dataType) { - case 0: // Raw data - parsedValue = data.data.toString('hex'); - break; - case 1: // Boolean - parsedValue = data.data.readUInt8(0); - break; - case 2: // 4-byte value - parsedValue = data.data.readUInt32BE(0); - break; - case 3: // String - parsedValue = data.data.toString('utf8'); - break; - case 4: // Enum - parsedValue = data.data.readUInt8(0); - break; - case 5: // Bitmap - parsedValue = data.data.length === 1 ? data.data.readUInt8(0) : - data.data.length === 2 ? data.data.readUInt16BE(0) : - data.data.readUInt32BE(0); - break; - default: - parsedValue = data.data.toString('hex'); // Default raw value - } - - // Log the processed datapoint - this.log(`DP ${dp}, Data Type: ${dataType}, Parsed Value:`, parsedValue); - - } - - onDeleted() { - this.log('Tuya Diagnostic Device removed'); - } -} - -module.exports = TuyaDiagnosticDevice; diff --git a/drivers/tuya_dummy_device/driver.compose.json b/drivers/tuya_dummy_device/driver.compose.json deleted file mode 100644 index 5d627c4c63..0000000000 --- a/drivers/tuya_dummy_device/driver.compose.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "id": "tuya_dummy_driver", - "name": { - "en": "Tuya Diagnostic Driver" - }, - "class": "sensor", - "platforms": ["local"], - "connectivity": ["zigbee"], - "capabilities": [], - "images": { - "large": "{{driverAssetsPath}}/images/large.png", - "small": "{{driverAssetsPath}}/images/small.png" - }, - "zigbee": { - "manufacturerName": [ - "_TZE20X_xxxxxxxx" - ], - "productId": [ - "TS0601" - ], - "endpoints": { - "1": { - "clusters": [0, 61184], - "bindings": [61184] - } - } - }, - "learnmode": { - "instruction": { - "en": "This driver will log all incoming Tuya datapoints. Please share diagnostic reports for analysis." - } - } - } - \ No newline at end of file diff --git a/drivers/tuya_dummy_device/driver.js b/drivers/tuya_dummy_device/driver.js deleted file mode 100644 index 90fb31ddb9..0000000000 --- a/drivers/tuya_dummy_device/driver.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; -const { ZigBeeDriver } = require('homey-zigbeedriver'); - -class TuyaDiagnosticDriver extends ZigBeeDriver { - -} - -module.exports = TuyaDiagnosticDriver; diff --git a/lib/TuyaDataPoints.js b/lib/TuyaDataPoints.js index 03b7419892..03d2149ff5 100644 --- a/lib/TuyaDataPoints.js +++ b/lib/TuyaDataPoints.js @@ -212,7 +212,9 @@ const V1_SIREN_TEMPHUMID_SENSOR_DATA_POINTS = { const V1_SMOKE_DATA_POINTS = { smokeAlarm: 1, // 0=Smoke Alarm On, 1=Smoke Alarm Off tamperAlert: 4, - batteryState: 14 // dp14 0=20% 1=50% 2=90% [dp=14] battery low, value 2 (FULL) + batteryState: 14, // dp14 0=20% 1=50% 2=90% [dp=14] battery low, value 2 (FULL) + temperature: 23, + humidity: 24 }; // Data points for Soil Sensor devices, version 1