[APP][Pro] Tuya Local - Looking for testers

Hi everyone :wave:

I’d like to share my Homey app Tuya Local — a way to control many Tuya WiFi devices directly over your local network, using their local protocol instead of the Tuya cloud.

:framed_picture: What is this app?

Tuya Local connects Homey to Tuya WiFi devices that expose the local Tuya LAN API (protocol 3.1 / 3.3 / some 3.4). It talks directly to the device in your LAN using its IP address, Device ID and Local Key — no Tuya cloud, no extra bridge, no external server.

You can:

  • map Tuya DPs (data points) to Homey capabilities
  • read and write DPs
  • build flows based on Tuya device states
  • keep everything local where possible

Important: This app is for LAN‑capable Tuya WiFi devices. Tuya BLE devices are typically cloud‑only and usually cannot be controlled via Tuya Local.

:point_right: Install from the Homey App Store

:electric_plug: What the app does

Core features

  • Local control: Communicates directly with Tuya devices in your LAN using their local protocol.
  • Protocol handling: Supports multiple Tuya protocol versions (3.1 / 3.3 / some 3.4) with:
    • manual selection
    • auto‑detect (where possible)
  • DP mapping to Homey:
    • read DP structure from your device
    • map each DP to a Homey capability (on/off, dim, measure_temperature, etc.)
  • Flows & automation: Use Tuya device states and actions in Homey flows like any other device.

:gear: Device types & limitations

Well‑suited device types (WiFi, LAN‑capable):

  • Plugs / sockets
  • Lights / dimmers
  • Switches / relays
  • Some thermostats / heaters
  • Some sensors (where DPs are exposed via LAN)

Important limitations:

if the device works only in Smart Life / Tuya app and DPs never show up in scans or localtuya‑style tools, it’s probably cloud‑only.

:wrench: Setup overview

  1. Install Tuya Local from the Homey App Store.
  2. For each device, provide:
  • IP address (static or DHCP reservation recommended)
  • Device ID
  • Local Key
  1. In the device’s Repair / Settings screen:
  • choose or auto‑detect protocol version
  • configure DP mapping (DP → Homey capability)
  1. Test:
  • check if states update
  • try switching / dimming / reading values
  • adjust DP mapping if needed

:robot: About this app

  • Open source project: GitHub – com.tuyalocal
  • Focus: local control first, no Tuya cloud dependency where avoidable
  • Community‑driven: new devices and DP mappings are often added based on user feedback and logs

If you find the app useful, the GitHub repo contains information on how to support development (issues, PRs, and optionally donations).

:balloon: Feedback & contributions

I’m very interested in:

  • Which Tuya WiFi devices work well for you?
  • Which models are problematic (especially 3.4 / cloud‑only)?
  • DP mappings you’ve created that could help others
  • Logs from tricky devices (so we can improve detection and error messages)

Feel free to comment here or open an issue on GitHub — detailed logs and device info are always welcome.

If you find this app useful, I’d appreciate a beer: :backhand_index_pointing_right: PayPal – Support development

More details about the app: andiwirz/com.tuyalocal: Homey App to manage Tuya devices local

I have been trying to get your app to work with my Tuya-based mobile airconditioner, but I am not able to get the app to recognize the DP points.

The device is an Evolar EVO-14000CHW mobile airconditioner.

I am currently using the Tuya Cloud app for Homey to control the device and get status updates via the RAW commands option. In order to get it to work in the Tuya Cloud app, I had to switch the device’s instruction set in the Tuya Developer Platform from ‘Standard Instruction’ to ‘DP Instruction’ (as the standard set does not contain data points).

When I try to add the device to your app, it does find it, but it indicates that no datapoints are detected. Maybe it tries to retrieve the datapoints from the Standard Instruction set, which are not available:

The comments indicated that I should be able to manually configure the data points in the device settings. However, when opening the device settings I see no option to do so. I only see an empty DP mapping field:

I thought that maybe I had to repair the device (via the Maintenance menu), but then I get an empty dialog box and an error:

Looking at the app’s log I see ECONNRESET errors:

I am not sure how to proceed. Perhaps you can provide me some guidance.

Or does the app only work with the Standard Instruction set (which is empty for this device)?

Note that I have another Tuya device (a temperature & humidity sensor) that also requires using the DP Instruction set for it to work with the Tuya Cloud app for Homey. So same situation.

Hi @SunBeech, thanks for the detailed report — really helpful!

On “DP Instruction” vs “Standard Instruction” That’s a Tuya cloud concept (it affects how the Tuya app communicates via the cloud). For local LAN control, what matters is the protocol version (3.1 / 3.3 / 3.4 / 3.5) and whether the device accepts local connections at all. Both instruction sets should work locally as long as the device supports local LAN mode.

ECONNRESET errors This almost always means the device accepted the TCP connection but immediately closed it — typically a protocol version mismatch. Please try changing the Protocol Version in the device settings:

  • First try 3.3, then 3.4, then 3.1
  • After each change, tap Test Connection in the Repair flow

“No datapoints detected” in pairing The auto-detection relies on the device sending a status update within a few seconds of connecting. If the protocol version is wrong, no data ever arrives — which explains the empty DP list. Once the correct version is set via Repair, the DPs should start appearing in the DP Debug panel (App Settings → DP Debug).

Empty Repair dialog Could you share a screenshot of the error message? It sounds like the connection test is failing silently — I’d like to see exactly what’s shown.

Next steps I’d suggest:

  1. Note the protocol version shown in Tuya Smart / Smart Life app for this device (sometimes visible in the device info screen)
  2. Try Repair with version 3.3 → check the Logs tab in app settings for the exact error
  3. If no DPs appear, share the log output here (you can redact the local key)
  4. Use the Tuya developer Portal to check all DP values:

The app is designed to work with any Tuya LAN device — air conditioners included — so let’s get this sorted!

Hi @Andi, first of all thanks for taking the time to help me out!

I did some further tests, as yesterday I tried all protocol versions and only 3.3. connected successfully.

Different protocols

Since 3.3 was non-functional, I tried again with 3.4 today after powering on the airco. It instantly connected and showed me the config screen to link the DP points to Homey capabilities. Strange as yesterday this did not work. I continued by setting up the DP mapping and the device was successfully added (refer to the DP configuration below).

I tested whether commands worked: yes, but…the unit:

  • Does not respond to one specific command (DP 103, Sleep Mode, a boolean/switch type). See the result of the Query Properties below.
  • Seems to keep disconnecting, making the device unavailable in Homey. After a few seconds it connects again and the device becomes available again in Homey. I included the app’s log below, but I am not sure whether it provides relevant info.

No response to Sleep Mode command

Regarding the first point, I thought that maybe I needed to use yet another protocol. So I removed the device from Homey and tried the other protocols starting with 3.5. This time none worked. Also the 3.4 that worked previously did not result in a successful connection.

I found out that I had to power cycle the airco unit after each pairing/connection attempt. After trying each protocol again (power cycling the unit and restarting the Tuya Local app after each attempt) I learned that only protocol version 3.4 resulted in a connection followed by a DP mapping screen.

After recreating the device with protocol v3.4 the result was the same: the unit responds to all commands, except the Sleep Mode command. Note that that capability does work via the Tuya Cloud app for Homey, so I know it should work. Not sure why it does not respond via the Tuya Local app.

Disconnects

Regarding the second point: after I disabled the Tuya Cloud app for Homey, to which the airco unit is also paired, the disconnects seemed to have ceased. Maybe both apps cannot connect concurrently?

Error and empty repair dialog

You asked for a screenshot of the error message shown when opening the device’s repair option. It was actually included in my prior post :blush:: Error: unknown_error_getting_file.

That was the one shown in the web app (so by the browser). I also made a screenshot from the mobile app. I think that shows it more clearly:

Further questions and suggestions

Order of advanced mapping fields

I noted in the DP mapping screen that when configuring a capability with min/max values, both fields are not displayed either directly on top of next to each other. Somehow my mind expects them to be directly on top or next to each other :grinning_face:. As such, I mixed up the Scale and Min fields. Not sure whether it is possible, to change the location of the fields.

Custom picker labels

Is it possible to change the labels of the picker items? The current items are the actual value names. It would be nice if you could use more friendlier name in your own language. Similarly like the capability/datapoint label.

Custom icons for sensors

Is it possible to change the icons of sensor type capabilities? Currently the default sensor icon is displayed. Also is is possible to override the displayed sensor value with a custom more descriptive value? E.g. in the example below Error Code 0 means No Error; 4 means Watertank full, etc.

Clear log button does not work

When trying to clear the log in the Tuya Local app, using the dedicated button, nothing happens: the log is not cleared. It looks like the button is disabled.

Cloud connection / SmartLife

After a Tuya device has been set up in and can be controlled by the Tuya Local app, is it still required to keep the device in the SmartLife app/the Tuya cloud?

Additional info

Tuya Local app DP Configuration
[
{"dp":1,"cap":"onoff","label":"On/Off (Switch)","settable":true},
{"dp":2,"cap":"target_temperature","label":"Target Temperature","settable":true,"min":16,"max":31,"step":1},
{"dp":3,"cap":"measure_temperature","label":"Temperature","settable":false},
{"dp":4,"cap":"generic_picker_1","label":"Mode","settable":true,"options":"cold,wet,wind,hot"},
{"dp":5,"cap":"generic_picker_2","label":"Fan Speed","settable":true,"options":"low, med, high"},
{"dp":20,"cap":"generic_sensor_1","label":"Error Code","settable":false},
{"dp":103,"cap":"generic_switch_1","label":"Sleep Mode","settable":true},
{"dp":109,"cap":"generic_sensor_2","label":"Feature Flags","settable":false},
{"dp":110,"cap":"generic_switch_2","label":"Horizontal Oscillation","settable":true}
]
Tuya Local app log
26-04-2026, 10:05:09  [INF]  [Tuya Device]  Reconnecting in 12s (attempt 1)
26-04-2026, 10:05:09  [WRN]  [Tuya Device]  Disconnected: socket closed
26-04-2026, 10:04:37  [INF]  [Tuya Device]  Connected
26-04-2026, 10:04:25  [INF]  [Tuya Device]  Reconnecting in 8s (attempt 1)
26-04-2026, 10:04:25  [WRN]  [Tuya Device]  Disconnected: socket closed
26-04-2026, 10:03:03  [INF]  [Tuya Device]  Connected
26-04-2026, 10:02:59  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:02:54  [INF]  [Tuya Device]  Reconnecting in 9s (attempt 1)
26-04-2026, 10:02:54  [WRN]  [Tuya Device]  Disconnected: socket closed
26-04-2026, 10:01:52  [INF]  [Tuya Device]  Connected
26-04-2026, 10:01:51  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:01:46  [WRN]  [Tuya Device]  Disconnected: Error from socket: read ECONNRESET
26-04-2026, 10:01:46  [ERR]  [Tuya Device]  Error: Error from socket: read ECONNRESET
26-04-2026, 10:01:46  [INF]  [Tuya Device]  Connected
26-04-2026, 10:01:46  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:01:42  [INF]  [Tuya Device]  Reconnecting in 10s (attempt 1)
26-04-2026, 10:01:42  [WRN]  [Tuya Device]  Disconnected: socket closed
26-04-2026, 10:01:41  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:01:36  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:01:12  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:00:54  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 10:00:40  [INF]  [Tuya Device]  Connected
26-04-2026, 10:00:29  [INF]  [Tuya Device]  Reconnecting in 11s (attempt 1)
26-04-2026, 10:00:29  [WRN]  [Tuya Device]  Disconnected: socket closed
26-04-2026, 10:00:13  [WRN]  [Tuya Device]  Timeout (non-fatal): Timeout waiting for status response from device id: xxx
26-04-2026, 09:53:16  [INF]  [Tuya Device]  Connected
26-04-2026, 09:32:52  [INF]  [App]  Started — v1.0.16
Tuya IoT Developer Portal Query Properties
{
  "result": {
    "properties": [
      {
        "code": "Power",
        "custom_name": "",
        "dp_id": 1,
        "time": 1751995068093,
        "type": "bool",
        "value": false
      },
      {
        "code": "temp_set",
        "custom_name": "",
        "dp_id": 2,
        "time": 1751994801716,
        "type": "value",
        "value": 18
      },
      {
        "code": "temp_current",
        "custom_name": "",
        "dp_id": 3,
        "time": 1751995832904,
        "type": "value",
        "value": 23
      },
      {
        "code": "mode",
        "custom_name": "",
        "dp_id": 4,
        "time": 1751992994779,
        "type": "enum",
        "value": "cold"
      },
      {
        "code": "windspeed",
        "custom_name": "",
        "dp_id": 5,
        "time": 1751993543398,
        "type": "enum",
        "value": "low"
      },
      {
        "code": "anion",
        "custom_name": "",
        "dp_id": 11,
        "time": 1751992868610,
        "type": "bool",
        "value": false
      },
      {
        "code": "windshake",
        "custom_name": "",
        "dp_id": 15,
        "time": 1751992868610,
        "type": "enum",
        "value": "off"
      },
      {
        "code": "Fault",
        "custom_name": "",
        "dp_id": 20,
        "time": 1751992870055,
        "type": "bitmap",
        "value": 0
      },
      {
        "code": "Sleeping_mode",
        "custom_name": "",
        "dp_id": 103,
        "time": 1751992870139,
        "type": "bool",
        "value": false
      },
      {
        "code": "TimerOn",
        "custom_name": "",
        "dp_id": 104,
        "time": 1751992868610,
        "type": "value",
        "value": 0
      },
      {
        "code": "TimerOff",
        "custom_name": "",
        "dp_id": 105,
        "time": 1751992868610,
        "type": "value",
        "value": 0
      },
      {
        "code": "temp_set_f",
        "custom_name": "",
        "dp_id": 107,
        "time": 1751994801721,
        "type": "value",
        "value": 64
      },
      {
        "code": "temp_current_f",
        "custom_name": "",
        "dp_id": 108,
        "time": 1751992868610,
        "type": "value",
        "value": 32
      },
      {
        "code": "funcTag",
        "custom_name": "",
        "dp_id": 109,
        "time": 1751992871106,
        "type": "bitmap",
        "value": 26
      },
      {
        "code": "windshakeH",
        "custom_name": "",
        "dp_id": 110,
        "time": 1751993261080,
        "type": "bool",
        "value": false
      }
    ]
  },
  "success": true,
  "t": 1751997148404,
}

Short answer: no , as long as you’ve already extracted the Local Key. The device works fully locally once paired. The only reason to keep SmartLife is to retrieve a new Local Key if you ever factory-reset the device

You’re still using 1.0.16

1.0.19 is already out and should fix hopefully your problems.

In the new version will be an air con as well:

Thanks for the quick follow-up.

Setup

I tested with v1.0.19 and the new airco driver works. It detected the 3.4 protocol and showed all the DPs. I only had to manually add:

  • The Sleep Mode, as that was not auto configured;
  • The picker items for the Mode and Fan Speed lists, as those included only the current item.

So the setup was really easy :grinning_face: .

By the way: the Sleep Mode command was working after all, but I was testing it while the unit was in Fan mode, and it only works in Cooling mode. So my bad.

Tags

I checked the available tags:

Perhaps you made a deliberate design choice here on which tags to provide.

If not, could you also add tags for the:

  • Power on/off state (boolean; though I noted that the app itself does provide an AND card for that)
  • Fault code (number; and/or add is as a tag to the ‘AC fault alarm triggered’ WHEN card)
  • Sleep Mode on/off (boolean)
  • Horizontal Oscillation on/off (boolean)

So I can act on changes. I did note that there is an ‘AC datapoint change’ flowcard provided by the app, though. So I assume I can act on any change in any datapoint using that flowcard.

Polling / Updating info in Homey

I noticed that the device info in Homey is not always updated when I use the physical buttons on the airco. E.g. when I change the target temperature or activate swing mode on the unit itself, the info in the device tile (temp value and button resp.) does not update; also not after the 30 sec polling interval. Sometimes it updates after I close the device and reopen the tile.

Is it supposed to update immediately?

I see that there is a setting for the polling interval. Does that mean that the device info in Homey updates only as per the polling interval, or does it also gets changed info pushed by the airco unit?

Step size & min/max target temperature

The target temperature control in Homey allows me to set temperatures at the 0.5 precision. The airco only accepts step sizes of 1. Is it possible to customize/configure the step size and min/max values, like when using the generic driver?

Error and empty repair dialog

Not sure whether you looked into the empty repair dialog, but I checked and it is still empty with the same unknown_error_getting_file error.

Thanks for the detailed testing and feedback — very helpful!

v1.0.20–1.0.22 are out and address all the points you raised:


Setup

The mode and fan speed pickers now show all common options immediately after pairing (cool, heat, auto, dry, fan / auto, low, medium, high, turbo) — no longer seeded with just the current value. Sleep mode auto-detection is also improved: if the AC doesn’t report DP 103 during pairing (e.g. in fan mode), it will be automatically picked up the first time it appears after switching to cooling mode and reconnecting.


Tags / Flow cards (v1.0.22)

A few things to clarify about tags:

  • Power on/off — the built-in onoff capability already gives you “When [device] turns on / off” trigger cards automatically. Same goes for ac_sleep and ac_swing_h — Homey auto-generates “turns on/off” triggers for all boolean capabilities. You’ll find them under the device in the flow builder, not under the app’s own cards.
  • Fault code — now added as a token to the AC fault alarm triggered WHEN card.

Beyond that, v1.0.22 adds several new cards you might find useful:

  • Trigger: AC mode changed — with tokens for the new and previous mode
  • Conditions: AC fan speed is, AC sleep mode is on/off, AC fault alarm is active
  • Actions: Set ECO mode, ioniser, horizontal swing, and child lock on/off

Polling / push updates

The driver maintains a persistent TCP connection and does receive push updates from the AC immediately when physical buttons are pressed — the 30 s polling is only a fallback in case a pushed update is missed. The tile not refreshing is most likely Homey’s UI caching the last-known state; closing and reopening the device card forces a redraw. There’s nothing the app can do about that on the Homey side.

That said, some AC units don’t push all data points when operated physically — they only push the DP that changed, and some DPs (like target temperature on certain models) aren’t always pushed at all. In that case the polling interval is what catches it. You can lower it in device settings if you need faster updates.


Temperature step / min / max

Now configurable in device settings: Temperature Step (default 1 °C), Min Target Temperature (default 16 °C), Max Target Temperature (default 30 °C). Changes apply immediately without restarting the app.


Repair dialog

The dialog now shows an explicit error message if loading fails, so at least it’s not silently empty anymore. The underlying unknown_error_getting_file looks like a Homey platform issue with how it serves repair views in certain environments — still investigating. As a workaround, all connection settings (IP, Local Key, protocol version) can be updated directly in the device settings page without using the repair flow.

I just checked the new version v1.0.22. I first removed and then re-paired my AC unit.

Setup

Indeed the picker lists for the Mode and Fan Speed are now populated. I did have to remove (of course) the modes/speeds my devices does not have. I also had to rename some of the Mode values. Not sure whether they are standardized or not:

cold,cool,heat,auto,dry,fancold,wet,wind,hot

My device uses:

  • wet to indicate the dehumidify/dry mode

  • wind to indicate the fan mode

  • hot to indicate the heating mode

Tags / Flow cards

I can indeed find the added tokens and flowcards (thanks!), except for the trigger cards you mention for the ac_sleep and ac_swing_h capabilities. Not an issue for me, as I won’t be using them as a trigger. But just for your info, Homey generated the following WHEN cards:

When…
Temperature changes AC datapoint changed
Switched on AC fault alarm triggered
Switched off AC mode changed
Temperature gets more than x °C Switched on for x period
Temperature gets less than x °C Switched off for x period
Target temperature changed Temperature gets more than x °C for y period
General alarm goes on Temperature gets less than x °C for y period
General alarm goes off Fault alarm triggered for x period
AC connected Fault alarm cleared for x period
AC disconnected

Polling / push updates

I checked for all the physical buttons on the AC unit whether it results in a direct update of the related control in the Homey device. It seems than only the power on/off results in a direct update of the on/off button in Homey.

Changes made by any of the other buttons (like increase/decrease of the target temperature) are only reflected after the next polling interval. Opening/closing the device screen in Homey does not update the values.

From my experience with the Tuya Cloud app for Homey, I know that my unit only communicates changed values. So if I change the target temperature then the device only sends that datapoint.

What I don’t understand is why the power off/on is reflected in the Homey device immediately, while the others are not updated unless polled. Any idea why that would be the case?

Temperature step / min / max

Thanks this works now.

Repair dialog

In my case, the dialog is still empty and the same error is shown. If I dismiss the error the dialog box remains empty.

Mode values
That’s completely expected. The default list (cool, heat, auto, dry, fan) is just a starting point based on the most common Tuya AC firmware strings — your device uses its own set (cold, wet, wind, hot), which is equally valid. The driver just passes the raw string straight through, so whatever your device sends is what you use. No standardisation at the Tuya LAN level, unfortunately.

v1.0.24 (just published) fixes the visible symptom: whenever the AC does send a push (e.g. power on/off), Homey now immediately fires a follow-up GET 500ms later. So changing power state on the remote will now also update mode, temperature, fan speed etc. right away — not just the on/off button. For changes made via the remote without a power change (e.g. adjusting temperature while already on), the polling interval still applies, because the device sends nothing at all.

Repair dialog
This is fixed in v1.0.23. The root cause was a Homey SDK v3 quirk: repair views must live in drivers/{id}/repair/repair.html, but three of the four drivers only had drivers/{id}/pair/repair.html — which Homey silently ignores for the repair flow. All drivers are now in the correct location and the form pre-fills your current IP and local key on open.

So: update to v1.0.24 and the repair dialog and the push-update behaviour should both be resolved. Let me know how it goes!

I check v1.0.24. Thanks again for the quick update.

The repair dialog now works. The only thing I noted is that when I make a change and it subsequently tests the connection it always results in a success message, also if the device is not available.

I did not note any difference in the update speed of datapoints in Homey. I do have a question though:

  • When I control the AC via the physical buttons on the AC, e.g. change the target temperature, the change is reflected directly in the virtual device I created in Homey that shows the incoming updates via the Tuya Cloud app for Homey. Same behavior when looking into the SmartLife app on mobile. I can also see the messages sent by the AC to the cloud in the Tuya IoT Platform.
  • So apparently the AC sends changes to the cloud immediately. Does that mean that the AC uses a different method for local LAN connections?

For now I have set the polling interval to 5 secs.

Another question: does your app also work with battery powered devices?

I have a temperature & humidity sensor that I tried to connect. The challenge is that the WiFi radio of the device is switched off most of the time. It is only enabled for a short period every hour or on significant changes. I created a device in your app (without being able to test the connection) based on the generic driver and manually created a DP mapping JSON (see below) based on the information in the Tuya IoT portal. I let is sit for the night hoping it would receive updates at some point. Unfortunately that did not work. Have you got any suggestions how to get this working, or won’t battery powered devices work at all via a local connection?

DP mapping temp & humidity sensor
[
{"dp":27,"cap":"measure_temperature","settable":false,"scale":0.1},
{"dp":46,"cap":"measure_humidity","settable":false},
{"dp":101,"cap":"measure_battery","settable":false,"readMap":
{"low":25,"middle":50,"high":100}},
{"dp":101,"cap":"alarm_battery","settable":false,"readMap":
{"low":true,"middle":false,"high":false}}
]

Likely won’t work. I don’t have experience with Tuya local devices, but my cloud connected Tuya contact, motion and smoke sensors disconnect almost immediately after sending the update to the Tuya server (so-called “Deep sleep” to save battery). So there is likely not enough time to discover the device, connect to it and poll the status before it disconnects.

Thanks again for the thorough testing!

Repair dialog always shows success
The save_settings handler was catching connection errors internally and returning { connected: false } instead of throwing. The repair HTML only checked for an exception, so it always showed the success message regardless. Fixed in v1.0.25: the handler now throws properly when the connection test fails, so you’ll see the red error message with the reason (timeout, wrong key, etc.). Settings are also only written when the test actually passes.

Why only power updates immediately — and why the cloud is different

Great question, and you’ve identified exactly the right distinction. Your AC maintains two completely separate connections at the same time:

  1. Cloud connection (persistent, to Tuya’s servers): The device pushes every state change — temperature, mode, fan speed, everything — over this connection immediately. That’s why SmartLife, the Tuya IoT Platform, and the Tuya Cloud Homey app all update instantly. This is essentially an always-on MQTT/WebSocket channel between the device and Tuya’s cloud.

  2. Local LAN TCP server (what this app uses): The device accepts incoming TCP connections from clients on the local network, but it decides independently what to push locally. Your AC’s firmware only pushes DP 1 (power state) proactively over the local connection. For everything else, it only responds to a GET request — it won’t send unsolicited local notifications.

This is a firmware decision by the manufacturer, not something that can be worked around at the protocol level. The local and cloud paths are genuinely different channels with different push behaviour.

What v1.0.24 improves: when the AC does send a local push (e.g. power state change), Homey now immediately fires a follow-up GET to fetch the full state. So turning the AC on/off via the remote will now also update mode, temperature, fan speed etc. right away. For other button presses (changing temperature while already on), the polling interval still applies because the AC sends nothing locally at all.

5 seconds is a reasonable polling interval for an AC — low enough to feel responsive, and the AC connection is light enough that it won’t cause any issues.

This app is fundamentally limited to always-on, mains-powered WiFi devices — anything that has to keep a persistent TCP connection alive. For battery sensors, cloud-based integration is the right architecture as I think they are tied to the cloud and are not able to work locally.

Updates v1.0.23–1.0.29 — bug fixes across the board

Here’s what changed:

:wrench: Repair dialog — fixed for all drivers (v1.0.23, v1.0.25)
The repair dialog was broken for three of the four drivers (Smart Plug, Generic, Air Conditioner). Root cause: Homey SDK v3 looks for repair views in drivers/{id}/repair/, not drivers/{id}/pair/ — so the dialog never loaded. Also fixed: when the connection test fails, the dialog now shows an error message instead of falsely reporting success.

:high_voltage: Faster state updates after push notifications (v1.0.24)
When a device sends an unsolicited push (e.g. AC powering on/off), Homey now immediately fires a follow-up GET to fetch the full device state. Previously, only the pushed DP updated instantly — mode, temperature, fan speed etc. had to wait for the next poll cycle.

:droplet: Dehumidifier water alarm — hopefully final fix (v1.0.26)
The spurious “tank full” notifications were reduced from every 3 minutes (v1.0.19) to every hour, but still occurring. The root cause is a firmware bug where some devices emit a periodic alarm pulse every ~60 minutes. Fixed by:

  • Increasing the oscillation guard from 5 minutes to 2 hours (configurable via new device setting Alarm guard window, default 2 h, range 0.5–24 h)
  • Increasing the confirmation debounce from 2 to 10 minutes
  • Persisting the timestamp across Homey restarts — previously a reboot reset the guard to zero, letting the next pulse through immediately

:collision: App crash fixes (v1.0.27, v1.0.29)
Two crash scenarios fixed:

  • Connection timed out: TuyAPI was throwing this on the raw socket, bypassing our error handler → crash. Now correctly triggers a reconnect.
  • HMAC mismatch: This happens when the local key is wrong or a 3.3 vs 3.4 protocol mismatch occurs during auto-detect. The root cause was a race condition in autoDetect.js — after stripping event listeners, the socket was still briefly alive, so any in-flight packet threw an unhandled error → crash. Fixed by re-attaching a no-op error handler before disconnect.

If you see HMAC mismatch in your diagnostic log, it means either your Local Key has changed (re-link the device in Tuya/SmartLife, then get the new key from Tuya IoT Platform) or you need to switch to Auto-detect protocol version in the Repair screen.

Hi Andi,
any chance for support a Tuya BLE / Wifi Bridge

I have some Tuya BLE SmartLocks that are connect to Tuya BLE/Wifi Bridge.
Unfortunaltly it seems that the connection is not very stable. Only Protocol Version 3.4 ist working somehow. Auto-Dectect is not working. But DP points are empty I think from the unstable connection. (DP Instruction set is set)

29.04.26, 16:02:24 [INF] [SmartLock 2] Reconnecting in 265s (attempt 51)
29.04.26, 16:02:24 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 16:02:24 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:57:10 [INF] [SmartLock 2] Reconnecting in 313s (attempt 50)
29.04.26, 15:57:10 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:57:10 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:52:21 [INF] [SmartLock 2] Reconnecting in 285s (attempt 49)
29.04.26, 15:52:21 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:52:21 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:46:49 [INF] [SmartLock 2] Reconnecting in 332s (attempt 48)
29.04.26, 15:46:49 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:46:49 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:42:43 [INF] [SmartLock 2] Reconnecting in 245s (attempt 47)
29.04.26, 15:42:43 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:42:43 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:38:36 [INF] [SmartLock 2] Reconnecting in 247s (attempt 46)
29.04.26, 15:38:36 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:38:36 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:33:16 [INF] [SmartLock 2] Reconnecting in 320s (attempt 45)
29.04.26, 15:33:16 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:33:16 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:28:05 [INF] [SmartLock 2] Reconnecting in 311s (attempt 44)
29.04.26, 15:28:05 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:28:05 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:22:11 [INF] [SmartLock 2] Reconnecting in 353s (attempt 43)
29.04.26, 15:22:11 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:22:11 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:16:16 [INF] [SmartLock 2] Reconnecting in 355s (attempt 42)
29.04.26, 15:16:16 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:16:16 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:11:14 [INF] [SmartLock 2] Reconnecting in 301s (attempt 41)
29.04.26, 15:11:14 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:11:14 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:06:46 [INF] [SmartLock 2] Reconnecting in 268s (attempt 40)
29.04.26, 15:06:46 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:06:46 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:02:30 [INF] [SmartLock 2] Reconnecting in 255s (attempt 39)
29.04.26, 15:02:30 [ERR] [SmartLock 2] Connection failed: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 15:02:30 [ERR] [SmartLock 2] Error from socket: read ECONNRESET — likely protocol version mismatch. Use Auto-detect in the device Repair screen.
29.04.26, 14:56:44 [INF] [SmartLock 2] Reconnecting in 346s (attempt 38)

The official Homey Tuya (Cloud) App will not support my Smartlocks (Wifi/BLE, I request it already) and there is no configuration possibility like it is in your app for DP. Maybe you can add support for cloud devices, too.
In SmartLife they are working fine.

I think there would be a large demand for the cloud version with same functions (DP points to Home capabilites) for official unsupported Tuya (cloud) devices, too

Here are the properties from the Smartlock

{
“result”: {
“properties”: [
{
“code”: “unlock_method_create”,
“custom_name”: “”,
“dp_id”: 1,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “unlock_method_delete”,
“custom_name”: “”,
“dp_id”: 2,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “unlock_method_modify”,
“custom_name”: “”,
“dp_id”: 3,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “residual_electricity”,
“custom_name”: “”,
“dp_id”: 8,
“time”: 1777458214037,
“type”: “value”,
“value”: 100
},
{
“code”: “unlock_card”,
“custom_name”: “”,
“dp_id”: 15,
“time”: 1777453129986,
“type”: “value”,
“value”: 0
},
{
“code”: “unlock_ble”,
“custom_name”: “”,
“dp_id”: 19,
“time”: 1777453129986,
“type”: “value”,
“value”: 0
},
{
“code”: “alarm_lock”,
“custom_name”: “”,
“dp_id”: 21,
“time”: 1777453129986,
“type”: “enum”,
“value”: “wrong_finger”
},
{
“code”: “beep_volume”,
“custom_name”: “”,
“dp_id”: 31,
“time”: 1777458214037,
“type”: “enum”,
“value”: “normal”
},
{
“code”: “automatic_lock”,
“custom_name”: “”,
“dp_id”: 33,
“time”: 1777462428714,
“type”: “bool”,
“value”: true
},
{
“code”: “rtc_lock”,
“custom_name”: “”,
“dp_id”: 44,
“time”: 1777453129986,
“type”: “bool”,
“value”: false
},
{
“code”: “synch_method”,
“custom_name”: “”,
“dp_id”: 54,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “remote_no_dp_key”,
“custom_name”: “”,
“dp_id”: 61,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “unlock_phone_remote”,
“custom_name”: “”,
“dp_id”: 62,
“time”: 1777453129986,
“type”: “value”,
“value”: 0
},
{
“code”: “record”,
“custom_name”: “”,
“dp_id”: 69,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “check_code_set”,
“custom_name”: “”,
“dp_id”: 70,
“time”: 1777453152023,
“type”: “raw”,
“value”: “AAL//wAAAAAAAAAAAP//AA==”
},
{
“code”: “ble_unlock_check”,
“custom_name”: “”,
“dp_id”: 71,
“time”: 1777453129986,
“type”: “raw”
},
{
“code”: “remote_pd_setkey_check”,
“custom_name”: “”,
“dp_id”: 73,
“time”: 1777453228722,
“type”: “raw”,
“value”: “//8CADM4NzQ2NjAyAQEAqcjxaX+bvHL//zgxNjkyODA2”
}
]
},
“success”: true,
“t”: 1777472113820,
“tid”: “d6d6fec743d511f19b09f6054563e45d”
}

What do you think? Any chance?
Let me know I will help with logs and donation

Your device is a Tuya BLE Smartlock behind a Tuya BLE/WiFi bridge. Tuya Local relies on the standard Tuya LAN protocol (UDP discovery + TCP DP channel). BLE locks usually do not expose this LAN API – they talk BLE to the bridge, and the bridge talks only to the Tuya Cloud (protocol 3.4+ with a cloud proxy/handshake). That’s why you see ECONNRESET, protocol mismatch and empty DPs: the bridge closes the TCP connection because it doesn’t understand the local payload.

In other words: this device type is effectively cloud‑only, not a true LAN device. Tuya Local is designed for WiFi devices with a working LAN API, so BLE locks via bridge are out of scope.

Sorry :frowning:

Thanks for feedback.

In the meantime I found a way to to go :wink:
I looked in HA and it seems that the LocalTuya Integration will support the BLE/Wifi Bridge.
I will try to add it there and than sync the smart lock to Homey.
But there are issue, too. So not all bridges can open enough connections. Mostly only 1-3 at all.
I will update to a newer bridge who can handle more connections. Maybe this will work for your app, too

Does that mean you’re able to see DP IDs there?

No.
Gateway Support for bluetooth is implemented
But I think my gateway is limited with the connections as mentioned here

So perhaps a newer bridge would make it
On the other hand there is a new one announced which will bridge ble to matter. Maybe this will be the best option

But finally I found now a fork of the HA Tuya Cloud implementation that is supporting my smart locks. So I have them now full running in HA and synced to Homey.
As they are drawer locks is not so critical that they are running through the cloud :wink:
At the end I am now able to build my homey flows with the ble tuya smart locks :wink:

Thanks for your support and time

That one already exists on AliExpress:

However, it only supports adding Matter devices to the Tuya app/cloud, AFAIK it doesn’t support bridging BLE devices to Matter.

You can also use http://homey.app/a/com.tuya2 with the generic/unknown device, then you can create Flows based on status changes and control the devices from your Flows.