rospogrigio / localtuya

local handling for Tuya devices
GNU General Public License v3.0
2.96k stars 563 forks source link

WIFI Temperature and humidity sensor (partial integration) #1790

Closed leto78 closed 1 month ago

leto78 commented 2 months ago

The problem

I have this unbranded WIFI only temperature and humidity sensor (no bluetooth). It is working fine with the Tuya cloud integration. I used the trick of removing the battery for 1 second so that the device would not go into deep sleep. With LocalTuya, I tried first to configure it without using the Tuya API but it was not detecting all the DPS when I tried to add the device. With the Tuya API configured, the LocalTuya was able to detect only 2 DPS, namely the temperature and humidity, but the secondary DPS were not detected. Adding the missing DPS to the configuration dialog did not work.

I added the temperature as a "sensor.temperature" with a scaling factor of 0.1, and I added humidity as "sensor.humidity" with a scaling factor of 1. The issue is that these sensors are only updated once in a while and for most of the time their status is "unavailable".

Environment

Steps to reproduce

  1. Configure Tuya API
  2. Remove battery of device for 1 second
  3. Add device
  4. Configure temperature ID:1 as "sensor.temperature" with scaling factor 0.1
  5. Configure humidity ID:2 as "sensor.humidity" with scaling factor 1.

History graph of temperature from LocalTuya Screenshot 2024-09-12 093757

History graph from Tuya Screenshot 2024-09-12 093629

Sensors in LocalTuya device Screenshot 2024-09-12 093713

Sensors in Tuya device Screenshot 2024-09-12 093546

DP dump

Only a few DP were detected.

Device **** at ***.***.***.**** key **** protocol 3.4 dev_type type_0d:
DPS [9] VALUE [c] 
DPS [10] VALUE [390] 
DPS [11] VALUE [0] 
DPS [12] VALUE [60]

Provide Home Assistant traceback/logs

LocalTuya json (personal data has been removed)

{
  "home_assistant": {
    "installation_type": "Home Assistant Container",
    "version": "2024.8.3",
    "dev": false,
    "hassio": false,
    "virtualenv": false,
    "python_version": "3.12.4",
    "docker": true,
    "arch": "x86_64",
    "timezone": "****",
    "os_name": "Linux",
    "os_version": "4.4.302+",
    "run_as_root": true
  },
  "custom_components": {
    "localtuya": {
      "documentation": "https://github.com/rospogrigio/localtuya/",
      "version": "5.2.1",
      "requirements": []
    },
    "hacs": {
      "documentation": "https://hacs.xyz/docs/configuration/start",
      "version": "2.0.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    }
  },
  "integration_manifest": {
    "domain": "localtuya",
    "name": "LocalTuya integration",
    "codeowners": [
      "rospogrigio",
      "postlund"
    ],
    "config_flow": true,
    "dependencies": [],
    "documentation": "https://github.com/rospogrigio/localtuya/",
    "iot_class": "local_push",
    "issue_tracker": "https://github.com/rospogrigio/localtuya/issues",
    "requirements": [],
    "version": "5.2.1",
    "is_built_in": false
  },
  "setup_times": {
    "null": {
      "setup": 0.014274568064138293
    },
    "01J6J96HAFDBTKE7V1Q0PMXE56": {
      "config_entry_setup": 1.0029681579908356
    }
  },
  "data": {
    "device_config": {
      "friendly_name": "WiFi Temperature & Humidity Sensor",
      "host": "***.***.***.***",
      "local_key": "****************",
      "protocol_version": "3.4",
      "enable_debug": false,
      "entities": [
        {
          "friendly_name": "Humidity",
          "unit_of_measurement": "%",
          "device_class": "humidity",
          "scaling": 1.0,
          "id": 2,
          "platform": "sensor"
        },
        {
          "id": 1,
          "friendly_name": "Temperature",
          "unit_of_measurement": "\u00baC",
          "device_class": "temperature",
          "scaling": 0.1,
          "platform": "sensor"
        }
      ],
      "add_entities": true,
      "scan_interval": 0,
      "model": "WiFi Temperature & Humidity Sensor",
      "device_id": "****",
      "dps_strings": [
        "1 (value: 271)",
        "2 (value: 43)"
      ],
      "product_key": "****"
    },
    "device_cloud_info": {
      "active_time": 1723371881,
      "biz_type": 18,
      "category": "wsdcg",
      "create_time": 1723292417,
      "icon": "smart/icon/ay15427647462366edzT/094edb77d25f8a721ccb524286bd5915.png",
      "id": "****",
      "ip": "***.***.***.***",
      "lat": "**.**",
      "local_key": "****************",
      "lon": "**.**",
      "model": "TH05",
      "name": "WiFi Temperature & Humidity Sensor",
      "online": true,
      "owner_id": "****",
      "product_id": "****",
      "product_name": "WiFi Temperature & Humidity Sensor",
      "status": [
        {
          "code": "va_temperature",
          "value": 262
        },
        {
          "code": "va_humidity",
          "value": 45
        },
        {
          "code": "battery_state",
          "value": "high"
        },
        {
          "code": "battery_percentage",
          "value": 99
        },
        {
          "code": "temp_unit_convert",
          "value": "c"
        },
        {
          "code": "maxtemp_set",
          "value": 390
        },
        {
          "code": "minitemp_set",
          "value": 0
        },
        {
          "code": "maxhum_set",
          "value": 60
        },
        {
          "code": "minihum_set",
          "value": 20
        },
        {
          "code": "temp_alarm",
          "value": "cancel"
        },
        {
          "code": "hum_alarm",
          "value": "cancel"
        },
        {
          "code": "temp_periodic_report",
          "value": 120
        },
        {
          "code": "hum_periodic_report",
          "value": 120
        },
        {
          "code": "temp_sensitivity",
          "value": 6
        },
        {
          "code": "hum_sensitivity",
          "value": 6
        }
      ],
      "sub": false,
      "time_zone": "****",
      "uid": "****",
      "update_time": 1726073773,
      "uuid": "****"
    }
  }
}

What is interesting from this debug information is that LocalTuya is able to obtain all the DP using the information provided by the Tuya API. This suggests that this device could have a full integration with LocalTuya.

Additional information

Official Tuya json (personal data has been removed)

{
  "home_assistant": {
    "installation_type": "Home Assistant Container",
    "version": "2024.8.3",
    "dev": false,
    "hassio": false,
    "virtualenv": false,
    "python_version": "3.12.4",
    "docker": true,
    "arch": "x86_64",
    "timezone": "****",
    "os_name": "Linux",
    "os_version": "4.4.302+",
    "run_as_root": true
  },
  "custom_components": {
    "localtuya": {
      "documentation": "https://github.com/rospogrigio/localtuya/",
      "version": "5.2.1",
      "requirements": []
    },
    "hacs": {
      "documentation": "https://hacs.xyz/docs/configuration/start",
      "version": "2.0.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    }
  },
  "integration_manifest": {
    "domain": "tuya",
    "name": "Tuya",
    "codeowners": [
      "Tuya",
      "zlinoliver",
      "frenck"
    ],
    "config_flow": true,
    "dependencies": [
      "ffmpeg"
    ],
    "dhcp": [
      {
        "macaddress": "105A17*"
      },
      {
        "macaddress": "10D561*"
      },
      {
        "macaddress": "1869D8*"
      },
      {
        "macaddress": "381F8D*"
      },
      {
        "macaddress": "508A06*"
      },
      {
        "macaddress": "68572D*"
      },
      {
        "macaddress": "708976*"
      },
      {
        "macaddress": "7CF666*"
      },
      {
        "macaddress": "84E342*"
      },
      {
        "macaddress": "D4A651*"
      },
      {
        "macaddress": "D81F12*"
      }
    ],
    "documentation": "https://www.home-assistant.io/integrations/tuya",
    "integration_type": "hub",
    "iot_class": "cloud_push",
    "loggers": [
      "tuya_iot"
    ],
    "requirements": [
      "tuya-device-sharing-sdk==0.1.9"
    ],
    "is_built_in": true
  },
  "setup_times": {
    "null": {
      "setup": 3.591296263039112e-05
    },
    "810ef75b522deae763a73c61f75b90c2": {
      "wait_import_platforms": -3.141211135080084,
      "wait_base_component": -0.0014348679687827826,
      "config_entry_setup": 3.592658736044541
    }
  },
  "data": {
    "endpoint": "https://apigw.tuyaeu.com",
    "terminal_id": "****",
    "mqtt_connected": true,
    "disabled_by": null,
    "disabled_polling": false,
    "id": "****",
    "name": "WiFi Temperature & Humidity Sensor",
    "category": "wsdcg",
    "product_id": "****",
    "product_name": "WiFi Temperature & Humidity Sensor",
    "online": true,
    "sub": false,
    "time_zone": "****",
    "active_time": "2024-08-11T10:24:41+00:00",
    "create_time": "2024-08-11T10:24:41+00:00",
    "update_time": "2024-08-11T10:24:41+00:00",
    "function": {
      "temp_unit_convert": {
        "type": "Enum",
        "value": {
          "range": [
            "c",
            "f"
          ]
        }
      },
      "maxtemp_set": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": -200,
          "max": 600,
          "scale": 1,
          "step": 1
        }
      },
      "minitemp_set": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": -200,
          "max": 600,
          "scale": 1,
          "step": 1
        }
      },
      "maxhum_set": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 0,
          "max": 100,
          "scale": 0,
          "step": 1
        }
      },
      "minihum_set": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 0,
          "max": 100,
          "scale": 0,
          "step": 1
        }
      },
      "temp_periodic_report": {
        "type": "Integer",
        "value": {
          "unit": "min",
          "min": 1,
          "max": 120,
          "scale": 0,
          "step": 1
        }
      },
      "hum_periodic_report": {
        "type": "Integer",
        "value": {
          "unit": "min",
          "min": 1,
          "max": 120,
          "scale": 0,
          "step": 1
        }
      },
      "temp_sensitivity": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": 3,
          "max": 20,
          "scale": 1,
          "step": 1
        }
      },
      "hum_sensitivity": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 3,
          "max": 20,
          "scale": 0,
          "step": 1
        }
      }
    },
    "status_range": {
      "va_temperature": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": -200,
          "max": 600,
          "scale": 1,
          "step": 1
        }
      },
      "va_humidity": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 0,
          "max": 100,
          "scale": 0,
          "step": 1
        }
      },
      "battery_state": {
        "type": "Enum",
        "value": {
          "range": [
            "low",
            "middle",
            "high"
          ]
        }
      },
      "battery_percentage": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 0,
          "max": 100,
          "scale": 0,
          "step": 1
        }
      },
      "temp_unit_convert": {
        "type": "Enum",
        "value": {
          "range": [
            "c",
            "f"
          ]
        }
      },
      "maxtemp_set": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": -200,
          "max": 600,
          "scale": 1,
          "step": 1
        }
      },
      "minitemp_set": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": -200,
          "max": 600,
          "scale": 1,
          "step": 1
        }
      },
      "maxhum_set": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 0,
          "max": 100,
          "scale": 0,
          "step": 1
        }
      },
      "minihum_set": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 0,
          "max": 100,
          "scale": 0,
          "step": 1
        }
      },
      "temp_alarm": {
        "type": "Enum",
        "value": {
          "range": [
            "loweralarm",
            "upperalarm",
            "cancel"
          ]
        }
      },
      "hum_alarm": {
        "type": "Enum",
        "value": {
          "range": [
            "loweralarm",
            "upperalarm",
            "cancel"
          ]
        }
      },
      "temp_periodic_report": {
        "type": "Integer",
        "value": {
          "unit": "min",
          "min": 1,
          "max": 120,
          "scale": 0,
          "step": 1
        }
      },
      "hum_periodic_report": {
        "type": "Integer",
        "value": {
          "unit": "min",
          "min": 1,
          "max": 120,
          "scale": 0,
          "step": 1
        }
      },
      "temp_sensitivity": {
        "type": "Integer",
        "value": {
          "unit": "\u2103",
          "min": 3,
          "max": 20,
          "scale": 1,
          "step": 1
        }
      },
      "hum_sensitivity": {
        "type": "Integer",
        "value": {
          "unit": "%",
          "min": 3,
          "max": 20,
          "scale": 0,
          "step": 1
        }
      }
    },
    "status": {
      "va_temperature": 241,
      "va_humidity": 44,
      "battery_state": "high",
      "battery_percentage": 99,
      "temp_unit_convert": "c",
      "maxtemp_set": 390,
      "minitemp_set": 0,
      "maxhum_set": 60,
      "minihum_set": 20,
      "temp_alarm": "cancel",
      "hum_alarm": "cancel",
      "temp_periodic_report": 120,
      "hum_periodic_report": 120,
      "temp_sensitivity": 6,
      "hum_sensitivity": 6
    },
    "home_assistant": {
      "name": "WiFi Temperature & Humidity Sensor",
      "name_by_user": null,
      "disabled": false,
      "disabled_by": null,
      "entities": [
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": null,
          "device_class": null,
          "original_device_class": "temperature",
          "icon": null,
          "original_icon": null,
          "unit_of_measurement": "\u00b0C",
          "state": {
            "entity_id": "sensor.wifi_temperature_humidity_sensor_temperature",
            "state": "24.1",
            "attributes": {
              "state_class": "measurement",
              "unit_of_measurement": "\u00b0C",
              "device_class": "temperature",
              "friendly_name": "WiFi Temperature & Humidity Sensor Temperature"
            },
            "last_changed": "2024-09-12T05:40:52.528884+00:00",
            "last_reported": "2024-09-12T05:40:52.532752+00:00",
            "last_updated": "2024-09-12T05:40:52.528884+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": null,
          "device_class": null,
          "original_device_class": "humidity",
          "icon": null,
          "original_icon": null,
          "unit_of_measurement": "%",
          "state": {
            "entity_id": "sensor.wifi_temperature_humidity_sensor_humidity",
            "state": "44.0",
            "attributes": {
              "state_class": "measurement",
              "unit_of_measurement": "%",
              "device_class": "humidity",
              "friendly_name": "WiFi Temperature & Humidity Sensor Humidity"
            },
            "last_changed": "2024-09-12T00:53:54.045938+00:00",
            "last_reported": "2024-09-12T05:40:52.532794+00:00",
            "last_updated": "2024-09-12T00:53:54.045938+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "diagnostic",
          "device_class": null,
          "original_device_class": "battery",
          "icon": null,
          "original_icon": null,
          "unit_of_measurement": "%",
          "state": {
            "entity_id": "sensor.wifi_temperature_humidity_sensor_battery",
            "state": "99.0",
            "attributes": {
              "state_class": "measurement",
              "unit_of_measurement": "%",
              "device_class": "battery",
              "friendly_name": "WiFi Temperature & Humidity Sensor Battery"
            },
            "last_changed": "2024-09-11T17:15:46.943478+00:00",
            "last_reported": "2024-09-12T05:40:52.532827+00:00",
            "last_updated": "2024-09-11T17:15:46.943478+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "diagnostic",
          "device_class": null,
          "original_device_class": null,
          "icon": null,
          "original_icon": null,
          "unit_of_measurement": null,
          "state": {
            "entity_id": "sensor.wifi_temperature_humidity_sensor_battery_state",
            "state": "high",
            "attributes": {
              "friendly_name": "WiFi Temperature & Humidity Sensor Battery state"
            },
            "last_changed": "2024-09-11T09:02:25.681503+00:00",
            "last_reported": "2024-09-11T09:40:50.808244+00:00",
            "last_updated": "2024-09-11T09:02:25.681503+00:00"
          }
        }
      ]
    },
    "set_up": true,
    "support_local": true
  }
}

This is the information regarding the DPS in the Tuya API:

Temperature: 1
Humidity: 2
Battery Level State: 3
Battery Level: 4
Unit convert: 9
Set maxtemp: 10
Set minitemp: 11
set maxhum: 12
temp alarm: 14
Humidity alarm: 15
Temperature report: 17
Humidity report: 18
Temperature sensitivity: 19
Humidity sensitivity: 20
RonVoormeeren commented 1 month ago

Same issue, love to see this solved.

leto78 commented 1 month ago

I am going to set this issue as closed. The battery is not integrated, but at least you can get the temperature and humidity data working. I added the following entries to the sensors.yaml.

  - platform: template
      mytemperature:
        unit_of_measurement: "\u00b0C"
        device_class: temperature
        friendly_name: MyTemperature
        unique_id: add280c3-d8bf-437d-93b5-b1b689c115de
        icon_template: >
          mdi:thermometer
        value_template: >
          {% set sensorstatus = states('sensor.temperature', 'raw_state') %}
          {% if  sensorstatus != 'unavailable'  %}
            {% set valuetokeep = sensorstatus %}
            {{ states('sensor.temperature', 'raw_state') | float }}
          {% else %}
            valuetokeep
          {% endif %}
      myhumidity:
        unit_of_measurement: "%"
        device_class: humidity
        friendly_name: MyHumidity
        unique_id: a88ac767-1881-42c5-bd6d-4c239361f933
        icon_template: >
          mdi:water-percent
        value_template: >
          {% set sensorstatus = states('sensor.humidity', 'raw_state') %}
          {% if  sensorstatus != 'unavailable'  %}
            {% set valuetokeep = sensorstatus %}
            {{ states('sensor.humidity', 'raw_state') | float }}
          {% else %}
            valuetokeep
          {% endif %}

The unique_id is required to be able to manage the entity in HomeAssistant. I just generated random ones. Do not use tabs when adding the code to sensors. Always use two spaces. Once you added the code, make sure it works properly before restarting, but going to Developer Tools > YAML > Check and Restart > Check Configuration.

Once you restarted, you need to get a data point before it has a valid value. You can remove and reinsert the battery to trigger an update. After that, it will keep the last value and track the history of the temperature and humidity.