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 @@
-
-
-
-
\ 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