Add Tuya Cloud integration; 2-step add-board wizard; DP value formatting
- Tuya Cloud Gateway driver (tuya-device-sharing-sdk):
- QR-code auth flow: user-provided user_code, terminal_id/endpoint
returned by Tuya login_result (mirrors HA implementation)
- Device sync, toggle DP, rename, per-device detail page
- category → kind mapping; detect_switch_dps helper
- format_dp_value: temperature (÷10 + °C/°F), humidity (+ %)
registered as 'tuya_dp' Jinja2 filter
- TuyaDevice model (tuya_devices table)
- Templates:
- tuya/gateway.html: device grid with live-reading sensor cards
(config/threshold keys hidden from card, shown on detail page)
- tuya/device.html: full status table with formatted DP values
- tuya/auth_settings.html: user_code input + QR scan flow
- Add-board wizard refactored to 2-step flow:
- Step 1: choose board type (Cloud Gateways vs Hardware)
- Step 2: type-specific fields; gateways skip IP/relay fields
- Layout builder: Tuya chip support (makeTuyaChip, tuya_update socket)
- requirements.txt: tuya-device-sharing-sdk, cryptography
This commit is contained in:
@@ -9,6 +9,7 @@ from app import db
|
||||
from app.models.layout import Layout
|
||||
from app.models.board import Board
|
||||
from app.models.sonoff_device import SonoffDevice
|
||||
from app.models.tuya_device import TuyaDevice
|
||||
|
||||
layouts_bp = Blueprint("layouts", __name__)
|
||||
|
||||
@@ -53,6 +54,7 @@ def builder(layout_id: int):
|
||||
for b in boards:
|
||||
bd = {"id": b.id, "name": b.name, "online": b.is_online,
|
||||
"relays": [], "inputs": [], "sonoff_channels": [],
|
||||
"tuya_channels": [],
|
||||
"board_type": b.board_type}
|
||||
|
||||
# ── Standard relay/input boards ──────────────────────────────────────
|
||||
@@ -104,6 +106,33 @@ def builder(layout_id: int):
|
||||
"isOnline": dev.is_online,
|
||||
})
|
||||
|
||||
# ── Tuya Cloud sub-devices ────────────────────────────────────────────
|
||||
if b.board_type == "tuya_cloud":
|
||||
TUYA_KIND_ICON = {
|
||||
"switch": "bi-toggles",
|
||||
"light": "bi-lightbulb-fill",
|
||||
"fan": "bi-fan",
|
||||
"sensor": "bi-thermometer-half",
|
||||
"cover": "bi-door-open",
|
||||
}
|
||||
tuya_devs = TuyaDevice.query.filter_by(board_id=b.id).order_by(
|
||||
TuyaDevice.name).all()
|
||||
for dev in tuya_devs:
|
||||
icon = TUYA_KIND_ICON.get(dev.kind, "bi-plug")
|
||||
for dp in dev.switch_dps:
|
||||
idx = dev.switch_dps.index(dp)
|
||||
label = (dev.name if dev.num_channels == 1
|
||||
else f"{dev.name} – Ch{idx + 1}")
|
||||
bd["tuya_channels"].append({
|
||||
"deviceId": dev.device_id,
|
||||
"channel": dp, # dp_code string, e.g. "switch_1"
|
||||
"name": label,
|
||||
"icon": icon,
|
||||
"kind": dev.kind,
|
||||
"isOn": dev.status.get(dp, False),
|
||||
"isOnline": dev.is_online,
|
||||
})
|
||||
|
||||
boards_data.append(bd)
|
||||
|
||||
return render_template(
|
||||
|
||||
Reference in New Issue
Block a user