You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Technical Write-Up: Selective Room/Zone Cleaning via Local API (Tuya Local / TinyTuya) on Airrobo T20+ (Abir X9 Platform)## Overview & Device Background
This write-up covers the challenges and ultimate pragmatical solution for integrating the Airrobo T20+ Lidar robot vacuum into Home Assistant using purely local control (Tuya Local / LocalTuya / TinyTuya).
Internally, the Airrobo T20+ is built on the Abir X9 OEM hardware platform. It utilizes Tuya protocol version 3.3 and communicates via standard Data Points (DPs) for basic functions, but uses a highly restrictive, encrypted binary payload on DP 15 (raw/hex type) for advanced map-based navigation features like room selection, pinning, and zoning.
1. The Core Problem: Dynamic Token Verification
During extensive packet sniffing and network monitoring using tinytuya monitor, we attempted to intercept and replay the Base64/Hex payloads sent to DP 15 when triggering specific room cleanings from the official Smart Life / Tuya app.
Why Static Local Commands Fail for Rooms:
Command Rejection: Sending a previously intercepted room cleaning payload (e.g., targeting Room DP 101) via local API (tinytuya or vacuum.send_command) successfully reaches the hardware layer, but the robot's mainboard immediately overwrites the state back to false and defaults to a global auto-clean (smart mode).
The Mechanism: The Abir firmware forces a strict security kernel. Every map-based room cleaning command sent to DP 15 requires an unencrypted map header, a base station offset, and a dynamic session token / sequence ID generated in real-time by the Tuya Cloud.
The Result: Without an active internet connection to synchronize these cryptographic session tokens, static replayed room payloads are instantly rejected by the vacuum's local firmware. True offline selective room cleaning is hard-blocked by the vendor kernel.
2. The Breakthrough: Exploiting DP 15 Vulnerabilities
While testing alternative app features via network sniffing, we discovered two crucial anomalies where the vacuum handles data differently, allowing us to bypass the cloud-token enforcement locally:
Discovery A: "Pin & Go" (pose mode)
When dropping a pin on the app map, the vacuum switches work_mode (DP 4) to "pose" and receives a very short payload on DP 15 containing pure X/Y coordinate vectors.
The Glitch: Because this mode bypasses room segment boundary verification, the firmware does not validate cloud tokens. It accepts the local payload unconditionally.
The Vacuum Behavior: Upon arriving at the target coordinates, the Abir firmware automatically triggers a local spot clean at that location and returns to the base station afterwards.
Discovery B: "Zone Clean" (zone mode)
When drawing a custom cleaning rectangle in the app, it sends a longer combined string to DP 15 containing the box coordinates.
The Glitch: Just like the pin mode, the zone payload is mathematically hardcoded against the local map coordinate system and does not expire. Replaying it locally works reliably.
3. The Catch: Flashing RAM Registers
During local automation testing, we encountered one final hardware restriction: The robot only ever executed the last used spot/zone point triggered from the official smartphone app.
The Cause: The robot does not store new coordinates in its flash memory when received in a standby or charging state on the dock. It keeps the last official cloud-synced coordinates in its volatile RAM register. Local payloads sent to an idle robot fail to overwrite this register.
The Solution: The robot's firmware opens its data registers for write access only after it physically starts moving and leaves the charging contacts.
4. The Final Offline Pragmatic Solution
To achieve 100% reliable, internet-independent automation, we developed a "Live Flight Injection" strategy via Python scripts (tinytuya).
The script works by waking up the robot into a standard, globally allowed auto-cleaning mode (smart). Once the robot backs off the dock and drives for 4 seconds, its data registers unlock. The script then highjacks the flight mid-air by injecting the precise local Hex payload, switching the mode, and forcing the vacuum to redirect seamlessly to the target area.
Script Implementation (/config/airrobo_clean.py)
This universal script is stored in Home Assistant and accepts hardcoded Hex payloads to avoid Linux shell argument escaping issues.
import tinytuya
import base64
import time
import sys
1. Map your intercepted Base64 payloads here# Convert the long combined strings captured from tinytuya monitor into clean HexZONES = {
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Technical Write-Up: Selective Room/Zone Cleaning via Local API (Tuya Local / TinyTuya) on Airrobo T20+ (Abir X9 Platform)## Overview & Device Background
This write-up covers the challenges and ultimate pragmatical solution for integrating the Airrobo T20+ Lidar robot vacuum into Home Assistant using purely local control (Tuya Local / LocalTuya / TinyTuya).
Internally, the Airrobo T20+ is built on the Abir X9 OEM hardware platform. It utilizes Tuya protocol version 3.3 and communicates via standard Data Points (DPs) for basic functions, but uses a highly restrictive, encrypted binary payload on DP 15 (raw/hex type) for advanced map-based navigation features like room selection, pinning, and zoning.
1. The Core Problem: Dynamic Token Verification
During extensive packet sniffing and network monitoring using tinytuya monitor, we attempted to intercept and replay the Base64/Hex payloads sent to DP 15 when triggering specific room cleanings from the official Smart Life / Tuya app.
Why Static Local Commands Fail for Rooms:
Command Rejection: Sending a previously intercepted room cleaning payload (e.g., targeting Room DP 101) via local API (tinytuya or vacuum.send_command) successfully reaches the hardware layer, but the robot's mainboard immediately overwrites the state back to false and defaults to a global auto-clean (smart mode).
The Mechanism: The Abir firmware forces a strict security kernel. Every map-based room cleaning command sent to DP 15 requires an unencrypted map header, a base station offset, and a dynamic session token / sequence ID generated in real-time by the Tuya Cloud.
The Result: Without an active internet connection to synchronize these cryptographic session tokens, static replayed room payloads are instantly rejected by the vacuum's local firmware. True offline selective room cleaning is hard-blocked by the vendor kernel.
2. The Breakthrough: Exploiting DP 15 Vulnerabilities
While testing alternative app features via network sniffing, we discovered two crucial anomalies where the vacuum handles data differently, allowing us to bypass the cloud-token enforcement locally:
Discovery A: "Pin & Go" (pose mode)
When dropping a pin on the app map, the vacuum switches work_mode (DP 4) to "pose" and receives a very short payload on DP 15 containing pure X/Y coordinate vectors.
Discovery B: "Zone Clean" (zone mode)
When drawing a custom cleaning rectangle in the app, it sends a longer combined string to DP 15 containing the box coordinates.
3. The Catch: Flashing RAM Registers
During local automation testing, we encountered one final hardware restriction: The robot only ever executed the last used spot/zone point triggered from the official smartphone app.
4. The Final Offline Pragmatic Solution
To achieve 100% reliable, internet-independent automation, we developed a "Live Flight Injection" strategy via Python scripts (tinytuya).
The script works by waking up the robot into a standard, globally allowed auto-cleaning mode (smart). Once the robot backs off the dock and drives for 4 seconds, its data registers unlock. The script then highjacks the flight mid-air by injecting the precise local Hex payload, switching the mode, and forcing the vacuum to redirect seamlessly to the target area.
Script Implementation (/config/airrobo_clean.py)
This universal script is stored in Home Assistant and accepts hardcoded Hex payloads to avoid Linux shell argument escaping issues.
import tinytuya
import base64
import time
import sys
1. Map your intercepted Base64 payloads here# Convert the long combined strings captured from tinytuya monitor into clean HexZONES = {
}
if len(sys.argv) < 2 or sys.argv[1] not in ZONES:
print("Error: Please provide a valid target zone.")
sys.exit(1)
target_hex = ZONES[sys.argv[1]]
Connect to the vacuum locallydevice = tinytuya.OutletDevice('YOUR_DEVICE_ID', 'YOUR_VACUUM_IP', 'YOUR_LOCAL_KEY')
device.set_version(3.3)
print("1. Launching standard smart clean to physically undock...")undock = device.generate_payload(tinytuya.CONTROL, {'4': 'smart', '1': True})
device.send(undock)
Crucial 4-second delay for the charging state to clear and open RAM registers
print("Waiting 4 seconds for registers to unlock...")
time.sleep(4)
print(f"2. Hijacking flight. Injecting coordinates for: {sys.argv[1]}")dps_payload = {
'4': 'zone', # Use 'pose' if replaying a Pin&Go string
'15': target_hex
}payload = device.generate_payload(tinytuya.CONTROL, dps_payload)
device.send(payload)
print("3. Confirming local execution command...")start = device.generate_payload(tinytuya.CONTROL, {'1': True})
device.send(start)
print("Success. Payload injected into volatile memory.")
Home Assistant Integration (configuration.yaml)
shell_command:
clean_kitchen_local: "python3 /config/airrobo_clean.py kitchen"
clean_tv_spot_local: "python3 /config/airrobo_clean.py tv_spot"
All reactions