A következő sorokon az alábbi összetett problémára keresünk megoldást:
Mit tehetünk, ha otthoni környezetben futtatott szerverünket gyakran éri áramszünet (hála az áramszolgáltatónak)?
Mi történik ha napokig nem tudunk hazajutni életviteli okokból, hogy újraindítsuk, rendezzük a szolgáltatásainkat?
Mi van akkor, ha az ISP-től kapott modemünk (kombinált eszköz, de nevezzük csak így), áramszünet után időnként nem találja a kapcsolatot, csak sokadik újraindításra?
Alkalmazzunk szünetmentes tápegységet. Ez kézenfekvő megoldás, ám sajnos előfordul több órás áramkimaradás is, az akkumulátor pedig lemerül, és megint ott állunk szerver nélkül napokig, amíg haza nem jutunk. Arra azért lehetőséget ad, hogy a szerver soft-shutdown-t tudjon csinálni a hard helyett.
Állítsunk be AC power loss intézkedést az alaplap BIOS-ában. Így ha visszajön az áram, a rendszer képes lesz újra elindulni, azonban az említett modem jó eséllyel ismét néma marad. Internetkapcsolat nélkül pedig olyan mintha nem is menne az egész.
Járjunk az áram- és internetszolgáltató nyakára az áramkimaradások és a szerintük hibátlan modem cseréje miatt, de leginkább költözzünk el. Sajnos a földrajzi adottságok miatt egyik szolgáltató helyett sincs másik alternatíva, a költözés pedig nem opció.
Készítsünk egy programozható saját eszközt, amely figyeli az otthoni állapotokat, és újraindítja a hálózati készülékeket, valamint Wake On LAN-al ébreszti a megfelelő gépet. Ezzel még sokat tanulhatunk is. Na, ez már jobban tetszik.
NoceMCU devboard, ESP8266-al a fedélzeten
A NodeMCU egy kisméretű, ESP8266 Wifi modulra építkező, programozható mikrokontrolleres fejlesztő board. Tökéletes a feladatra, képes a helyi hálózathoz csatlakozni WLAN interface segítségével, kimenetein programból behúzatható és kiengedhető valamilyen relé (az arra kötött hálózati eszközök), és etethető egyszerű telefontöltőről (5V). Energiaigénye elhanyagolható, újrainduláskor pedig nem sértődik meg, és a program mikroszekundumok alatt már fut is.
Arduino IDE-ben létezik hozzá könyvtár, ezt telepítve ugyanúgy tudunk rá fejleszteni, mintha natív Arduino board lenne. A költségeket tekintve Ebay-ről 1000 forint alatt beszerezhető, ami kedvezőbb, mintha egy Arduino UNO/MEGA-t, és Wifi Shield-et alkalmaznánk.
Vázlat és megépítés
A szükséges hardver elemeket hamar összedobáltuk egy használaton kívüli, esztétikus alumínium dobozba. Elkészítettük a furatokat, meneteket, kábelezést, ügyelve a készülékház földelésére. A hálózati be- és kimenetre egy C13-C14-es aljat került, ezek egyikére csatlakozik az elosztó, amelybe a rakoncátlan modem van dugva. Egy szilárdtest relé szakítja a kimeneti ágat, ezt húzza be, vagy engedi ki a NodeMCU.
Tápegység gyanánt egy telefontöltőt építettünk be, ez a prototípus elhagyása után egy olyan hagyományos 5V-os DC tápra módosult, ami földeléssel is rendelkezik. A kimenetre elhelyeztünk egy USB aljzatot, amivel lehet figyelni a serial monitort az USB-n keresztül, és a flashelés is innen végezhető megbontás nélkül.
A board antenna részére egy SMA pigtail-t forrasztottunk, a csatlakozót a hátlapra vezettük ki. Erre azért volt szükség, hogy a hatótávot némileg növeljük, valamint hogy a WLAN interface kilásson az alumínium doboz erős árnyékoló hatása alól.
Ezen a ponton az összeállításban partnerem volt Kemencei János, ezért a többesszám.
Félkész állapotban, prototípus
Programozás
Működés röviden:
-Csatlakozás WLAN-hoz, forrásban megadott SSID-password alapján.
-Áramszünet funkció: helyi hálózati cím pingelése, majd WOL magic packet küldése ha szükséges. Internetkapcsolat ellenőrzése public IP-k pingelésével, majd hálózati eszközök újraindítása, ha nincs kapcsolat.
-Cooldown funkció: amennyiben egy konstansban megadott idő internetkapcsolat nélkül telik el, a hálózati eszközök újraindítása felfüggesztődik, és csak akkor indul újra, ha visszatér az internetkapcsolat, vagy a cooldown idő lejár (eszközkímélés).
-Folyamatos verbose tájékoztatás serial monitoron keresztül.
A szükséges vizsgálatokhoz a EPS8266Ping könyvtárat használtam fel, thx to dancol90.
Fontosabb részletek, hátha valakinek hasznos, érdekes lehet:
Szükséges könyvtárak és néhány felhasznált konstans#include <ESP8266Ping.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
IPAddress computer_ip(192, 168, 0, 109); //Ébresztendő gép statikus IP címe pingeléshez
IPAddress computers_broadcast(192, 168, 0, 255); //Adott hálózat broadcast címe
byte mac[] = {0x70, 0x8B, 0xCD, 0x7D, 0xE5, 0x83}; //Ébresztendő gép MAC címe 6 bájtos tömbben
Csatlakozás WLAN-hozboolean connectWifi() {
boolean state = true;
int i = 0;
wlanconnect_count = 0;
WiFi.disconnect();
WiFi.begin(ssid, password); //Program elején megadott stringek
Serial.print("Csatlakozás ");
Serial.print(ssid);
Serial.println(" WLAN-hoz.");
Serial.print("Folyamatban");
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
if (i > 100) {
state = false;
break;
}
i++;
}
Serial.println("");
if (state) {
Serial.print("Csatlakozva: ");
Serial.print(ssid);
Serial.println(" WLAN");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
else {
Serial.println("Csatlakozás sikertelen. Ellenőrizze a hálózatot és az azonosítási adatokat.");
Serial.print("Próbált SSID: ");
Serial.println(ssid);
Serial.print("Próbált jelszó: ");
Serial.println(password);
}
return state;
}
Itt találkoztam egy buggal, sajnos újracsatlakozáskor előfordult, hogy a kapcsolat nem jött létre, mert a board még igazából nem zárta le az előzőt (ami megszakadt). Rövid keresés után rájöttem, hogy a csatlakozás megkezdése elé beillesztett WiFi.disconnect(); (minden kapcsolat lezárása) orvosolja ezt a problémát.
WOL magic packet előállítása és küldése 102 bájtos tömb - 6xFF + 16xMACvoid sendPkt() {
byte magic_packet[102];
int i, c1, j = 0;
for (i = 0; i < 6; i++, j++) { //Tömb feltöltése 6db 0xFF-el
magic_packet[j] = 0xFF;
}
for (i = 0; i < 16; i++) { //A tömb további elemei az ébresztendő gép MAC címe 16x egymás után
for ( c1 = 0; c1 < 6; c1++, j++)
magic_packet[j] = mac[c1];
}
Udp.beginPacket(computers_broadcast, 9); //Broadcast cím, port
Udp.write(magic_packet, sizeof magic_packet); //Az egész, 102 bájtos előállított magic packet szórása egyben
Udp.endPacket();
}
Modem újraindításavoid restart_modem() {
int i = 0;
Serial.println("SSR kiengedése.");
digitalWrite(5, LOW); //Pin alacsony szintre helyezése, szilárdtest relé kiengedése
Serial.print("Várakozás az eszközök memóriavesztésére ");
Serial.print(ssr_out);
Serial.print(" sec.");
for (i = 0; i < 50; i++) {
delay(ssr_out * 20);
Serial.print(".");
}
Serial.println("");
Serial.println("SSR behúzása.");
digitalWrite(5, HIGH); //Pin magas szintre helyezése, szilárdtest relé újra behúzása
Serial.print("Várakozás az eszközök bootolására, kapcsolat kiépülésére ");
Serial.print(ssr_in);
Serial.print(" sec.");
for (i = 0; i < 100; i++) {
delay(ssr_in * 10);
Serial.print(".");
}
Serial.println("");
}
Eredmény
Összességében az elvártaknak megfelelően működik minden funkciója. Használat közben szépen közli serial monitoron, hogy éppen hol tart a program. Ez USB kapcsolaton akár logolható is egy tetszőleges eszközzel, így rögzíthetőek az események.
Innentől a "doboz" szinte akármilyen hasonló feladatra igénybe vehető, hiszen USB porton keresztül tölthető rá más program is.