Skip to content

Better Thermostat fails to control one specific TS0601 TZE200 #1674

@theyv

Description

@theyv

Description

Better Thermostat fails to control one specific TRV (Tuya Smart thermostat module), while three identical TRVs work correctly. The issue has two stages:

Stage 1 (initial problem):

  • TRV appears as active in BT
  • Temperature can be changed on BT card
  • BT entity state updates correctly
  • BUT: TRV doesn't respond to BT commands at all

Stage 2 (current state after multiple reinstallation attempts):

  • TRV can be added to BT successfully
  • BT entity immediately shows as "inactive" on the card
  • Cannot control anything from BT card
  • TRV continues to work perfectly via Zigbee2MQTT

Previous working state: All four identical TRVs worked correctly last winter. This winter, three still work but one refuses to work with BT.


Steps to Reproduce

Stage 1 - Initial behavior (first attempts):

  1. Add Tuya TRV (ZigBeeTS0601_TZE200_rxq4iti9) to Zigbee2MQTT - works correctly
  2. Add Better Thermostat integration for this TRV
  3. ✅ BT entity appears as active on the card
  4. Change temperature on BT entity (e.g., from 23°C to 10°C)
  5. BT entity state updates correctly in Developer Tools
  6. ❌ TRV does not respond - valve stays open, TRV's own temperature setting remains unchanged (e.g., stays at 22°C)
  7. ✅ Changing temperature directly in Z2MQTT or via climate.set_temperature service works immediately

Example:

  • Room temperature: 23°C
  • Set BT to 30°C: BT shows temperature: 30, hvac_action: heating, but TRV internal temperature stays at 22°C, valve doesn't open
  • Set BT to 10°C: BT shows temperature: 10, hvac_action: idle, but TRV internal temperature stays at 22°C, valve continues heating

Stage 2 - Current behavior (after multiple reinstallation attempts):

  1. Remove BT entity for this TRV
  2. Attempt to add Better Thermostat integration again
  3. ✅ TRV is visible in BT setup wizard
  4. ✅ Can select and configure the TRV
  5. ✅ BT entity is created
  6. ❌ BT entity immediately shows as "inactive" on the card
  7. ❌ Cannot change temperature or control anything from BT
  8. ✅ TRV still works perfectly via Z2MQTT

Note: After one "force delete" in Z2MQTT, BT worked correctly (Stage 1 behavior - active but not responding) for ~1 minute, then immediately went to "inactive" state and has remained inactive since.


Attempted fixes (all failed)

  • ❌ Removed and re-added TRV in Z2MQTT (5+ times, including force delete)
  • ❌ Removed external temperature sensors
  • ❌ Disabled all additional features (window detection, humidity sensor, etc.)
  • Completely uninstalled Better Thermostat via HACS and reinstalled from scratch
  • ❌ Deleted .storage/better_thermostat.* files (none found)
  • ❌ Removed TRV batteries and re-paired
  • ❌ Multiple Home Assistant restarts
  • ❌ Changed TRV friendly name in Z2MQTT
  • ❌ Tried simplest possible BT configuration (only TRV, no sensors, no calibration)

Expected behavior

  1. BT should successfully add the TRV
  2. BT entity should show as active on the card
  3. BT should send temperature commands to the TRV
  4. TRV should respond to BT commands (same as three other identical TRVs)

Actual behavior

Stage 1 (initial problem):

  • ✅ BT entity is active on the card
  • ✅ Temperature can be changed
  • ✅ BT entity state updates internally (visible in Developer Tools)
  • ❌ No commands are actually sent to the underlying climate entity
  • ❌ TRV completely ignores BT and continues with its own settings

Stage 2 (current state):

  • ✅ BT detects and adds the TRV successfully
  • ❌ BT entity shows as "inactive" immediately after adding
  • ❌ Cannot control anything from BT card
  • ❌ BT appears completely disconnected from the TRV
  • ✅ TRV still works perfectly via Z2MQTT throughout all of this

Versions and HW

  • Home Assistant: 2025.6.0 (Home Assistant OS 15.2)
  • Better Thermostat: 1.7.0 (completely reinstalled via HACS)
  • TRV: Tuya Smart thermostat module (ZigBeeTS0601_TZE200_rxq4iti9) via Zigbee2MQTT
  • Working TRVs: 3x identical model (ZigBeeTS0601_TZE200_rxq4iti9) - all work perfectly with BT
  • Non-working TRV: 1x identical model - only this one fails with BT
  • Zigbee2MQTT: Works perfectly for all 4 TRVs

Debug data

Diagnostic data (from Stage 1 when TRV was still "active" in BT)

{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2025.6.0",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.13.3",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/Warsaw",
    "os_name": "Linux",
    "os_version": "6.12.23-haos",
    "supervisor": "2025.10.0",
    "host_os": "Home Assistant OS 15.2",
    "docker_version": "28.0.4",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "better_thermostat": {
      "documentation": "https://github.com/KartoffelToby/better_thermostat",
      "version": "1.7.0",
      "requirements": []
    }
  },
  "data": {
    "info": {
      "name": "BetterThermostat - Salon04",
      "temperature_sensor": "sensor.thsensor_salon_temperature",
      "off_temperature": 20,
      "tolerance": 0.0,
      "target_temp_step": "0.0",
      "humidity_sensor": "sensor.thsensor_salon_humidity",
      "window_sensors": "binary_sensor.windowsensor_salon_contact",
      "window_off_delay": 5,
      "window_off_delay_after": 5,
      "outdoor_sensor": null,
      "weather": null,
      "cooler": null,
      "model": "Smart thermostat module"
    },
    "thermostat": {
      "climate.0xa4c138e0a08c2548": {
        "name": "0xa4c138e0a08c2548",
        "state": "heat",
        "attributes": {
          "hvac_modes": [
            "auto",
            "heat",
            "off"
          ],
          "min_temp": 5.0,
          "max_temp": 35.0,
          "target_temp_step": 1.0,
          "current_temperature": 24.0,
          "temperature": 11.0,
          "hvac_action": "idle",
          "friendly_name": "0xa4c138e0a08c2548",
          "supported_features": 385
        },
        "bt_config": {
          "calibration": "local_calibration_based",
          "calibration_mode": "heating_power_calibration",
          "protect_overheating": false,
          "no_off_system_mode": false,
          "heat_auto_swapped": false,
          "child_lock": false,
          "homematicip": false
        },
        "bt_adapter": "mqtt",
        "bt_integration": "mqtt",
        "model": "Smart thermostat module"
      }
    },
    "external_temperature_sensor": {
      "entity_id": "sensor.thsensor_salon_temperature",
      "state": "23.5"
    },
    "window_sensor": {
      "entity_id": "binary_sensor.windowsensor_salon_contact",
      "state": "off"
    }
  }
}

Debug log


Error during BT
 startup/initialization:
Rejestrator: homeassistant
Źródło: custom_components/better_thermostat/adapters/mqtt.py:47
integracja: Better Thermostat
Pierwsze zdarzenie: 15:56:47 (10 wystąpień)
Ostatnio zalogowany: 16:36:03

Error doing job: Task exception was never retrieved (None)

Traceback (most recent call last):
  File "/config/custom_components/better_thermostat/climate.py", line 826, in startup
    await init(self, trv)
  File "/config/custom_components/better_thermostat/adapters/delegate.py", line 44, in init
    return await self.real_trvs[entity_id]["adapter"].init(self, entity_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/better_thermostat/adapters/mqtt.py", line 47, in init
    ).state in (STATE_UNAVAILABLE, STATE_UNKNOWN, None):
      ^^^^^
AttributeError: 'NoneType' object has no attribute 'state'
Task destruction errors (repeated):
Rejestrator: homeassistant
Źródło: runner.py:112
Pierwsze zdarzenie: 11 października 2025 19:33:31 (16 wystąpień)
Ostatnio zalogowany: 16:30:21

Error doing job: Task was destroyed but it is pending! 
(<Task pending name='Task-105094' coro=<control_queue() running at /config/custom_components/better_thermostat/utils/controlling.py:61> wait_for=<Future pending cb=[Task.task_wakeup()]>>)

Error doing job: Task was destroyed but it is pending! 
(<Task pending name='Task-106869' coro=<window_queue() running at /config/custom_components/better_thermostat/events/window.py:78> wait_for=<Future pending cb=[Task.task_wakeup()]>>)

Error doing job: Task was destroyed but it is pending! 
(<Task pending name='Task-106868' coro=<control_queue() running at /config/custom_components/better_thermostat/utils/controlling.py:61> wait_for=<Future pending cb=[Task.task_wakeup()]>>)

Additional Information

✅ climate.heater_salon (or climate.0xa4c138e0a08c2548) exists in Developer Tools → States
✅ Entity is available and shows correct state
✅ Entity responds to climate.set_temperature service immediately
✅ Entity is listed in BT setup wizard and can be added
❌ After adding to BT, entity shows as "inactive" on card (Stage 2)
❌ BT doesn't send any commands to this entity

Storage/cache check:

No better_thermostat.* files found in /config/.storage/ directory
Clean reinstallation via HACS didn't help
Multiple HA restarts didn't help

Key observations:

  • The TRV worked with BT last winter - this is not a compatibility issue
  • Three identical TRVs work perfectly - BT works fine with this model in general
  • Only one specific TRV fails - suggests individual device/pairing issue
  • Problem progression: Active but not responding → Inactive after multiple reinstallation attempts
  • Brief success after force delete - BT worked for ~1 minute (Stage 1 behavior), then went inactive
  • Z2MQTT always works - the TRV itself is functional throughout all tests

Technical suspicions:

The AttributeError: 'NoneType' in mqtt.py:47 suggests BT's MQTT adapter fails to properly initialize this specific TRV

  • BT might be attempting to read a state/attribute that doesn't exist or is malformed for this particular device instance
  • The progression from "active but not responding" to "inactive" suggests BT is blacklisting or marking this TRV as problematic after failed initialization attempts
  • The control_queue() and window_queue() pending task errors indicate BT's internal queues are not being properly shut down, possibly leaving corrupted state
  • Critical question: Why does BT treat this TRV differently when its climate entity behaves identically to the other three working TRVs?

Questions for developers:

  • Where does BT cache or store device-specific initialization state if not in .storage/better_thermostat.*?
  • Could there be a race condition in MQTT adapter initialization that only affects this specific device?
  • Is there internal blacklisting/failure tracking that could cause BT to mark a device as inactive after repeated initialization failures?
  • Why would mqtt.py:47 get NoneType for one TRV when the climate entity clearly exists and works via services?
  • Is there a way to enable more verbose MQTT adapter logging to see what's different about this TRV's initialization?

Metadata

Metadata

Assignees

Labels

new bugincoming bug issue

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions