Vlastní ovládání chytré zásuvky s firmwarem Tasmota

Delší dobu mě trápilo nespolehlivé spínání chytrého bazmeku Vocolinc přes cloud aplikaci Smart life. Většina chytrých zásuvek je jenom nějaký rebranding téhož, takže koupit něco jiného nevypadalo jako ta správná cesta. Obzvlášť, když chci „jenom“ ovládat jednu zásuvku, na kterou mám zapojené čerpadlo a nechci řešit integraci do chytré domácnosti.

Podobné udělátko je teoreticky šikovná věc. V mém případě nechcete mít neustále natlakovaný zalévací okruh z nádrže. Takže když jdete zalévat, tak si zapnete na dálku zásuvku s čerpadlem a je to. Potřebujete přecvaknout z pistole na rozstřikovač? Aplikace ťuk, rozstřikovač cvak, aplikace ťuk – a je to. Z jednoho místa pohodlně, bez dvojího obcházení domu. To by bylo, aby lenost netlačila pokrok kupředu.

Tropická vedra, když se nezalévá.

Bohužel to v praxi fungovalo jen z domova a jen někdy. Často se stávalo, že sice zásuvka byla v aplikaci on-line, ale po jejím zapnutí se nic nestalo a hodila se do off-linu. Signál na wi-fi přitom byl a zásuvka v síti také. Mimo domov (přes data/jinou wif-fi) to bylo ještě horší. To si takhle zapnete rozstřikovač a nemůžete to vypnout. Přes Apple Watch to fungovalo ještě hůř – pravděpodobně se hodinky domlouvají s telefonem a ten až s cloudem. A to už je pro to, jak je ta aplikace udělaná, sci-fi.

Náhodou jsem časem na e-shopu i4wifi v novinkách narazil na to, že se dělá chytrá zásuvka s firmwarem Tasmota. Což je alternativa do chytrých zařízení s velmi populárním ESP čipem. Můžete si to buď do zásuvky flashnout sami (což vyžaduje fyzické rozebrání mnohdy lepených zásuvek, pájení, mít programátor…), nebo pořídit už něco flashnutého. Oni to předtím skladem neměli, teď ten Tinycontrol TP29 mají. V srpnu mi řekli, že to bude možná až v prosinci, tak jsem našel a objednal alternativu od DeLocku z Amazonu a byla za 3 dny doma (jen pozor na bezkolík vpředu a na žádnou díru na kolík vzadu!). Na českých e-shopech je DeLock zásuvka tu a tam také k mání, ale v popisu se píše „je-li nahrán firmware Tasmota, můžete…“ – tak já nevím, je nahrán? 😀

Po zapojení zásuvky se připojíte na její wi-fi síť a můžete vyplnit údaje pro připojení hned ke dvěma bezdrátovým přístupovým bodům, takže se zásuvka připojí ke druhé síti, pokud bude ta první nedostupná. Samozřejmě za předpokladu, že je v dosahu. Pozor na to, pokud má druhá síť jen slabý signál – může se vám stát stejně jako mě, že po výpadku elektřiny naběhne ta vzdálenější wi-fi dřív, zásuvka se připojí k ní a její odezva bude bídná.

Budete-li upgradovat stejně jako já pro lepší pocit na poslední verzi Tasmoty (není to nutné!), rozhodně postupujte podle návodu a jděte postupně po doporučených verzích. Obzvlášť pozor budete-li upgradovat přes minimal verze, tak vždy po minimal upgradněte na „plnotučnou“ Tasmotu a né na další minimal. Dopadli byste stejně jako já – špatně a s bricknutou zásuvkou.

Máte Tasmotu připojenou do sítě? Paráda! Pak máte na její IP adrese takovouto stránku:


Po kliknutí na „Toggle“ zásuvka okamžitě sepne. Juchů! Už teď si můžete odkaz na stránku uložit do telefonu a dalších zařízení a spínat si dle libosti. Pod Configuration si můžete krom dalších věcí nastavit i časovače. Paráda!

Nicméně do zásuvky se dá posílat celá spousta příkazů. Pro mě by třeba bylo fajn zásuvku s čerpadlem zapnout jen na pár minut, když tam je nasazený ostřikovač na trávník. Předtím jsem musel doufat, že se mi přes Smart life podaří zásuvku nejen zapnout, ale i nastavit časovač na vypnutí. A potom jsem neměl jak ověřit, jestli je opravdu vypnuto, protože zařízení se mohlo ukazovat jako offline po náhodně dlouhou dobu a bohužel se tak často dělo.

Takže co si takhle udělat vlastní ovládací stránku? V domě už běží Raspberry Pi Zero pro odečet impulzů z elektroměru, takže webový server je kam jednoduše umístit (což by šlo i na Synology).

Na Raspberry jsem tedy nainstaloval NGINX (znatelně lehčí než Apache) + PHP a dal se do díla.

Za chvíli jsem měl webovku, kterou jsem lehce ostyloval a díky tomu, že můžete Tasmotě přes příkaz Backlog poslat sérii toho, co se má provést (zapni, počkej xy času, vypni), došlo i na mnou vysněné jednoklikové zapni na x minut.

Stránka na telefonu vypadá takto:


Stačí uložit jako odkaz na plochu – pro ten účel jsem si vyrobil sexy retro ikonku:


Jako další jsem chtěl mít stránku i v hodinkách. Pro ten účel stačí vytvořit zkratku, která má otevřít adresu Raspberry. To s iOS 15 a watchOS 8 přestalo fungovat, protože jsem měl zkratku jako „Otevřít URL“ místo „Zobrazit stránku“ – grr! Předtím to šlo… teď to nadávalo na „nemám čím otevřít schéma http“ (i https). Po této drobné úpravě to opět frčí a v hodinách dám zkratku Čerpadlo a zobrazí se:


Je to paráda! Navíc hodinky fungují autonomně, takže jsou to jediné co potřebuju a můžu si vesele ovládat krásně napřímo. Zabezpečení zvenčí řeším VPN, ve vnitřní síti jen nestandardním portem (je to pro mě dostačující, ale je možné si vše zaheslovat).

A nakonec kód samotné stránky:

<?php

// IP address of power outlet with Tasmota firmware
$ip = "192.168.150.50";

if(isset($_GET['request']))
{
    echo "<div class='requestinfo'>";
    echo "Returned: <b>" . request($ip, $_GET['request']) . "</b>";
    echo "</div>";
}

function request($ip, $request)
{
    $request = str_replace([" ", ";"], ["%20", "%3B"], $request);
    $request = "http://" . $ip . "/cm?cmnd=" . $request;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $r = curl_exec($ch);
    curl_close($ch);

    return $r;
}

?>
<html>
<head>
<title>Čerpadlo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="watering-pump.png" />

<style>
    body { font-size: 2rem; background: #282926; }
    a { text-decoration: none; }
    .button { margin: 5px auto; padding: 20px 0; color: darkgreen; border: 2px solid black; background: #f4ffc0; font-weight: bold; display: block; width: 95%; text-align: center; border-radius: 15px; }
    .green { background: #198754; color: white }
    .green:hover { background: #157347; }
    .red { background: #DC3545; color: white; }
    .red:hover { background: #BB2D3B; }
    .info { background: #FFC107; color: black; }
    .info:hover { background: #FFCA2C; }
    .state { background: #4480b5; color: white; margin: 0 auto; padding: 5px 0; border: 2px solid black; font-weight: normal; display: block; width: 95%; text-align: center; border-radius: 15px; }
    .state span { font-weight: bold }
    .requestinfo { color: saddlebrown; background: lightblue; margin: 20px auto; padding: 20px; border: 2px solid #1e527f; text-align: center; width: 90%; }
    hr { content: ""; clear: both; display: table; }
</style>
</head>

<body>
<?php

    // Is it ON or OFF?
    $state = request($ip, "Power");
    $state = json_decode($state, true);

    if($state["POWER"] == "ON")
    {
        echo "<a href='?'><div class='state'>Stav: <span>Zap</span>nuto</div></a>";
    }
    else
    {
        echo "<a href='?'><div class='state'>Stav: <span>Vyp</span>nuto</div></a>";
    }

?>
<p>
    <a href='?request=Power on' class='button green'>Zapnout</a><br>
    <a href='?request=Power off' class='button red'>Vypnout</a><br>
    <a href='?request=Backlog Power on;Delay 600; Power off' class='button info'>Na 1 minutu</a><br>
    <a href='?request=Backlog Power on;Delay 1200; Power off' class='button info'>Na 2 minuty</a><br>
    <a href='?request=Backlog Power on;Delay 1800; Power off' class='button info'>Na 3 minuty</a><br>
    <a href='?request=Backlog Power on;Delay 3000; Power off' class='button info'>Na 5 minut</a><br>
    <a href='?request=Backlog Power on;Delay 3600; Power off' class='button info'>Na 6 minut</a><br>
    <a href='?request=Backlog Power on;Delay 4200; Power off' class='button info'>Na 7 minut</a><br>
    <a href='?request=Backlog Power on;Delay 4800; Power off' class='button info'>Na 8 minut</a><br>
    <a href='?request=Backlog Power on;Delay 5400; Power off' class='button info'>Na 9 minut</a><br>
    <a href='?request=Backlog Power on;Delay 6000; Power off' class='button info'>Na 10 minut</a>
</p>
</body>
</html>

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *