====== Internet of Things: Teckin Smart Plug SP22 ====== Di queste prese intelligenti marchiate **Teckin** ne esistono almeno due versioni. Le più vecchie si basano sul chip **ESP** mentre quelle più recenti si basano sul chip Realtek **RTL8710BN**. Questo fa molta differenza se si vuole cambiare il firmware originale con quello **libero ed open source Tasmota**, infatti Tasmota è compatibile solo con il chip **ESP**. Le prese - con la configurazione originale - utilizzano la piattaforma cloud **Tuya** per essere controllate. Esiste l'app **Smart Life - Smart Living** per Android ed una equivalente per iOS. ===== Perché il Cloud Tuya è male ===== Abbiamo provato a gestire una **presa intelligente Teckin SP22** tramite le **API** della libreria Python **TinyTuya**. Per quanto mi riguarda l'**esperienza è del tutto disastrosa** in termini di flessibilità e libertà di programmazione. Questo un riassunto delle motivazioni. Per poter gestire un device Tuya tramite API è necessario: * Installare la **app Smart Life** (Android o iOS) e fare il pairing del device sulla app. * Attivare un **account developer sul cloud Tuya** (gratuito solo in prova limitata nel tempo). * **Aggiungere il device** sul Cloud Tuya. * Se si decide di **spostare il device su una diversa rete** (cambio dell'ESSID WiFi) è necessario ripetere l'operazione di pairing che dipende dal cloud Tuya. Questa operazione **modifica la local key** del dispositivo (utilizzata dalla API TinyTuya) ed è necessario ottenerne una nuova dal cloud Tuya. * Un dispositivo, quando viene acceso, chiama il cloud Tuya per determinare eventuali variazione al suo stato corrente (ad esempio lo stato ON/OFF dello switch). **Se il cloud non è raggiungibile** (ad esempio per mancanza di connettività), il dispositivo resta in uno stato indefinito in cui non può essere controllato dalla API TinyTuya. È necessario **premere almeno una volta il pulsante** per cambiare il suo stato per poterlo comandare nuovamente via API. * Appena si **rimuove una device dalla app**, il Cloud invia al device stesso l'**istruzione di reset**. Il dispositivo **resetta tutta la sua configurazione** ed entra immediatamente in pairing mode. Se il device non è on-line al momento della sua rimozione dalla app, l'istruzione di reset viene comunque inviata appena esso torna on-line. ===== Smart Life App ===== The QR code printed on the plug itseld points to [[http://e.tuya.com/smartlife]], here you can download the 76.7 Mb **smartlife.apk**. We prefered to download it from the Google Play, searching the **Smart Life - Smart Living** app by Volcano Technology Limited, at the URL **[[https://play.google.com/store/apps/details?id=com.tuya.smartlife]]**. Strangely enough, the Google Play app is only 40.35 Mb... ==== Pairing the smart plug with the App and WiFi ==== - Plug the SP22 into an electricity outlet. - Start the **Smart Life** app on the smartphone (it shows a warning message if the phone is rooted). - Tap **Try now** (**Provalo adesso**) to use the app without registering an account. - Tap the **+** in the upper-right corner **Add devices** (**Aggiungi dispositivo**). - Select the **Electrical Outlet Wi-Fi** (**Presa Wi-Fi**). * If you negate the localization permission, you will be required to manyally enter the WiFi network name. * Input the ESSID and password. - Press the button on the SP22 for 5 seconds: the LED under the button start flashing in blue, about three time per second: the device is in pairing mode. - Tap the **Next** button into the app as required, untill the app start searching for the device. - The procedure on the smartphone should terminate with the message **Successfully Added** (**Aggiunto con successo**). ==== After the pairing ==== * The SP22 connect to the WiFi network, getting an IP address from the local DHCP server. You can view the request into the DHCP server log, coming from a **Tuya Smart Inc.** MAC address (prefix d4:a6:51). In my case the device presented itself with the name **TY_WR**. * The device has the port **6668/TCP** open. * The device broadcasts on the local network using port **6667/UDP**. * The device communicates with several internet servers on port **8886/TCP**. In our case it was an Amazon AWS under the DNS name **m2.tuyaeu.com** or **a3.tuyaeu.com** (they resolve into several and changing IP addresses). * The SP22 can be switched on/off from the smartphone. ==== How the app communicates witht the device ==== * If the Smart Plug has internet connectivity, it gets **commands from the cloud server**. * If the Smart Plug does not have internet connectivty, it gets **commands from the LAN**. * The smartphone detects if **it can use internet or LAN connectivity** to communicate with the device. If bot connections are broken, the device appears as "off-line" into the app. * With default configuration, the SP22 remembers its last status (on or off) when it recovers from a power failure. ==== How the app communicates witht the cloud ==== * It seems that the app does not make DNS calls to resolve for the cloud server name, at least in my case I cannot detect **any DNS requests**, even after a smartphone reboot. The app communicates on port **TCP/8883** (Secure MQTT) with an **Amazon AWS** server,IP address 18.194.10.142. ===== How to create a Tuya Developer Account ===== To use the TinyTuya library we need the **device local key**. This key is assigned by the **Tuya Cloud** to your device when you do the **pairing** with the **Smart Life** app. The key will be valid and can be **used locally** to control your device even if the Tuya cloud is unavailable, but you cannot move the device into another network; in that case you need to obtain a new local key from Tuya cloud. Actually we need to: * **Register** an account at **[[https://iot.tuya.com/]]**. * Open a **support ticket** asking to be upgraded to **developer**. If you are not enabled and you try to create a cloud project, you get an error like this: //Your account is not yet available for cloud development platform. The cloud development platform can only be used after completing personal authentication or enterprise authentication//). * Create a **Cloud Project**. * **Link the devices** you have enabled into the Smart Life app into the Cloud Project. * **Authorize** the use of the API for this Cloid Project. These are the steps to be executed into the **Web Framework**: * Cloud * Projects * Try It Free * Project Name: TinyTuya Python API * Description: Manage Tuya devices from GNU/Linux * Industry: Other * Authorization Key * Access ID/Client ID: 4e46be08d231a017dc2c * Access Secret/Client Secret: 0061ee191a3e90e22467c1be8dce4b1f * Any IP can use the authorized key to access the API of this project * Link Devices * Select the Project //TinyTuya Python API// from drop-donw menu * Link devices by App Account => Add App Account (a QR-code appear) * Start the Smart Life app on the smartphone => Me * Tap the top-right icon [-] and scan the QR-code * API Groups * Select the Project //TinyTuya Python API// from drop-donw menu * Authorization management: Open (Reason: TinyTuya requests) * Device Management: Open * Device Control: Open ==== TinyTuya Python library ==== Il nostro obiettivo è poter controllare i dispositivi tramite una qualche **API**, possibilmente in **Python** e con esigenze modeste. La piattaforma di riferimento è **Raspberry Pi** o una qualunque distribuzione **GNU/Linux**. La scelta è caduta sulla **[[https://pypi.org/project/tinytuya/|libreria Python TinyTuya]]**, che sembra rispondere a tutte le richieste. L'installazione ha dei prerequisiti che possono essere soddisfatti con l'installazione locale via **pip**, qualora la distribuzione di riferimento non li soddisfi. In particolare la libreria **python3-crypto** offerta da Debian 10 è adeguata, mentre la libreria **python3-pycryptodome** di Debian è alla versione **3.6.1**, mentre TinyTuya richiede **3.9.9**. In definitiva si possono scaricare i pacchetti dal repository [[https://pypi.org/]] e installarli manualmente: pip3 install pycryptodome-3.9.9-cp37-cp37m-manylinux1_x86_64.whl pip3 install tinytuya-1.1.2-py2.py3-none-any.whl === Scanning for devices on the LAN === After installing the TinyTuya Python library, just run: python3 -m tinytuya TinyTuya (Tuya device scanner) [1.1.2] Scanning on UDP ports 6666 and 6667 for devices (15 retries)... 3.3 Device Found [Valid payload]: 10.0.0.129 ID = bff7e612edf4edb899uaiz, Product ID = keyqwtgrcsf3hxng, Version = 3.3 No Stats - Device Key required to poll for status Scan Complete! Found 1 devices. According to the instruction of the **[[https://github.com/jasonacox/tinytuya|TinyTuya Readme]]**, we need the following data to interact with the device: ^ DEVICE_ID | This is the device **ID** shown after the devices scan performed by **python3 -m tinytuya**. | ^ IP_ADDRESS | This is the IP address acquired by the device, this is shown by **python3 -m tinytuya**. | ^ LOCAL_KEY | This is a API programming key obtained from the Tuya Cloud. You need to register to the Tuya web developmente framework and obtain a **developer account**. It seems that this **requires a payment**, but a free trial period exists. | Let's see how to obtain a **Tuya Developer account** on **[[https://iot.tuya.com]]**. As I reported into the **[[https://github.com/jasonacox/tinytuya/issues/15|issue #15]]** it seems that a Developer Account is not longer available for free, nor it is so simple to obtain. === Getting the device local key and programming === Now we use TinyTuya library to get the **local key** required to control the device. **NOTICE**: run the tinytuya wizard in a terminal with a **dark background**, otherwise you cannot read the white text! python3 -m tinytuya wizard Enter API Key from tuya.com: 4e46be08d231a017dc2c Enter API Secret from tuya.com: 0061ee191a3e90e22467c1be8dce4b1f Enter any Device ID currently registered in Tuya App (used to pull full list): bff7e612edf4edb899uaiz Enter Your Region (Options: us, eu, cn or in): eu Some output will be displayed on the screen and two files are created: **tinytuya.json** and **devices.json** { "apiKey": "4e46be08d231a017dc2c", "apiSecret": "0061ee191a3e90e22467c1be8dce4b1f", "apiRegion": "eu", "apiDeviceID": "bff7e612edf4edb899uaiz" } [ { "name": "Presa #1", "id": "bff7e612edf4edb899uaiz", "key": "a28b367332e8b5ee" } ] Finally you can control the device using Python. Here it is an example on how to get the status of the smart switch and toggle its status: #!/usr/bin/env python3 import tinytuya d = tinytuya.OutletDevice('bff7e612edf4edb899uaiz', '10.0.0.129', 'a28b367332e8b5ee') d.set_version(3.3) data = d.status() # Show status and state of first controlled switch on device print('Dictionary %r' % data) print('State (bool, true is ON) %r' % data['dps']['1']) # Toggle switch state switch_state = data['dps']['1'] data = d.set_status(not switch_state) if data: print('set_status() result %r' % data) Here it is an example of the dictionary returned by the **tinytuya.OutletDevice().status()** method. There are several keys, where the **1** is the **ON/OFF** status and the **20** is the **voltage in decivolt**: Dictionary {'dps': {'1': True, '9': 0, '18': 0, '19': 0, '20': 2302}} State (bool, true is ON) True ===== Tasmota and Tuya-Convert ===== La soluzione **Tuya Cloud** è ovviamente **non accettabile** se si vuole avere il controllo dei device al di fuori del circolo vizioso **Smart Life app** - **Tuya Cloud**. Purtroppo sostituire il firmware originale con Tasmota pare che sia diventato impossibile. Anzitutto sembra che Teckin si sia impegnata a rendere impossibile il funzionamento di Tuya-Convert (tool per il flash del firmware Tasmota), almeno a giudicare dalla **[[https://github.com/ct-Open-Source/tuya-convert/issues/197|issue 197]]**. Poi, cosa ancora più grave, sembra proprio che le nuove versioni di SP22 siano basate su chip Realtek non compatibile con Tasmota, vedere questa **[[https://tasmota.github.io/docs/devices/Teckin-SP22/|pagina informativa]]**. * **[[https://tasmota.github.io/docs/Tuya-Convert/|Tuya-Convert intro]]** * **[[https://github.com/ct-Open-Source/tuya-convert|Tuya-Convert download and help]]**