make-all / tuya-local

Local support for Tuya devices in Home Assistant
MIT License
1.42k stars 544 forks source link

Certain Devices goes Unavailable indefinetly with wierd reconnection issues #1804

Open remlei opened 7 months ago

remlei commented 7 months ago

Describe the bug When a device sensors and switches goes Unavailable, tuya local seems to re-connect to the device with weird reconnection issue. First the device seems to get reconnected but a few seconds later, it goes to Unavailable again, this thing happens several times per minute. Tried debugging it if its a networking related issue but no, the AP sees the device still connected and able to ping the device just fine.

The only way to fix this issue is "reload" the device by going to Settings > Device & Services > Tuya Local > Your Device, after that click the 3 dot thingy beside the problematic device and click reload. Take note, even power cycling the device doesnt fix the issue more like it actually gets worse since it no longer able to reconnect to the device, unlike before it was able to connect to the device albeit it only last for a few seconds.

Currently the device is disconnected to the internet, making the device unblocked to the internet make no difference. No other smartphone app that can directly control the device, the only way to control this device is through home assistant, I only run the tuya app if I want to add a new device to my tuya account but after that the smart app gets deleted.

To Reproduce Unknown, The issue happens randomly.

Expected behavior If the device gets disconnected, local tuya should be able to reconnect to device without any issue.

Additional context

Device Diagnostic

{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2024.3.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.12.2",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Asia/Manila",
    "os_name": "Linux",
    "os_version": "6.6.20-haos",
    "supervisor": "2024.03.1",
    "host_os": "Home Assistant OS 12.1",
    "docker_version": "24.0.7",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "tuya_local": {
      "version": "2024.3.2",
      "requirements": [
        "tinytuya==1.13.2"
      ]
    },
    "pfsense": {
      "version": "0.1.0",
      "requirements": [
        "mac-vendor-lookup>=0.1.11"
      ]
    },
    "localtuya": {
      "version": "5.2.1",
      "requirements": []
    },
    "proxmoxve": {
      "version": "3.4.1",
      "requirements": [
        "proxmoxer==2.0.1"
      ]
    },
    "tplink_easy_smart": {
      "version": "0.3.0",
      "requirements": [
        "json5==0.9.10"
      ]
    },
    "openmediavault": {
      "version": "0.0.0",
      "requirements": []
    },
    "ssh_command": {
      "version": "1.0.0",
      "requirements": [
        "paramiko"
      ]
    },
    "hacs": {
      "version": "1.34.0",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    }
  },
  "integration_manifest": {
    "domain": "tuya_local",
    "name": "Tuya Local",
    "codeowners": [
      "@make-all"
    ],
    "config_flow": true,
    "dependencies": [],
    "documentation": "https://github.com/make-all/tuya-local",
    "integration_type": "device",
    "iot_class": "local_push",
    "issue_tracker": "https://github.com/make-all/tuya-local/issues",
    "requirements": [
      "tinytuya==1.13.2"
    ],
    "version": "2024.3.2",
    "is_built_in": false
  },
  "data": {
    "name": "Aircon Smartplug",
    "type": "blitzwolf_bwshp6_smartplug",
    "device_id": "**REDACTED**",
    "device_cid": "",
    "local_key": "**REDACTED**",
    "host": "**REDACTED**",
    "protocol_version": 3.4,
    "tinytuya_version": "1.13.2",
    "api_version_set": 3.4,
    "api_version_used": 3.4,
    "api_working": true,
    "status": {},
    "cached_state": {
      "updated_at": 1712534268.9972293,
      "1": true,
      "9": 0,
      "18": 2969,
      "19": 6890,
      "20": 2366,
      "21": 2,
      "26": 0,
      "38": "memory",
      "39": "relay",
      "40": false,
      "41": "",
      "42": "",
      "43": ""
    },
    "pending_state": {},
    "connected": true,
    "force_dps": [
      18,
      19,
      20
    ],
    "home_assistant": {
      "name": "Aircon Smartplug",
      "name_by_user": null,
      "disabled": false,
      "disabled_by": null,
      "entities": [
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "config",
          "device_class": null,
          "original_device_class": null,
          "icon": null,
          "unit_of_measurement": "min",
          "state": {
            "entity_id": "number.aircon_smartplug_timer",
            "state": "0.0",
            "attributes": {
              "min": 0.0,
              "max": 1440.0,
              "step": 1.0,
              "mode": "auto",
              "unit_of_measurement": "min",
              "friendly_name": "Aircon Smartplug Timer"
            },
            "last_changed": "2024-04-07T21:31:48.926583+00:00",
            "last_updated": "2024-04-07T21:31:48.926583+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "config",
          "device_class": null,
          "original_device_class": null,
          "icon": null,
          "unit_of_measurement": null,
          "state": {
            "entity_id": "lock.aircon_smartplug_child_lock",
            "state": "unlocked",
            "attributes": {
              "friendly_name": "Aircon Smartplug Child lock",
              "supported_features": 0
            },
            "last_changed": "2024-04-07T21:32:20.088727+00:00",
            "last_updated": "2024-04-07T21:32:20.088727+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "config",
          "device_class": null,
          "original_device_class": null,
          "icon": null,
          "unit_of_measurement": null,
          "state": {
            "entity_id": "select.aircon_smartplug_initial_state",
            "state": "Last state",
            "attributes": {
              "options": [
                "On",
                "Off",
                "Last state"
              ],
              "icon": "mdi:toggle-switch",
              "friendly_name": "Aircon Smartplug Initial state"
            },
            "last_changed": "2024-04-07T21:32:20.090149+00:00",
            "last_updated": "2024-04-07T21:32:20.090149+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "config",
          "device_class": null,
          "original_device_class": null,
          "icon": null,
          "unit_of_measurement": null,
          "state": {
            "entity_id": "select.aircon_smartplug_light_mode",
            "state": "State",
            "attributes": {
              "options": [
                "State",
                "Position",
                "Off"
              ],
              "icon": "mdi:lightbulb",
              "friendly_name": "Aircon Smartplug Light mode"
            },
            "last_changed": "2024-04-07T21:32:20.090632+00:00",
            "last_updated": "2024-04-07T21:32:20.090632+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "diagnostic",
          "device_class": null,
          "original_device_class": null,
          "icon": null,
          "unit_of_measurement": "Wh",
          "state": {
            "entity_id": "sensor.aircon_smartplug_energy",
            "state": "unknown",
            "attributes": {
              "unit_of_measurement": "Wh",
              "friendly_name": "Aircon Smartplug Energy"
            },
            "last_changed": "2024-04-07T21:31:48.929163+00:00",
            "last_updated": "2024-04-07T21:31:48.929163+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "diagnostic",
          "device_class": null,
          "original_device_class": "current",
          "icon": null,
          "unit_of_measurement": "mA",
          "state": {
            "entity_id": "sensor.aircon_smartplug_current",
            "state": "2969",
            "attributes": {
              "state_class": "measurement",
              "unit_of_measurement": "mA",
              "device_class": "current",
              "friendly_name": "Aircon Smartplug Current"
            },
            "last_changed": "2024-04-07T23:57:17.938697+00:00",
            "last_updated": "2024-04-07T23:57:17.938697+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "diagnostic",
          "device_class": null,
          "original_device_class": "power",
          "icon": null,
          "unit_of_measurement": "W",
          "state": {
            "entity_id": "sensor.aircon_smartplug_power",
            "state": "689.0",
            "attributes": {
              "state_class": "measurement",
              "unit_of_measurement": "W",
              "device_class": "power",
              "friendly_name": "Aircon Smartplug Power"
            },
            "last_changed": "2024-04-07T23:57:17.939754+00:00",
            "last_updated": "2024-04-07T23:57:17.939754+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": "diagnostic",
          "device_class": null,
          "original_device_class": "voltage",
          "icon": null,
          "unit_of_measurement": "V",
          "state": {
            "entity_id": "sensor.aircon_smartplug_voltage",
            "state": "236.6",
            "attributes": {
              "state_class": "measurement",
              "unit_of_measurement": "V",
              "device_class": "voltage",
              "friendly_name": "Aircon Smartplug Voltage"
            },
            "last_changed": "2024-04-07T23:57:17.940670+00:00",
            "last_updated": "2024-04-07T23:57:17.940670+00:00"
          }
        },
        {
          "disabled": false,
          "disabled_by": null,
          "entity_category": null,
          "device_class": null,
          "original_device_class": "outlet",
          "icon": "mdi:air-conditioner",
          "unit_of_measurement": null,
          "state": {
            "entity_id": "switch.aircon_smartplug_none",
            "state": "on",
            "attributes": {
              "factory_test": 2,
              "cycle_time": "",
              "random_time": "",
              "inching": "",
              "device_class": "outlet",
              "icon": "mdi:air-conditioner",
              "friendly_name": "Aircon Smartplug None"
            },
            "last_changed": "2024-04-07T21:36:59.650857+00:00",
            "last_updated": "2024-04-07T21:36:59.650857+00:00"
          }
        }
      ]
    }
  }
}

Home Assistant Log related to the issue

This error originated from a custom integration.

Logger: custom_components.tuya_local.device
Source: custom_components/tuya_local/device.py:554
integration: Tuya Local (documentation, issues)
First occurred: 12:29:35 AM (70 occurrences)
Last logged: 5:31:37 AM

Failed to update device dps for Aircon Smartplug
Failed to fetch device status for Aircon Smartplug

Workaround:

Create a new automation based on device state, if the device goes unavailable, do a call service integration reload on specific problematic device.

make-all commented 7 months ago

Possibly related to this upstream bug: https://github.com/jasonacox/tinytuya/issues/472

robinhood-code commented 7 months ago

this happens to me every time when I turn off the power of the device (lights) and then turn it back on, and I will have to reload the entry for the device otherwise TL would not be able to reconnect to the device.

make-all commented 7 months ago

Have you set the IP address and protocol version?

robinhood-code commented 7 months ago

yup, both are set manually and not auto. I will observe more to see if it’s specific to certain protocol version or device

sweetpants commented 6 months ago

For what it's worth. In my situation it happens when the device is known/configured and worked in tuya-local but becomes unreachable. When disabeling this device in tuya-local, everything seems to return to 'nomal'' and my GUI is responsive again.

tabascoz commented 6 months ago

hi, having the same issues with three of my heatpumps. will implement a reload fix automation, happy to test / debug a fix, thanks

array81 commented 6 months ago

I think I have a similar problem with Tongou TO-Q-SY1-JWT. As long as it has an active load it doesn't seem to have a problem but when I remove the load (sometimes) the device becomes unavailable. @remlei could you post your automation code to reload the integration? Thanks

remlei commented 5 months ago

I think I have a similar problem with Tongou TO-Q-SY1-JWT. As long as it has an active load it doesn't seem to have a problem but when I remove the load (sometimes) the device becomes unavailable. @remlei could you post your automation code to reload the integration? Thanks

just use the Call Service "Home Assistant Core Integration: Reload config entry" and choose for Device as a target and look for a tuya device that your having problem with.

as for trigger, you can use any part of that tuya device that goes unavailable, in this case I used the "child lock" entity of the device as a trigger, if the state goes unavailable or unknown, execute a reload config call service action.

felipecrs commented 5 months ago

Just to mention, when the device goes unavailable in Tuya Local:

  1. The official Tuya (cloud) integration can control the device just fine
  2. Tuya Smart app can control the device just fine
  3. I can ping the device just fine using tinytuya wizard
felipecrs commented 5 months ago

I am currently working around this issue by using an entity template and adding redundancy (use Tuya Local if it's available, or use Tuya Cloud otherwise):

cover:
  - platform: template
    covers:
      terreiro:
        unique_id: 2c82abec-5be3-40a2-b8aa-76cbe9b067f8
        friendly_name: Terreiro
        device_class: garage
        value_template: "{{ (not is_state('cover.terreiro_tuya_local', 'unavailable') and not is_state('cover.terreiro_tuya_local', 'closed')) or (not is_state('cover.terreiro_tuya_cloud', 'unavailable') and not is_state('cover.terreiro_tuya_cloud', 'closed')) }}"
        availability_template: "{{ not is_state('cover.terreiro_tuya_local', 'unavailable') or not is_state('cover.terreiro_tuya_cloud', 'unavailable') }}"
        open_cover:
          if:
            - condition: template
              value_template: "{{ not is_state('cover.terreiro_tuya_local', 'unavailable') }}"
          then:
            - service: cover.toggle
              target:
                entity_id: cover.terreiro_tuya_local
          else:
            - service: cover.toggle
              target:
                entity_id: cover.terreiro_tuya_cloud
        close_cover:
          if:
            - condition: template
              value_template: "{{ not is_state('cover.terreiro', 'closed') }}"
          then:
            - if:
                - condition: template
                  value_template: "{{ not is_state('cover.terreiro_tuya_local', 'unavailable') }}"
              then:
                - service: cover.toggle
                  target:
                    entity_id: cover.terreiro_tuya_local
              else:
                - service: cover.toggle
                  target:
                    entity_id: cover.terreiro_tuya_cloud
sophof commented 2 months ago

This bug appears to be more extreme for me as time goes by (or I'm just having a string of bad luck). On top of that, I just ran into an issue that's stopping me from reloading the integration? The error I get when doing the service call is receive loop has terminated. It does come back by itself after a while too, so the whole thing is mystifying.

make-all commented 2 months ago

The receive loop terminates when you reload the integration, it is normal, and shows that the reload is working.

felipecrs commented 3 weeks ago

@make-all, I'm very excited about https://github.com/make-all/tuya-local/commit/3fafb5fee239dbdd849f6b99248ebf88290609e8. I have reverted my workaround and I am now testing it. Let's see how the following days goes.

felipecrs commented 1 week ago

@make-all, unfortunately, after working perfectly well for over a week, I noticed this issue again.

  1. Restarting HA brought two devices back
  2. For the last one, clicking in CONFIGURE without changing any parameter and submitting it, brought it back.

This makes me think if the integration itself isn't retrying the connection properly.

Do you think I should open a different issue or should this one be reopened?

felipecrs commented 1 week ago

I just realized I should have tried to capture some logs. I will try next time.

felipecrs commented 1 week ago

Ok, I have a better story to tell now:

  1. The device went unavailable when I powered it off (a smart garage door opener)
  2. When powering it on again, it never came back in Tuya Local
  3. Stayed that way for hours
  4. I tried to Reload the Tuya Local integration, nothing changed
  5. Tried Re-CONFIGURE the device in Tuya Local, it gave me connection error. I captured the logs.
  6. I opened the Tuya app; the device was online. I opened the garage door once from the Tuya app: the device came back in Home Assistant.

Weird. I captured debug logs during the Reload and Re-CONFIGURE, but I'm not sure it will help.

tuya_local_bbb18cee736636978b25f07001002a50_Portão_da_garagem_de.json

home-assistant_tuya_local_2024-11-18T01-21-00.547Z.log

dominguesgm commented 20 hours ago

Just ran into either this or a similar issue. I have a large amount of lights configured through tuya-local. A power cycle of the lights + router caused some of the light IP addresses to change, I assume, and no longer connect to tuya-local.

Is there a way for the device reload to re-do the IP address scanning step and keep the remaining settings, without going through the whole remove + re-add device flow? Assuming the device ID is stored, this should be able to be done automatically. Does it already happen and it just didn't work in case for some reason?

felipecrs commented 18 hours ago

@dominguesgm, in my case I add static IP leases in the router for each device to help with this issue.