Zigbee button and tasmota socket integration misbehaving

Hi,

I use Zigbee button and a tasmota socket with an automation to turn ON the socket when the button is turned ON, and turn OFF socket when the button is turned OFF.
Mosquito MQTT is the broker.

So when clicking the button - the socket switches ON / OFF as it should and in the dashboard the status of both are button and socket are in sync. Problem happens when I change the status of the button via web UI in home assistant - the socket status remains unchanged most of the times (sometimes it gets triggered, sometimes it pops “Failed to call service switch/turn_off. Failed to send request: duplicate 3 TSN” error or “Failed to call service switch/turn_on. Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>” error). Also after that if triggering the physical button - socket quickly switches on off on off few times (an audible signal of relay switching is heard).

I am using SONOFF Zigbee 3.0 USB Dongle Plus V2.

What is happening? Is is it me being an idiot or is there a bug?
P.s. I am using latest core and os versions, but that also happened with one of the latest versions from end of 2023.

P.p.s seems that the more times I unsuccessfully try to trigger the button via web UI, the more times the relay switches ON and OFF when I trigger physical button - in other words the automation on web UI button state change is not being executed but is stored somewhere internally in event stream and all events are executed all at once only when the physical button is triggered.

A side question: what is the best way to keep the status of both button and socket in sync, as in practice my socket also has it’s own physical button which can be clicked to toggle it;'s state change.

Buttons do not have a state.

Not knowing what Zigbee device you are using, it’s unclear whether you have a switch, which has a state of either on or off, or a button, which is just a momentary “press” to do something, and is not itself on or off.

If the Zigbee device is a switch, i.e. showing on/off in the Web UI, I prefer to use a blueprint to quickly create an automation to sync the switch’s state to the tasmota relay.

If the Zigbee device is a button with no state, i.e. showing “Press” in the Web UI, you can create an automation that fires when the button is pressed and calls “switch.toggle” service for the relay.

1 Like

This points to a weak link in your Zigbee mesh. Maybe read this:

Yes, you are right. I have a switch with two states - on and off.

Thanks. I might try todo something with my Zigbee network, even though initially I ruled out (and I still have strong doubts) it as being a problem because:

  • my zigbee coordinator is one of the recommended newest models.
  • network is simple with just 3 zigbee devices.
  • distances are small (max 4 meters), and in this particular issue - just 2 meter away.
  • other zigbee devices (sensors) do not report any issues for months now
  • most importantly:

the zigbee switch (which i incorrectly called zigbee button initially) has no issues triggering the relay via my automation when the switch is turned on/off by pressing it physically. The issue was observed only when changing swich’s state via web UI (and in my understanding Zigbee network does not even need to be involved here, as automation needs just to change the state of wifi tasmota socket (relay)). The physical switch itself is stateles (one click - on, two clicks - off).

Moreover, after unsuccessful state changes in web UI - all of them are being executed on tasmota device once the physical switch is toggled physically (the relay goes to on/off cycle for the same amount of times as the unsuccessful attempts to change state previously via web UI). At that point no error messages are present indicating poor Zigbee network or interferences.

Thanks, I have a switch (sorry for incorrectly calling it a button, but this is also how manufacturer calls it :wink: )

The blueprint also behaves absolutely the same - physical switch toggling changes tasmota socket state, but web UI switch toggling does nothing on the socket. But when toggling physical button - the socket is switched on/off multiple times - looks like it is executing previously not triggered web UI integrations.

Any further ideas? Thanks in advance on this really frustrating issue

P.s. The last error in the logs is:
"Error while executing automation automation.musicswitch_tasmotasocket_link: Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>",
but by the timestamp it is not triggered by the web UI state change of the switch (I have also triggered web UI and physical buttons experiencing same behaviour and seeing no additional errors in the logs). So even if I might not have the most stable Zigbee network, I am rulling out @francisp suggestion of it being the cause.

Ok, a bit further update:
Last error I have is:

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:230
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: April 4, 2024 at 11:02:03 PM (25 occurrences)
Last logged: 3:18:24 PM

[140350610552128] Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>
[140350610577472] Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>
[140350627997248] Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>
[140350602169792] Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>
[140350628033216] Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/__init__.py", line 64, in wrap_zigpy_exceptions
    yield
  File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/__init__.py", line 84, in wrapper
    return await RETRYABLE_REQUEST_DECORATOR(func)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/zigpy/util.py", line 138, in retry
    return await func()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/zigpy/zcl/__init__.py", line 377, in request
    return await self._endpoint.request(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/zigpy/endpoint.py", line 253, in request
    return await self.device.request(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/zigpy/device.py", line 297, in request
    await self._application.request(
  File "/usr/local/lib/python3.11/site-packages/zigpy/application.py", line 768, in request
    await self.send_packet(
  File "/usr/local/lib/python3.11/site-packages/bellows/zigbee/application.py", line 872, in send_packet
    raise zigpy.exceptions.DeliveryError(
zigpy.exceptions.DeliveryError: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 230, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 2035, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2072, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 876, in entity_service_call
    response_data = await _handle_entity_call(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/zha/switch.py", line 88, in async_turn_on
    await self._on_off_cluster_handler.turn_on()
  File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/general.py", line 388, in turn_on
    result = await self.on()
             ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/__init__.py", line 83, in wrapper
    with wrap_zigpy_exceptions():
  File "/usr/local/lib/python3.11/contextlib.py", line 155, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/__init__.py", line 75, in wrap_zigpy_exceptions
    raise HomeAssistantError(message) from exc
homeassistant.exceptions.HomeAssistantError: Failed to send request: Failed to deliver message: <EmberStatus.DELIVERY_FAILED: 102>

These errors are appearing with some delay - looks like there is a retry mechanism running for a while before reporting an error. After these errors are reported, the automations’ event queue is cleared and physical switch triggering executes it’s own automation only and the socket changes the state only once (no more multiple socket on/off at that time).

So:

  • web UI state changes fail to execute automations after retry mechanism fails to send message to zigbee device. Error is reported
  • If toggling physical switch while retry mechanism has not reported errors - the messages are send out and retry mechanism succeeds (that’s why multiple on/off cycles on tasmota socket).
  • Physical button toggling changes the state of tasmota socket always.

This leads to:

  • Automation is written correctly.
  • Zigbee network and interference not being a problem.

Open questions:

  • Why does HA fails to send these state changes if request comes from web UI?
  • Why does it even need to send a Zigbee message, as the Zigbee device is stateless here, and only tasmota switch needs to get a state change request over wifi connection.