doc:appunti:hardware:iot
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
doc:appunti:hardware:iot [2021/01/20 12:40] – [Configuring MQTT on Tasmota] niccolo | doc:appunti:hardware:iot [2021/01/20 17:13] (current) – removed niccolo | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== IoT - 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' | ||
- | |||
- | 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' | ||
- | * Un dispositivo, | ||
- | * Appena si **rimuove una device dalla app**, il Cloud invia al device stesso l' | ||
- | |||
- | |||
- | ==== Smart Life App ==== | ||
- | |||
- | The QR code printed on the plug itseld points to [[http:// | ||
- | |||
- | === 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/ | ||
- | * The device broadcasts on the local network using port **6667/ | ||
- | * The device communicates with several internet servers on port **8886/ | ||
- | * The SP22 can be switched on/off from the smartphone. | ||
- | |||
- | === How the app communicates witht the device === | ||
- | |||
- | * If the Smart Plug has internet connectivity, | ||
- | * If the Smart Plug does not have internet connectivty, | ||
- | * 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 " | ||
- | * With default configuration, | ||
- | |||
- | === 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/ | ||
- | |||
- | ==== 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, | ||
- | |||
- | Actually we need to: | ||
- | |||
- | * **Register** an account at **[[https:// | ||
- | * 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: | ||
- | * Industry: Other | ||
- | * Authorization Key | ||
- | * Access ID/Client ID: 4e46be08d231a017dc2c | ||
- | * Access Secret/ | ||
- | * 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/ | ||
- | |||
- | La scelta è caduta sulla **[[https:// | ||
- | |||
- | < | ||
- | 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, | ||
- | No Stats - Device Key required to poll for status | ||
- | |||
- | Scan Complete! | ||
- | </ | ||
- | |||
- | According to the instruction of the **[[https:// | ||
- | |||
- | ^ DEVICE_ID | ||
- | ^ IP_ADDRESS | ||
- | ^ LOCAL_KEY | ||
- | |||
- | Let's see how to obtain a **Tuya Developer account** on **[[https:// | ||
- | |||
- | === 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**, | ||
- | |||
- | < | ||
- | 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** | ||
- | |||
- | < | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | </ | ||
- | |||
- | < | ||
- | [ | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | ] | ||
- | </ | ||
- | |||
- | 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: | ||
- | |||
- | <code python> | ||
- | # | ||
- | import tinytuya | ||
- | d = tinytuya.OutletDevice(' | ||
- | d.set_version(3.3) | ||
- | data = d.status() | ||
- | # Show status and state of first controlled switch on device | ||
- | print(' | ||
- | print(' | ||
- | # Toggle switch state | ||
- | switch_state = data[' | ||
- | data = d.set_status(not switch_state) | ||
- | if data: | ||
- | print(' | ||
- | </ | ||
- | |||
- | 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 {' | ||
- | 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:// | ||
- | |||
- | * **[[https:// | ||
- | * **[[https:// | ||
- | |||
- | ===== Sonoff Basic R2 ===== | ||
- | |||
- | Il vantaggio di quesi **power switch intelligenti** marchiati **Sonoff**, è che sono facilmente programmabili con il firmware **[[https:// | ||
- | |||
- | {{.: | ||
- | |||
- | To **open the plastic case** of the Sonoff Basic R2 you have to unlock the four **snap fit joints**: there are two on each of the long edges. | ||
- | |||
- | {{.: | ||
- | {{.: | ||
- | |||
- | {{.: | ||
- | {{.: | ||
- | |||
- | ==== Tools required to flash the Tasmota firmware ==== | ||
- | |||
- | - **Pin headers** to be soldered on the Sonoff Basic PCB. | ||
- | - An **USB to serial adapter**. | ||
- | - The **esptool.py** flashing tool (Python program). | ||
- | - The **tasmota.bin** firmware to be uploaded (flashed) into the Sonoff Basic. | ||
- | |||
- | You can download the **esptool.py** form the **[[https:// | ||
- | |||
- | The Tasmota firmware can be downloaded from the **[[https:// | ||
- | ==== Flashing the Tasmota firmware ==== | ||
- | |||
- | To flash the Tasmota firmware I used a **GNU/ | ||
- | |||
- | - **Disconnect** the Sonoff Basic from **AC power**. | ||
- | - **Connect** the USB to **serial adapter** to the **Sonoff serial**, all the 4 wires are required: **3.3 Volt**, **TX**, **RX** and **GND**. The TX line of the adapter is connected to the RX line of Sonoff, and vice-versa. | ||
- | - **Execute each step** of the flashing procedure in this manner: | ||
- | * **Connect** the USB adapter to the computer **while holding down** the push button of the Sonoff device. Keeping the button pressed for 7 seconds is sufficient. Keeping the button pressed while power-on is required to put the device into a special programming mode. | ||
- | * **Execute** the required **esptool.py command** on the PC. | ||
- | * **Disconnect** the USB adapter from the PC. | ||
- | |||
- | This is the concise list of commands I used (remember: **each command** is executed after the Sonoff device is **booted in programming mode** as explained above!): | ||
- | |||
- | < | ||
- | ./ | ||
- | ./ | ||
- | ./ | ||
- | ./ | ||
- | </ | ||
- | |||
- | Running the command **%%./ | ||
- | |||
- | ^ flash_id | ||
- | ^ read_flash | ||
- | ^ erase_flash | ||
- | ^ write_flash | ||
- | |||
- | Here it is the output generated by the **write_flash** command: | ||
- | |||
- | < | ||
- | ./ | ||
- | esptool.py v3.0 | ||
- | Serial port / | ||
- | Connecting.... | ||
- | Detecting chip type... ESP8266 | ||
- | Chip is ESP8285 | ||
- | Features: WiFi, Embedded Flash | ||
- | Crystal is 26MHz | ||
- | MAC: c8: | ||
- | Uploading stub... | ||
- | Running stub... | ||
- | Stub running... | ||
- | Configuring flash size... | ||
- | Compressed 600960 bytes to 428969... | ||
- | Wrote 600960 bytes (428969 compressed) at 0x00000000 in 37.9 seconds (effective 127.0 kbit/s)... | ||
- | Hash of data verified. | ||
- | Leaving... | ||
- | Hard resetting via RTS pin... | ||
- | </ | ||
- | |||
- | After the **write_flash** command you can **power-cycle** the Sonoff device by unplugging and plugging the USB adapter again, this time **without holding the Sonoff button**. The LED on the Sonoff flashes in blue, the device starts into **Access Point mode** and stays this way for about **three minutes**, connect a smartphone or the notebook to it (search for an ESSID like **tasmota-xxxx**) and browse the address **%%http:// | ||
- | |||
- | **NOTICE** :!: I had some **problems connecting to the Sonoff Access Point** using the smartphone and using the notebook: sometimes the IP address were not assigned, other times the host 192.168.4.1 were not reachable. One time I succeded by setting the IP address manually (in the range 192.168.4.x), | ||
- | |||
- | ^ AP1 SSId/ | ||
- | ^ AP2 SSId/ | ||
- | ^ Hostname | ||
- | ^ CORS Domain | ||
- | |||
- | === Hardware Module Configuration === | ||
- | |||
- | After WiFi configuration, | ||
- | |||
- | * **Configure** the device **name and template**. Choose a name to identify this device and select the appropriate template. The template tells the firmware how to use the hardware (the relay and the LED): just use the default **Sonoff Basic (1)**. | ||
- | * **Configuration** => **Configure Template** => **Based on** => **Sonoff Basic (1)** | ||
- | * **Protect** the **web access** with a password (beware that it uses plain http, so password can be sniffed along the network): | ||
- | * **Configuration** => **Configure Other** => **Web Admin Password** | ||
- | * **Disable** the **[[https:// | ||
- | * Connecto to the web interface, **Main Menu** => **Console** and enter the command **WifiConfig 5**. This means //wait until selected AP is available again without rebooting// | ||
- | |||
- | === Button Reset === | ||
- | |||
- | If you have trouble connecting to a Tasmota device and the device have a button, you have at least two methods to try to recover. | ||
- | |||
- | ^ 6 short presses | ||
- | ^ Long press for 40 seconds | ||
- | ===== Controlling Tasmota via MQTT ===== | ||
- | |||
- | MQTT is a client/ | ||
- | |||
- | **WARNING**: | ||
- | ==== Installing a MQTT Broker ==== | ||
- | |||
- | On a GNU/Linux Debian host (version 10 Buster) I installed the following packages: | ||
- | |||
- | * **mosquitto** | ||
- | * **mosquitto-clients** | ||
- | |||
- | The daemon **mosquitto** is running and listening on port **TCP/ | ||
- | |||
- | With default configuration, | ||
- | |||
- | < | ||
- | mosquitto_sub -h mqtt.server.tld -t my_topic | ||
- | </ | ||
- | |||
- | < | ||
- | mosquitto_pub -h mqtt.server.tld -t my_topic -m " | ||
- | </ | ||
- | |||
- | On the first terminal you will get the message '' | ||
- | |||
- | ==== Configuring MQTT on Tasmota ==== | ||
- | |||
- | From the Tasmota **Main menu** => **Configuration** => **Configure MQTT**: | ||
- | |||
- | ^ Host | Hostname or IP address of the MQTT server. | ||
- | ^ Port | Default is 1883, which is MQTT TCP unencrypted. | ||
- | ^ Client | ||
- | ^ User | Username for authenticating on the MQTT broker, default is **DVES_USER**. | ||
- | ^ Password | ||
- | ^ Topic | Default is **%%tasmota_%06X%%**, | ||
- | ^ Full Topic | Default is **%%%prefix%/ | ||
- | |||
- | From the Tasmota **Main menu** => **Configuration** => **Configure other**: | ||
- | |||
- | ^ MQTT enable | ||
- | ^ Device Name | Default is // | ||
- | ^ Friendly Name 1 | Used by the autodiscovery feature, default is // | ||
- | |||
- | Here it is an example to **publish** an MQTT message asking the Sonoff device to **toggle the switch**: | ||
- | |||
- | < | ||
- | mosquitto_pub -h mqtt.server.tld | ||
- | </ | ||
- | |||
- | **NOTICE**: If you use a non-existent topic (e.g. a **wrong device name**), **no error is reported**. | ||
- | |||
- | Obviously the device understands the **TOGGLE**, **ON** and **OFF** messages. If you are **subscribed** to the proper MQTT topic, you will **receive a message** for each toggle: | ||
- | |||
- | < | ||
- | mosquitto_sub -h mqtt.server.tld -t " | ||
- | {" | ||
- | {" | ||
- | </ | ||
- | |||
- | === Password protect the Mosquitto broker === | ||
- | |||
- | Default Debian installation of the **mosquitto** server does not require a password from the connecting client. | ||
- | |||
- | **/ | ||
- | |||
- | < | ||
- | user username1 | ||
- | topic write gateway/ | ||
- | topic read gateway/ | ||
- | |||
- | user username2 | ||
- | topic readwrite gateway/ | ||
- | </ | ||
- | |||
- | **/ | ||
- | |||
- | < | ||
- | allow_anonymous false | ||
- | password_file / | ||
- | acl_file / | ||
- | </ | ||
- | |||
- | To manage a password file you can use the **mosquitto_passwd** tool, this command will set an **username** with a **passowrd** (asked interactively) into the **password file** (add a **%%-c%%** option to create the password file): | ||
- | |||
- | < | ||
- | mosquitto_passwd / | ||
- | </ | ||
- | |||
- | The file contains **sha512** hashes; to avoid world-read you can change the file mode to **0640**. The file is read at program start using root privileges; if the file is changed the mosquitto server must be restarted. | ||
- | |||
- | Now you have to specify the correct **username** and **password** when you execute **mosquitto_pub**, | ||
- | |||
- | < | ||
- | mosquitto_pub -h mqtt.server.tld -u ' | ||
- | Connection Refused: not authorised. | ||
- | Error: The connection was refused. | ||
- | </ | ||
- | |||
- | ===== Controlling Tasmota via HTTP GET ===== | ||
- | |||
- | The Tasmota firmware exposes an open, //admin mode//, web interface to configure and control the device status (this default can be changed). It is advisable to set a password from **Main menu** => **Configuration** => **Configure Other** => **Web Admin Password**. The default username is **admin**. | ||
- | |||
- | **WARNING**: | ||
- | |||
- | Suppose that your Tasmota device has IP address **10.0.0.114**, | ||
- | |||
- | <code bash> | ||
- | # Control the relay status: Toggle, switch it On, switch it Off. | ||
- | wget -q -O /dev/null ' | ||
- | wget -q -O /dev/null ' | ||
- | wget -q -O /dev/null ' | ||
- | </ | ||
- | |||
- | If you want to read the relay status after the command, read the output of the GET request (a JSON string): | ||
- | |||
- | <code bash> | ||
- | wget -q -O - ' | ||
- | {" | ||
- | </ | ||
- | ===== Web References ===== | ||
- | |||
- | * **[[https:// | ||
- | * **[[https:// | ||