Tuya strangeness - Fixed

It’s been a while since I changed anything so decided the cooler months would be a good time to rebuild and upgrade my HA.
I decided to add the tuya integration - silly me.
I’ve read the docs, created a developer account at tuya, linked my app account and after a bit of trial and error, discovered my devices on the “Western America Data Center”. ( The regions_dataCenters documentation on GitHub place Australia on the “Central Europe Data Center”)

Everything turned to custard when I configured the integration, the dreaded Login error (2406) appeared.

The cloud project was created today so it’s a long way past May 21 2021. I’ve double checked the usernames and passwords and tried changing my country to New Zealand as the above mentioned document reads that New Zealand is on the Western America Data Center. That resulted in a 1106 permission deny response.

edit.

A bit more wandering around:
from homeassistant/components/tuya/const.py

 Country("Australia", "61", TuyaCloudOpenAPIEndpoint.EUROPE),

Shouldn't  this be TuyaCloudOpenAPIEndpoint.AMERICA?

I’m in Australia and all my Tuya devices are on the Central Europe Data Center.

A bit more delving into this and its now working.
This will only effect users in Australia. - the problem stemmed from an error in the original tuya documentation as far as I can work out.
The tuya endpoint documentation incorrectly shows the endpoint for Australia as Europe. This error has been carried through to the tuya integration.

The fix (temporary until the master file on Github is fixed), is to change the endpoint in your local install.
I am currently running a supervised install on a Raspberry Pi 4. These are the steps I followed.
WARNING - do something wrong here and you can wipe out your install.
Prerequisites: ssh access to your installation. I have the “Advanced SSH & Web Terminal” add-on installed.
You can use either the terminal from the above add-on or whatever means you have to ssh in. I use PuTTY on my windows box, because its in front of me.

Once you have logged in you see

  OS Version:               Home Assistant OS 10.3
  Home Assistant Core:      2023.6.3

  Home Assistant URL:       http://homeassistant.local:8123
  Observer URL:             http://homeassistant.local:4357
~ # 

type docker ps at the prompt

~ # docker ps

This results in a list of containers


CONTAINER ID   IMAGE                                                           COMMAND               CREATED       STATUS                  PORTS                                                                                                                          NAMES
8f1839336acf   ghcr.io/hassio-addons/ssh/aarch64:15.0.2                        "/init"               3 hours ago   Up 3 hours                                                                                                                                             addon_a0d7b954_ssh
cfcf2814ba42   ghcr.io/hassio-addons/vscode/aarch64:5.8.0                      "/init"               2 days ago    Up 2 days (unhealthy)                                                                                                                                  addon_a0d7b954_vscode
e8bc073db8f9   ghcr.io/home-assistant/aarch64-hassio-observer:2022.10.0        "/usr/bin/observer"   2 days ago    Up 2 days               0.0.0.0:4357->80/tcp, :::4357->80/tcp                                                                                          hassio_observer
aadb9aa6d745   homeassistant/aarch64-addon-mosquitto:6.2.1                     "/init"               5 days ago    Up 5 days               0.0.0.0:1883-1884->1883-1884/tcp, :::1883-1884->1883-1884/tcp, 0.0.0.0:8883-8884->8883-8884/tcp, :::8883-8884->8883-8884/tcp   addon_core_mosquitto
4db1443b6498   ghcr.io/home-assistant/raspberrypi4-64-homeassistant:2023.6.3   "/init"               5 days ago    Up About an hour                                                                                                                                       homeassistant
818ae9a373ff   ghcr.io/hassio-addons/tasmoadmin/aarch64:0.24.4                 "/init"               7 days ago    Up 7 days (unhealthy)   0.0.0.0:9541->9541/tcp, :::9541->9541/tcp                                                                                      addon_a0d7b954_sonweb
5f51cc920d10   ghcr.io/hassio-addons/glances/aarch64:0.19.2                    "/run.sh"             7 days ago    Up 7 days                                                                                                                                              addon_a0d7b954_glances
c7cb58e2107e   homeassistant/aarch64-addon-samba:10.0.2                        "/init"               7 days ago    Up 7 days                                                                                                                                              addon_core_samba
88e66885029c   ghcr.io/home-assistant/aarch64-hassio-multicast:2022.02.0       "/init"               7 days ago    Up 7 days                                                                                                                                              hassio_multicast
dc456edd419c   ghcr.io/home-assistant/aarch64-hassio-audio:2023.04.2           "/init"               7 days ago    Up 7 days                                                                                                                                              hassio_audio
3405ecb6602d   ghcr.io/home-assistant/aarch64-hassio-dns:2022.04.1             "/init"               7 days ago    Up 7 days                                                                                                                                              hassio_dns
5f394e319299   ghcr.io/home-assistant/aarch64-hassio-cli:2023.05.0             "/init"               7 days ago    Up 7 days                                                                                                                                              hassio_cli
9bcff8c380b2   ghcr.io/home-assistant/aarch64-hassio-supervisor:latest         "/init"               7 days ago    Up 7 days                                                                                                                                              hassio_supervisor
~ #

You need the container ID for the container containing the main system. In my case it is
4db1443b6498
Now you need to access the container innards. To do this you attach an interactive terminal to the running container.

~ # docker exec -it 4db1443b6498 /bin/bash
homeassistant:/config#

You are now in the homeassistant config folder, there are a couple of paths from here. I usually step back to the root directory with cd … or cd /
either will work from here.
The file that needs changing is const.py, however there are more than a few of these. There is a more than even chance that the one we need is in directory tree hanging off /usr. There are a couple of options here.
Assuming we know the file name and the integration we can use the ‘find’ command

homeassistant:/# find /usr -name const.py
/usr/local/lib/python3.11/site-packages/elkm1_lib/const.py
/usr/local/lib/python3.11/site-packages/surepy/const.py

const.py is popular , there are a couple of hundred files by that name. One thing you will glean from the exercise the path to the homeassistant ones.

/usr/src/homeassistant/homeassistant/components/devolo_home_control/const.py
/usr/src/homeassistant/homeassistant/components/pilight/const.py
/usr/src/homeassistant/homeassistant/components/ovo_energy/const.py
/usr/src/homeassistant/homeassistant/components/wyoming/const.py
/usr/src/homeassistant/homeassistant/components/fibaro/const.py
/usr/src/homeassistant/homeassistant/components/frontier_silicon/const.py
/usr/src/homeassistant/homeassistant/components/mailgun/const.py
/usr/src/homeassistant/homeassistant/components/airtouch4/const.py
/usr/src/homeassistant/homeassistant/components/greeneye_monitor/const.py
/usr/src/homeassistant/homeassistant/components/qbittorrent/const.py
/usr/src/homeassistant/homeassistant/components/nam/const.py
/usr/src/homeassistant/homeassistant/components/amazon_polly/const.py

We can cd up there to narrow the path

homeassistant:/# cd  /usr/src/homeassistant/homeassistant/components/
homeassistant:/usr/src/homeassistant/homeassistant/components#

ls -al will give an alphabetical directory listing, cd into the tuya directory and list the files there with ls -al

homeassistant:/usr/src/homeassistant/homeassistant/components# cd tuya
homeassistant:/usr/src/homeassistant/homeassistant/components/tuya# ls -al
total 380
drwxr-xr-x    1 root     root          4096 Jun 29 15:52 .
drwxr-xr-x    1 root     root          4096 Jun 24 05:47 ..
-rw-r--r--    1 root     root         10561 Jun 24 03:11 __init__.py
drwxr-xr-x    1 root     root          4096 Jun 29 16:06 __pycache__
-rw-r--r--    1 root     root          4823 Jun 24 03:11 alarm_control_panel.py
-rw-r--r--    1 root     root          8404 Jun 24 03:11 base.py
-rw-r--r--    1 root     root         13874 Jun 24 03:11 binary_sensor.py
-rw-r--r--    1 root     root          3872 Jun 24 03:11 button.py
-rw-r--r--    1 root     root          3671 Jun 24 03:11 camera.py
-rw-r--r--    1 root     root         17837 Jun 24 03:11 climate.py
-rw-r--r--    1 root     root          4649 Jun 24 03:11 config_flow.py
-rw-r--r--    1 root     root         35193 Jun 29 15:54 const.py
-rw-r--r--    1 root     root         35192 Jun 29 15:52 const.py-
-rw-r--r--    1 root     root         13391 Jun 24 03:11 cover.py
-rw-r--r--    1 root     root          6396 Jun 24 03:11 diagnostics.py
-rw-r--r--    1 root     root          8687 Jun 24 03:11 fan.py
-rw-r--r--    1 root     root          5783 Jun 24 03:11 humidifier.py
-rw-r--r--    1 root     root         24281 Jun 24 03:11 light.py
-rw-r--r--    1 root     root           837 Jun 24 03:11 manifest.json
-rw-r--r--    1 root     root         14782 Jun 24 03:11 number.py
-rw-r--r--    1 root     root          1961 Jun 24 03:11 scene.py
-rw-r--r--    1 root     root         14909 Jun 24 03:11 select.py
-rw-r--r--    1 root     root         42198 Jun 24 03:11 sensor.py
-rw-r--r--    1 root     root          3646 Jun 24 03:11 siren.py
-rw-r--r--    1 root     root          5308 Jun 24 03:11 strings.json
-rw-r--r--    1 root     root         23686 Jun 24 03:11 switch.py
drwxr-xr-x    2 root     root          4096 Jun 24 03:13 translations
-rw-r--r--    1 root     root           498 Jun 24 03:11 util.py
-rw-r--r--    1 root     root          7427 Jun 24 03:11 vacuum.py

You will notice there are two “const” files , this is because I always make a copy of the file before changing anything.

 cp const.py const.py- 

does that.

If you don’t know the file you are need to change but do know the content that needs changing you can use grep to find the file and the line number in the file. I’ll demonstrate this from /usr/src, otherwise there will be screens of text.

homeassistant:/usr/src# grep -rin "australia" */* *.py
homeassistant/build/translations-download/ro.json:24756:                        "au": "Australia",
homeassistant/build/translations-download/es.json:25204:                        "au": "Australia",
homeassistant/build/translations-download/id.json:24789:                        "au": "Australia",
homeassistant/build/translations-download/pl.json:23408:                        "au": "Australia",
homeassistant/build/translations-download/it.json:24873:                        "au": "Australia",
homeassistant/build/translations-download/en.json:25120:                        "au": "Australia",
homeassistant/homeassistant/components/amazon_polly/const.py:97:    "Nicole",  # English Australian
homeassistant/homeassistant/components/amazon_polly/const.py:99:    "Olivia",  # Female, Australian, Neural
homeassistant/homeassistant/components/amazon_polly/const.py:105:    "Russell",  # English (Australian)
homeassistant/homeassistant/components/waze_travel_time/strings.json:59:        "au": "Australia"
homeassistant/homeassistant/components/waze_travel_time/translations/ro.json:41:                "au": "Australia",
homeassistant/homeassistant/components/waze_travel_time/translations/es.json:41:                "au": "Australia",
homeassistant/homeassistant/components/waze_travel_time/translations/id.json:41:                "au": "Australia",
homeassistant/homeassistant/components/waze_travel_time/translations/pl.json:41:                "au": "Australia",
homeassistant/homeassistant/components/waze_travel_time/translations/it.json:41:                "au": "Australia",
homeassistant/homeassistant/components/waze_travel_time/translations/en.json:41:                "au": "Australia",
homeassistant/homeassistant/components/tuya/const.py:599:    Country("Australia", "61", TuyaCloudOpenAPIEndpoint.AMERICA),
homeassistant/homeassistant/components/tuya/const.py-:599:    Country("Australia", "61", TuyaCloudOpenAPIEndpoint.EUROPE),
grep: homeassistant/homeassistant/components/tuya/__pycache__/const.cpython-311.pyc: binary file matches
homeassistant/homeassistant/components/ps4/const.py:20:    "AU": "Australia",
grep: homeassistant/homeassistant/components/ps4/__pycache__/const.cpython-311.pyc: binary file matches

You can see the two const files const.py- is the original and const.py the changed one. The number after the name is the line number , in this case 599.
To edit the file I used vi

homeassistant:/usr/src/homeassistant/homeassistant/components/tuya# vi const.py

vi commands are available online, the basic ones that will get the job done are
599G - jumps to line 599
right arrow to start of EUROPE
x 6 times to remove EUROPE
i to go to insert mode, type AMERICA
esc to get out of insert mode
:wq to write the file and quit the editor.

exit drops out of the container and exit again closes the session.
restart homeassistant, cross fingers.

Hmm, that is strange. I wonder what they are doing? Could it be an age thing? How long have you been running tuya devices? Mine are a few years old now.

I don’t think this is an issue for most people as I believe most Australian users are using the Central Europe Data Center and not the American one.

I for one am in Australia and my Tuya and LocalTuya integrations are working fine. When I log into the Tuya IOT site, it says that I am setup on the Central Europe Data Center.

I have been using Tuya devices for quite some time. My first Tuya IOT project was setup in March 2021 and I setup another project for the HA integration in November 2021 and I have always been on the Central Europe Data Center.

I wonder why the difference? The Tuya development site has all mine in America and the add on works now. Have you ever connected yours to Google assistant, I did that a couple of years ago.

Maybe having Google Assistant linked to Tuya needed it to be using the American Data Center in the early days as I didn’t have it linked to Google Assistant. I have my HA linked to Google Assistant and control my Tuya devices through that using LocalTuya if I want to use voice control (which I don’t use much of anymore).

You can add multiple data centers to your Tuya IOT Project so maybe that would work as well rather than changing the code to point to the American data center.

I added all the data centres to the project when I was trying to find out which one my devices used. I went through them all one by one until I found the one that showed my devices. Europe was the first one I tried. My devices only appear on the American data centre.

While researching this I read a number of posts in other places, one mentioned changing the endpoint and recompiling the app. That is a bit of an overkill as Python is an interpreted language, hence my solution.

It appears the ISD country code plays some part and if an endpoint isn’t specifically mentioned, it defaults to America. Christmas and Cocos islands both have a 61 ISD country code and don’t have a specific endpoint listed. I wonder what data centre Tuya devices there would use?