Shelly Plug S Gen3, chytrá zásuvka pro bastlíře

Odpovědět
Pablo74
Příspěvky: 177
Registrován: 03 lis 2019, 17:00

Shelly Plug S Gen3, chytrá zásuvka pro bastlíře

Příspěvek od Pablo74 » 06 zář 2026, 11:36

Rád se podělím o zkušenosti se zásuvkou Shelly Plug S Gen3 a to z "lokálního" pohledu: žádný Shelly Cloud, žádná oficiální Shelly aplikace.
Celé ovládání běží čistě lokálně – přes BLE a přes lokální HTTP RPC v domácí Wi-Fi síti. Tenhle první příspěvek bude spíš přehledový, další budou navazovat konkrétními detaily a problémy, které jsme spolu s AI řešili a (některé) vyřešili.

Bez cloudu?
Shelly Cloud je fajn, pokud vám nevadí účet u výrobce a závislost na jeho serverech. Jakmile ale chcete zásuvku sdílet mezi víc lidmi bez cloudového účtu, nebo prostě chcete mít jistotu, že vám zásuvka půjde ovládat i bez internetu, dává smysl jít lokální cestou. Shelly to naštěstí umožňuje – zařízení má plnohodnotné lokální RPC rozhraní, které nepotřebuje jejich aplikaci ani cloud.

HW v kostce
- řídicí čip ESP32
- relé pro spínání zátěže
- RGB LED indikace, samostatně nastavitelná barva/jas pro stav zapnuto/vypnuto
- jedno fyzické tlačítko s více funkcemi – krátký stisk přepíná výstup, podržení 5 s znovu otevře BLE párovací okno, podržení 10 s = tovární reset

SW v kostce – lokální RPC
Celé zařízení se ovládá přes JSON-RPC rozhraní, dostupné dvěma cestami:
- lokálně po HTTP (v rámci domácí Wi-Fi, žádný cloud)
- přes BLE (Bluetooth Low Energy), bez nutnosti použít Wi-Fi

Metody jsou rozdělené do komponent – namátkou Switch (ovládání výstupu, Switch.Set, Switch.GetStatus), Sys (systémové info a config), WiFi, Cloud (dá se explicitně vypnout), BLE, Script (uživatelské skripty) a PLUGS_UI (nastavení LED). Užitečný detail: Switch.Set má rovnou parametr toggle_after (v sekundách) – zásuvka se sama vrátí do opačného stavu bez nutnosti posílat druhý příkaz.

skriptování (mJS)
Shelly umí interně uložit a spustit vlastní skripty přímo na zařízení (jazyk mJS, odlehčený JavaScript). Skript se nahraje buď přes její rozhraní v prohlížeči nebo vzdáleně přes Script.Create a Script.PutCode (po částech), a pomocí Script.SetConfig se dá nastavit, aby se spouštěl automaticky při startu zařízení. Výhoda je zásadní – takový skript běží přímo na ESP32 v zásuvce; funguje i v situaci, kdy telefon není k zásuvce vůbec připojen Typické využití je třeba časované zapnutí/vypnutí bez závislosti na klientovi.

nastavení LED
Barvy i jas LED se dají nastavit zvlášť pro režim zásuvky ON/OFF.

komunikace přes BLE
Zásuvka po zapnutí (nebo po podržení tlačítka 5 s) otevře 15minutové párovací okno, ve kterém se dá spárovat s mobilem či tabletem (přes BLE). Podporováno je až 20 současně spárovaných klientů. Přes BLE se posílá stejné JSON-RPC jako po HTTP, jen zabalené do BLE charakteristik.

Už toho mám zprovozněno víc než jen zapnutí/vypnutí, které ovládám jak z mobilu, tak i z notebooku.

Pablo74
Příspěvky: 177
Registrován: 03 lis 2019, 17:00

Re: Shelly Plug S Gen3, chytrá zásuvka pro bastlíře

Příspěvek od Pablo74 » 16 zář 2026, 04:26

Shelly Plug S Gen3 – BLE protokol do detailu (a proč vás firmware 2.0.0 může zaskočit)

Navazuji na minulý příspěvek. Tady je konkrétní BLE protokol, jak jsme ho s AI (Anthropic Claude Sonnet 5) reverse-engineerovali a ověřili na reálném hardwaru, a hlavně bezpečnostní past, do které jsme spadli při přechodu z firmwaru 1.7.3 na 2.0.0.

BLE RPC – service a charakteristiky

Pro Shelly Gen2+ zařízení (platí i pro Plug S Gen3) je RPC service UUID:

Kód: Vybrat vše

5f6d4f53-5f52-5043-5f53-56435f49445f
(tohle je z oficiální Shelly knowledge base, ne z odhadu komunity – starší UUID, které kolovalo po fórech, je jiné a nefunguje spolehlivě).
Pod ním jsou tři charakteristiky:

- charData (...5f64-6174615f5f5f) – vlastní datový přenos
- charTxCtl (...5f74-785f63746c5f) – řízení odesílání
- charRxCtl (...5f72-785f63746c5f) – řízení příjmu

formát přenosu
Protokol je jednoduchý: do TX/RX control charakteristik se posílá 4bajtová délka payloadu (big-endian), samotný JSON-RPC payload se pak posílá po částech (chunky ~180 B) do datové charakteristiky. RxCtl a datová odpověď se čtou explicitním pollingem, ne přes notify/subscribe – to je důležitý detail, pokud si píšete vlastního BLE klienta.

párování a bonding
Párovací okno je otevřené 15 minut po každém zapnutí zásuvky (ne jen při prvním spuštění) a dá se kdykoliv znovu otevřít podržením fyzického tlačítka na 5 s (10 s = tovární reset). Zásuvka umí držet bondy až s 20 klienty současně, takže sdílení mezi víc zařízeními/lidmi není problém.

past č. 1 – Secure provisioning (firmware 1.7.5+)
Tohle nás pěkně překvapilo. Shelly kvůli kybernetické bezpečnosti zavedlo od firmwaru 1.7.5 funkci "Secure provisioning": jakmile zařízení poprvé dostane IP adresu na Wi-Fi, automaticky se do 5 minut vypne BLE RPC (a zavře se i otevřené AP), pokud předtím nebylo nastaveno AP heslo. A jakmile se AP heslo jednou nastaví, nejde ho vrátit zpět na otevřené/bez hesla. Pro architekturu založenou čistě na BLE bez hesla (typicky pokud chcete zůstat mimo cloud, ale zásuvku přesto připojit k domácí Wi-Fi kvůli vypnutí AP režimu) je to zásadní problém – jeden konkrétní kus zásuvky nám takhle nechtěně "zamrzl" a BLE RPC na ní přestalo fungovat pár minut po připojení k Wi-Fi.

past č. 2 – šifrované GATT ve firmwaru 2.0.0
Ještě zajímavější past přišla s firmwarem 2.0.0. Podle oficiální dokumentace zařízení od této verze vyžaduje pro veškerou BLE RPC komunikaci šifrované a autentizované GATT spojení – starší firmware (1.7.3, se kterým byla moje aplikace původně stavěná a testovaná) používal obyčejné nešifrované GATT čtení/zápis.

Reálný projev: zásuvka po upgradu na 2.0.0 se v telefonu i mé aplikaci tvářila jako spárovaná (viditelná v systémovém Bluetooth i ve vlastním device pickeru), ale komunikace s ní nešla vůbec – moje aplikace ji hlásila jako nedostupnou.

Přes logy bluetoothd jsme to dohledali přesně: moje aplikace zapíše do `txCtl` charakteristiky → zařízení odpoví LE_ATT_ERROR_INSUFFICIENT_AUTHORIZATION → OS (na notebooku) korektně spustí SMP párování → Shelly zásuvka sama párování odmítne s chybou "Peer sent Pairing Failed with reason=5" (SMP reason 5 = "Pairing Not Supported"). Zápis pak trvale selže. Vyloučili jsme Matter (bylo vypnuté) i chybu firmwaru (stejné chování na 2.0.1-beta1).

řešení problému

Podle oficiální dokumentace BLE komponenty je potřeba před novým bondem explicitně zavolat RPC BLE.StartPairing po lokální síti (HTTP), např.:

Kód: Vybrat vše

http://<ip zásuvky>/rpc/BLE.StartPairing?timeout=60
Bez toho zařízení nové párování legitimně odmítne (odtud ten reason=5). Jakmile jednou existuje bond, další připojení se autentizuje automaticky, žádné další volání BLE.StartPairing už není potřeba. Bondy přežívají restart zařízení, pořád platí limit 20 klientů.

zapeklitý detail navíc
Jakmile jednou párování selže, operační systém (potvrzeno na notebooku a mobilu) si interně "zapamatuje", že zařízení párování odmítá, a při dalších pokusech se o SMP handshake ani nesnaží – a to i po správném zavolání BLE.StartPairing. Co nakonec zafungovalo:

- na notebooku: kompletní restart systému (žádný jiný workaround jsme nenašli)
- na mobilu: zapomenutí zařízení v systémovém Bluetooth + smazání starého bondu přímo na zásuvce přes BLE.DeletePairedDevice?addr="<mac>" (adresu zjistíte přes BLE.ListPairedDevices) + několik opakovaných pokusů přímo z mé aplikace (ne přes systémové párovací okno)

praktický dopad pro vaše projekty
Pokud stavíte cokoliv, co má zásuvku ovládat čistě přes BLE bez cloudu:

- na firmware 1.7.x počítejte s tím, že jakmile zásuvku připojíte k Wi-Fi bez nastaveného AP hesla, BLE RPC vám do 5 minut spadne
- na firmware 2.0.0+ musíte před prvním párováním nového klienta zavolat BLE.StartPairing po lokální síti – tzn. telefon či notebook musí být v momentě prvního párování na stejné Wi-Fi jako zásuvka (přes BLE samotné to obejít nejde, zařízení párování vyžaduje i ve stavu complete)
- tahle podmínka platí jen pro první spárování nového klienta – běžné ovládání po spárování jede čistě přes BLE, bez potřeby Wi-Fi/internetu

---

Napsáno s využitím AI.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host