From 7eaa0674d83351828a2e235752d21f160b5fe9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20=C5=A0ijanec?= Date: Sat, 14 Dec 2019 20:55:18 +0100 Subject: vse ostalo --- data/www/0.html | 8 ++ data/www/1.html | 137 +++++++++++++++++++++++++++++ data/www/2.html | 40 +++++++++ data/www/3.html | 9 ++ data/www/4.html | 9 ++ data/www/css/main.css | 25 ++++++ data/www/index.html | 32 +++++++ data/www/kazalo.html | 15 ++++ data/www/redirect.html | 10 +++ f000_sijaneciot.ino | 39 +++++++++ f010_raznefunkcije.ino | 164 ++++++++++++++++++++++++++++++++++ f015_apihandler.ino | 234 +++++++++++++++++++++++++++++++++++++++++++++++++ f020_setup.ino | 71 +++++++++++++++ f030_httpserver.ino | 1 + f050_loop.ino | 4 + 15 files changed, 798 insertions(+) create mode 100644 data/www/0.html create mode 100644 data/www/1.html create mode 100644 data/www/2.html create mode 100644 data/www/3.html create mode 100644 data/www/4.html create mode 100644 data/www/css/main.css create mode 100644 data/www/index.html create mode 100644 data/www/kazalo.html create mode 100644 data/www/redirect.html create mode 100644 f000_sijaneciot.ino create mode 100644 f010_raznefunkcije.ino create mode 100644 f015_apihandler.ino create mode 100644 f020_setup.ino create mode 100644 f030_httpserver.ino create mode 100644 f050_loop.ino diff --git a/data/www/0.html b/data/www/0.html new file mode 100644 index 0000000..9fa9527 --- /dev/null +++ b/data/www/0.html @@ -0,0 +1,8 @@ + + + + +Glavna stran +
Anton Luka Šijanec, 14. november 2019
+

Tole je predloga, spisana za IoT čipe (prilagojena za ESP8266). Izdelal sem jo za potrebe projektne naloge pri fiziki v prvem letniku.


+Preberi še: Nastavitve omrežja diff --git a/data/www/1.html b/data/www/1.html new file mode 100644 index 0000000..c75f0b3 --- /dev/null +++ b/data/www/1.html @@ -0,0 +1,137 @@ + + + + + +Nadzorna plošča +
Anton Luka Šijanec, 13. december 2019
+
+ + + + + + + + + + + + + +
+zadnja zahteva na strežnik: + + +
+ +
vrednost: +
+
+
+
+ +
+
+
+
+ + +
+
+ +
+
+ +
+
+
+ + +kanal: +skrij dostopno točko? ne da +spoofan mac naslov čipa (neobvezno): + +
+
+
+ + + +spoofan mac naslov ESP-čipa (neobvezno): + +
+
7

+
+ +
+
+
+
+ Hz + +
+
+
+ za mikrosekund + +
+(potrebuje pin D0/GPIO16 priklopljen na RST pin) +
+
+ + + +
+
+
+
+ + + + + + +
Če izpolnite samo sekunde bodo upoštevane kot UNIX timestamp. +
+
+
+ + + +
SPIFFS, ki se uporablja za shranjevanje datotek ne pozna map, poševnice bodo samo del imena datoteke, torej premik cele mape ni možen. +
To je uporabno, ker FTP klienti ne podpirajo poševnic v imenih datotek, torej boste lahko datoteke postavljali le v korenu shrambe, s tem APIjem jih lahko premaknete v druge mape. +
+
+
+Preberi še: Glavna stran diff --git a/data/www/2.html b/data/www/2.html new file mode 100644 index 0000000..04eb96a --- /dev/null +++ b/data/www/2.html @@ -0,0 +1,40 @@ + + + + +Dokumentacija API klicev prek HTTP strežnika +
Anton Luka Šijanec, 13. december 2019
+

+Klici se delajo z GET ali POST zahtevami na virtualno podmapo strežnika /api/
+Kot argumente uporabimo argumente z vrednostmi po RFC specifikaciji, bodi si v URI-ju ali v POST telesu.
+Priporočam uporabo GET zahtev, saj zafrkavanje z Content-Length headerji ni potrebno. +

+Vse zahteve so avtenticirane z uporabo WWW-Authentication standarda z geslom, ki ga nastavite po meri. Uporabniško ime je sijaneciot (oziroma program_ime, če to spremenljivko spremenite), geslo pa lahko spreminjate in je privzeto prav tako nastavljeno na program_ime.
+Priporočam, da geslo pred priklopom v večjo mrežo ali internet spremenite.
+Sprememba gesla: prek FTP strežnika, datoteka /403/webgeslo.txt ali z API ukazom /api/pwd?g=novogeslo
+

+Kode napak so standardne, če niste avtenticirani, dobite 401, če je dostop prepovedan je 403, napaka na strani strežnika je 5xx, uporabniška napaka/napaka klienta je 4xx, preusmeritve so 3xx, status OK pa je 2xx.
+

+NUJNO! pri API ukazu ne napišite zadnje poševnice, /api/pwd ni isto kot /api/pwd/, slednja bo vrnila 404: Napačen ukaz ali napačno ime datoteke. +

+Spodaj so našteti podprti ukazi, za argumente posameznega ukaza pa zahtevajte ukaz brez argumentov. Če argumentov ne navedete in so za izvedbo ukaza potrebni, tako ali tako dobite napako 400: Napačna zahteva in izpiše se vam seznam potrebnih in opcijskih argumentov, razen če ni drugače navedeno; na primer ukaz /api/rst ne potrebuje argumentov in takoj ponovno zažene sistem. +

+

+  /api/pin - ročna nastavitev pinov (branje in pisanje)
+  /api/res - prikaz resursov sistema
+  /api/sap - nastavitev dostopne točke
+  /api/sta - priklop na drugo dostopno točko
+  /api/gid - pridobi informacije o napravi in o omrežju
+  /api/pwm - nastavi frekvenco pulzoširinske modulacije (brez argumentov pove trenutno vrednost)
+  /api/rst - znova zažene sistem in programje (brez argumentov)
+  /api/slp - globoko spanje za n mikrosekund
+  /api/now - vrne podatek o trenutnem času v obliki UNIX časovnega žiga (brez argumentov)
+  /api/pwd - sprememba gesla
+  /api/tms - nastavitev časa (ob povezavi v splet se čas sicer vsakih 300 sekund posodobi iz 0.pool.ntp.org)
+  /api/ren - preimenovanje datotek, pod "haubo" isto kot /api/mov
+  /api/mov - premikanje datotek, pod "haubo" isto kot /api/ren
+  
+  /test - vedno vrne 200: OK, za namen testiranje povezave, npr. če je kontrolna plošča še vedno povezana na napravo.
+
+


+Preberi še: Dokumentacija API klicev prek HTTP strežnika diff --git a/data/www/3.html b/data/www/3.html new file mode 100644 index 0000000..0d3d7b9 --- /dev/null +++ b/data/www/3.html @@ -0,0 +1,9 @@ + + + + +3333333333333 SLIKA +
Anton Šijanec, 13. februar 2018
+

Sem Anton Luka Šijanec, star sem 13 let in to, ker ravnokar gledate je moj prvi HTML/CSS template. Čisto sam sem ga ročno natipkal, brez kopiraj-prilepi. Če česa nisem vedel, sem si v LibreOffice naredil to, kar sem hotel na strani, potem pa sem shranil kot HTML, vendar sem si v LibreOffice dokumentu pogledal samo kako značko ali atribut, nisem kopiral direktno. Za tabelni stil me je navdihnila stran ARK Komarov(klik, če imaš Internet), ampak sploh nisem pogledal Izvirne kode, samo začel sem delati. Da bi naredil stran, sem se spomnil, ko je učiteljica za informatiko razlagala HTML značko table. Doma sem brez Interneta naredil stran v geditu na Ubuntuju. +

Ugotovil sem, da Chromixium boljše prikaže stran kot Firefox, ker ima več prostora in naslovna vrstica ni tako debela, vendar sem težavo odpravil tako, da za velikost kakšnih elementov v strani uporabim procente starševskega elementa, za kakšne pa velikost v pikslih, tako, da je stran primerna za velik nabor namiznih brskalnikov (ni testirano na mobilnih napravah).

UPORABA STILA: Stil lahko uporabiš kot svojo stran, le navesti me moraš kot avtorja. Prosim razmisli o donaciji (crypto/gotovina)

OPOMBA: Če želiš prikazati dodatno razpredelnico (tabelo) za reklamo (ali karkoli drugega) pod prostorom za članek, sledi navodilom v komentarju nekje med to HTML td značko za članek in med HTML tr značko za nogo. ;-)


+Preberi še: ČLANEK diff --git a/data/www/4.html b/data/www/4.html new file mode 100644 index 0000000..55285dc --- /dev/null +++ b/data/www/4.html @@ -0,0 +1,9 @@ + + + + +4444444444444 SLIKA +
Anton Šijanec, 13. februar 2018
+

Sem Anton Luka Šijanec, star sem 13 let in to, ker ravnokar gledate je moj prvi HTML/CSS template. Čisto sam sem ga ročno natipkal, brez kopiraj-prilepi. Če česa nisem vedel, sem si v LibreOffice naredil to, kar sem hotel na strani, potem pa sem shranil kot HTML, vendar sem si v LibreOffice dokumentu pogledal samo kako značko ali atribut, nisem kopiral direktno. Za tabelni stil me je navdihnila stran ARK Komarov(klik, če imaš Internet), ampak sploh nisem pogledal Izvirne kode, samo začel sem delati. Da bi naredil stran, sem se spomnil, ko je učiteljica za informatiko razlagala HTML značko table. Doma sem brez Interneta naredil stran v geditu na Ubuntuju. +

Ugotovil sem, da Chromixium boljše prikaže stran kot Firefox, ker ima več prostora in naslovna vrstica ni tako debela, vendar sem težavo odpravil tako, da za velikost kakšnih elementov v strani uporabim procente starševskega elementa, za kakšne pa velikost v pikslih, tako, da je stran primerna za velik nabor namiznih brskalnikov (ni testirano na mobilnih napravah).

UPORABA STILA: Stil lahko uporabiš kot svojo stran, le navesti me moraš kot avtorja. Prosim razmisli o donaciji (crypto/gotovina)

OPOMBA: Če želiš prikazati dodatno razpredelnico (tabelo) za reklamo (ali karkoli drugega) pod prostorom za članek, sledi navodilom v komentarju nekje med to HTML td značko za članek in med HTML tr značko za nogo. ;-)


+Preberi še: ČLANEK diff --git a/data/www/css/main.css b/data/www/css/main.css new file mode 100644 index 0000000..6834014 --- /dev/null +++ b/data/www/css/main.css @@ -0,0 +1,25 @@ + +table, tr, td {border: 1px solid cyan +} + +iframe { + border: 0px +} +body {background: black; + color: white; + font-family: monospace +} +a { + color: yellow +} +a:visited { + color: yellow +} +a:hover { + color: orange +} +input { + background:black; + color:white; + font-family:monospace +} \ No newline at end of file diff --git a/data/www/index.html b/data/www/index.html new file mode 100644 index 0000000..e985b47 --- /dev/null +++ b/data/www/index.html @@ -0,0 +1,32 @@ + + + + +Začetno ogrodje za ESP8266 + + + + + + + + + + + + + +
sijanecIoT: + + + +

Ogrodje za grajenje IoT aplikacij z uporabniškim vmesnikom -- Spisal Anton Luka Šijanec, (C) 2019-- Prilagojeno za ESP8266

+ + diff --git a/data/www/kazalo.html b/data/www/kazalo.html new file mode 100644 index 0000000..9d94830 --- /dev/null +++ b/data/www/kazalo.html @@ -0,0 +1,15 @@ + + + + + + + +
. Glavna stran +
. Navodila: +
.. API dokumentacija +
. Nadzorna plošča + + + diff --git a/data/www/redirect.html b/data/www/redirect.html new file mode 100644 index 0000000..ee0a2a1 --- /dev/null +++ b/data/www/redirect.html @@ -0,0 +1,10 @@ + + + + +Stran je na /index.html + + +Stran je na /index.html, preusmerjam ... + + \ No newline at end of file diff --git a/f000_sijaneciot.ino b/f000_sijaneciot.ino new file mode 100644 index 0000000..0e6e5ee --- /dev/null +++ b/f000_sijaneciot.ino @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include "FS.h" +#include +#include +#include +#include +extern "C" { +#include +} +const int verzija[3] = {0, 0, 0}; +const char* program_ime = "sijaneciot"; +String dostopnatocka[2]; +String oddaljenadostopnatocka[2]; +bool razhroscevanje = true; +ESP8266WebServer server(80); +FtpServer ftpSrv; +File fsUploadFile; // a File object to temporarily store the received file +static const char ntpServerName[] = "0.pool.ntp.org"; +//static const char ntpServerName[] = "time.nist.gov"; +//static const char ntpServerName[] = "time-a.timefreq.bldrdoc.gov"; +//static const char ntpServerName[] = "time-b.timefreq.bldrdoc.gov"; +//static const char ntpServerName[] = "time-c.timefreq.bldrdoc.gov"; + +const int timeZone = 1; // Central European Time +//const int timeZone = -5; // Eastern Standard Time (USA) +//const int timeZone = -4; // Eastern Daylight Time (USA) +//const int timeZone = -8; // Pacific Standard Time (USA) +//const int timeZone = -7; // Pacific Daylight Time (USA) + +WiFiUDP Udp; +unsigned int localPort = 8888; // local port to listen for UDP packets + +time_t getNtpTime(); +void digitalClockDisplay(); +void printDigits(int digits); +void sendNTPpacket(IPAddress &address); diff --git a/f010_raznefunkcije.ino b/f010_raznefunkcije.ino new file mode 100644 index 0000000..9613049 --- /dev/null +++ b/f010_raznefunkcije.ino @@ -0,0 +1,164 @@ +int x2i(char *s) +{ + int x = 0; + for(;;) { + char c = *s; + if (c >= '0' && c <= '9') { + x *= 16; + x += c - '0'; + } + else if (c >= 'A' && c <= 'F') { + x *= 16; + x += (c - 'A') + 10; + } + else if (c >= 'a' && c <= 'f') { + x *= 16; + x += (c - 'a') + 10; + } + else break; + s++; + } + return x; +} + +void explode(String s, String delimiter, String arr[], int ARR_LEN) { + // by timemage on #arduino/freenode + unsigned part_begin = 0; + for (size_t i = 0; i < ARR_LEN; ++i) { + const auto delim_index = s.indexOf(delimiter, part_begin); + const auto part_end = (delim_index >= 0) ? delim_index : s.length(); + + arr[i] = s.substring(part_begin, part_end); + + if (delim_index >= 0) { + part_begin = delim_index + delimiter.length(); + } + } +} + + +int pin2gpio(String in) { + in.toUpperCase(); + if (in == "A0") return int(A0); + if (in == "D0") return int(D0); + if (in == "D1") return int(D1); + if (in == "D2") return int(D2); + if (in == "D3") return int(D3); + if (in == "D4") return int(D4); + if (in == "D5") return int(D5); + if (in == "D6") return int(D6); + if (in == "D7") return int(D7); + if (in == "D8") return int(D8); + return in.toInt();// fallback to gpio +} + +String getContentType(String filename) { // convert the file extension to the MIME type + if (filename.endsWith(".html")) return "text/html"; + else if (filename.endsWith(".css")) return "text/css"; + else if (filename.endsWith(".js")) return "application/javascript"; + else if (filename.endsWith(".ico")) return "image/x-icon"; + else if (filename.endsWith(".jpg")) return "image/jpeg"; + else if (filename.endsWith(".jpeg")) return "image/jpeg"; + else if (filename.endsWith(".txt")) return "text/plain"; + else if (filename.endsWith(".pdf")) return "application/pdf"; + else if (filename.endsWith(".png")) return "image/png"; + else if (filename.endsWith(".zip")) return "application/zip"; + else if (filename.endsWith(".ttf")) return "font/ttf"; + else if (filename.endsWith(".gif")) return "image/gif"; + else if (filename.endsWith(".mp3")) return "application/ogg"; + else if (filename.endsWith(".ogg")) return "application/ogg"; + else if (filename.endsWith(".mp4")) return "application/ogg"; + else if (filename.endsWith(".gz")) return "application/x-gzip"; + else if (filename.endsWith(".xml")) return "text/xml"; + else if (filename.endsWith(".svg")) return "text/svg+xml"; + return "application/octet-stream"; +} + +bool writefile(String filepath, String contents) { + File file = SPIFFS.open(filepath, "w"); + if (!file) { + return false; + } + int bytesWritten = file.print(String(contents)); + if (bytesWritten == 0) { + return false; + } + file.close(); + return true; +} +String readfile(String filepath) { + File file = SPIFFS.open(filepath, "r"); + if (!file) { + return ""; + } + String filecontents; + while (file.available()) { + filecontents += char(file.read()); + } + file.close(); + return filecontents; +} + +String fihr(int code, String text) { // format inline html response + return "

"+String(code)+": "+text+" na koren spletišča (/)" + +"


"+program_ime+"/"+String(verzija[0])+"."+String(verzija[1])+"."+String(verzija[2]) + +"

"; +} + + +const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message +byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets + +time_t getNtpTime() +{ + IPAddress ntpServerIP; // NTP server's ip address + + while (Udp.parsePacket() > 0) ; // discard any previously received packets + Serial.println("Transmit NTP Request"); + // get a random server from the pool + WiFi.hostByName(ntpServerName, ntpServerIP); + Serial.print(ntpServerName); + Serial.print(": "); + Serial.println(ntpServerIP); + sendNTPpacket(ntpServerIP); + uint32_t beginWait = millis(); + while (millis() - beginWait < 1500) { + int size = Udp.parsePacket(); + if (size >= NTP_PACKET_SIZE) { + Serial.println("Receive NTP Response"); + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer + unsigned long secsSince1900; + // convert four bytes starting at location 40 to a long integer + secsSince1900 = (unsigned long)packetBuffer[40] << 24; + secsSince1900 |= (unsigned long)packetBuffer[41] << 16; + secsSince1900 |= (unsigned long)packetBuffer[42] << 8; + secsSince1900 |= (unsigned long)packetBuffer[43]; + return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; + } + } + Serial.println("No NTP Response :-("); + return 0; // return 0 if unable to get the time +} + +// send an NTP request to the time server at the given address +void sendNTPpacket(IPAddress &address) +{ + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); //NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} diff --git a/f015_apihandler.ino b/f015_apihandler.ino new file mode 100644 index 0000000..12c9044 --- /dev/null +++ b/f015_apihandler.ino @@ -0,0 +1,234 @@ +void handleTest() { + server.send(200, "text/plain", "200: OK"); +} + +bool preveriprijavo() { + if(!server.authenticate(program_ime, readfile("/403/webgeslo.txt").c_str())){ + server.requestAuthentication(); + return false; + } else { + return true; + } +} +void handleRoot() { + if (!preveriprijavo()) return; + server.sendHeader("Location", "/www/index.html"); + server.send(303); +} +void handleRename() { + if (!preveriprijavo()) return; + if (!server.hasArg("i") || server.arg("i") == NULL || !server.hasArg("v") || server.arg("v") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: i(z) in v (pot datoteke, npr. /www/index.html)")); + return; + } + if(SPIFFS.rename(server.arg("i"), server.arg("v"))) { + server.send(200, "text/html", fihr(200, "uspešno premaknjeno!")); + } else { + server.send(500, "text/html", fihr(500, "premikanje ni uspelo!")); + } +} +void handleTms() { // timeset + if (!preveriprijavo()) return; + if (!server.hasArg("s") || server.arg("s") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: s(ec) ter neobvezni: h(r), m(in), s(ec), d(ay), (m)o(nth), y(ear) (ce je prisoten le argument s, nastavimo kot unix timestamp, drugace kot mhsdmy)")); + return; + } + if (!server.hasArg("m") || server.arg("m") == NULL) { + setTime(String(server.arg("s")).toInt()); + server.send(200, "text/html", fihr(200, "ura nastavljena!")); + } else { + if(server.hasArg("h") && server.arg("h") != NULL && server.hasArg("m") && server.arg("m") != NULL && server.hasArg("s") && server.arg("s") != NULL && + server.hasArg("d") && server.arg("d") != NULL && server.hasArg("o") && server.arg("o") != NULL && server.hasArg("y") && server.arg("y") != NULL) { + setTime(String(server.arg("h")).toInt(), String(server.arg("m")).toInt(), String(server.arg("s")).toInt(), String(server.arg("d")).toInt(), + String(server.arg("o")).toInt(), String(server.arg("y")).toInt()); + server.send(200, "text/html", fihr(200, "ura zamenjana!")); + } else { + server.send(400, "text/html", fihr(400, "ce ze delas ura, minuta, sekunda, dan, mesec, leto; morajo biti prisotni vsi argumenti (hmsdoy)")); + } + } +} +void handlePin() { + if (!preveriprijavo()) return; + if (!server.hasArg("p") || server.arg("p") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: p(in) ter neobvezni: v(rednost) (0-1 za digital, 0-1023 za a) (glede na to ce je prisoten spremeni pinMode)")); + return; + } + if (!server.hasArg("v") && server.arg("v") != NULL) { + pinMode(pin2gpio(server.arg("p")), OUTPUT); + if(server.arg("p").substring(0, 1) == "a" || server.arg("p").substring(0, 1) == "A" || server.arg("v").toInt() > 1) { + analogWrite(pin2gpio(server.arg("p")), server.arg("v").toInt()); + } else { + digitalWrite(pin2gpio(server.arg("p")), server.arg("v").toInt()); + } + } else { + pinMode(pin2gpio(server.arg("p")), OUTPUT); + delay(1); // idk + if(server.arg("p").substring(0, 1) == "a") { + analogRead(pin2gpio(server.arg("p"))); + } else { + digitalRead(pin2gpio(server.arg("p"))); + } + } +} +void handleRes() { + if (!preveriprijavo()) return; + if (!server.hasArg("k") || server.arg("k") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: k(aj), vrednost je lahko: availheap")); + return; + } + server.send(200, "text/plain", String(ESP.getFreeHeap())); +} +void handleSetAP() { + if (!preveriprijavo()) return; + if (!server.hasArg("s") || server.arg("s") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: s(sid) ter neobvezni: p(ass), c(hannel), h(idden-bool) in m(AC address npr. EEFABC286787 APja)")); + return; + } + WiFi.softAPdisconnect(true); + if(server.hasArg("m") && server.arg("m") != NULL) { + long unsigned int mac; uint8_t macar[6]; + mac = strtoul(server.arg("m").c_str(), NULL, 16); + memcpy(macar, (char*)&mac, 6); + wifi_set_macaddr(STATION_IF, macar); + } + if (server.hasArg("h") && server.arg("h") != NULL) { + writefile("/403/hostname.txt", String(server.arg("h"))); + } + writefile("/403/wifi-ap.txt", String(server.arg("s"))+","+String(server.arg("p"))+","+String(server.arg("c"))+","+String(readfile("/403/hostname.txt"))); + WiFi.softAP(server.arg("s").c_str(), server.arg("p").c_str(), server.arg("c").toInt(), readfile("/403/hostname.txt").toInt()); + server.send(200, "text/html", fihr(200, "AP nastavljena")); +} +void handleSetSTA() { + if (!preveriprijavo()) return; + if (!server.hasArg("s") || server.arg("s") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: s(sid) ter neobvezni: p(ass), h(ostname) in m(AC address npr. EEFABC286787 STAja)")); + return; + } + WiFi.disconnect(true); + if(server.hasArg("m") && server.arg("m") != NULL) { + long unsigned int mac; uint8_t macar[6]; + mac = strtoul(server.arg("m").c_str(), NULL, 16); + memcpy(macar, (char*)&mac, 6); + wifi_set_macaddr(SOFTAP_IF, macar); + } + if (server.hasArg("h") && server.arg("h") != NULL) writefile("/403/hostname.txt", String(server.arg("h"))); + WiFi.hostname(readfile("/403/hostname.txt").c_str()); + WiFi.begin(server.arg("s").c_str(), server.arg("p").c_str()); + server.send(200, "text/html", fihr(200, "STA nastavljena")); +} +void handleGetID() { + if (!preveriprijavo()) return; + if (!server.hasArg("k") || server.arg("k") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: k(aj s(ta MAC)/a(p MAC)/i(p)/c(hipId)/h(ostname)). prebere ID, za pisanje MACa glejte /api/sta in /api/ap")); + return; + } + if(server.arg("k").startsWith("s")) { + server.send(200, "text/plain", String(WiFi.macAddress())); + } else if (server.arg("k").startsWith("a")) { + server.send(200, "text/plain", String(WiFi.softAPmacAddress())); + } else if (server.arg("k").startsWith("i")) { + server.send(200, "text/plain", WiFi.localIP().toString()); + } else if (server.arg("k").startsWith("c")) { + server.send(200, "text/plain", String(ESP.getChipId())); + } else { + server.send(200, "text/plain", String(readfile("/403/hostname.txt"))); + } +} +void handlePWM() { + if (!preveriprijavo()) return; + if (server.hasArg("v") && server.arg("v") != NULL) { + writefile("/403/pwmfreq.txt", String(server.arg("v"))); + analogWriteFreq(String(server.arg("v")).toInt()); + server.send(200, "text/html", fihr(200, "PWM nastavljena")); + } else { + server.send(400, "text/html", fihr(400, "obvezni argument: v(rednost v Hz)")); + } +} +void handleRestart() { + if (!preveriprijavo()) return; + ESP.restart(); +} +void handleDeepSleep() { + if (!preveriprijavo()) return; + if (!server.hasArg("m") || server.arg("m") == NULL) { + server.send(400, "text/html", fihr(400, "obvezni argument: m(ikrosekund)")); + return; + } + ESP.deepSleep(String(server.arg("m")).toInt()); +} +void handleUpdate() { + if (!preveriprijavo()) return; + int vraat; + if (!server.hasArg("g") || server.arg("g") == NULL || !server.hasArg("p") || server.arg("p") == NULL) { + server.send(400, "text/html", fihr(400, "obvezna argumenta: g(ostiteljev IP) in p(ot /do/datoteke.bin), neobvezen: v(rata HTTP (privzeta 80))")); + return; + } + if(String(server.arg("v")).toInt() > 0 && String(server.arg("v")).toInt() < 65536) { + vraat = String(server.arg("v")).toInt(); + } else { + vraat = 80; + } + t_httpUpdate_return ret = ESPhttpUpdate.update(server.arg("g"), vraat, server.arg("p"), String(verzija[0])+"."+String(verzija[1])+"."+String(verzija[2])); + switch(ret) { + case HTTP_UPDATE_FAILED: + server.send(500, "text/html", fihr(500, "Sistemska napaka: programska posodobitev: ni uspela")); + break; + case HTTP_UPDATE_NO_UPDATES: + server.send(304, "text/html", fihr(304, "Nespremenjeno: programska posodobitev: ni potrebna, verjetno ni nove verzije")); + break; + case HTTP_UPDATE_OK: + server.send(200, "text/html", fihr(200, "OK: programska posodobitev: uspela, po ponovnem zagonu se bo uporabila")); + break; + } +} +void handleUnixTimestamp() { + if (!preveriprijavo()) return; + server.send(200, "text/plain", String(now())); +} +void handleNewPassword() { + if (!preveriprijavo()) return; + if (!server.hasArg("g") || server.arg("g") == NULL) { + server.send(400, "text/html", fihr(400, "obvezen argument: g(eslo-novo)")); + return; + } + writefile("/403/webgeslo.txt", String(server.arg("g"))); +} +void handleFileUpload() { + if (!preveriprijavo()) return; + HTTPUpload& upload = server.upload(); + if(upload.status == UPLOAD_FILE_START){ + String filename = upload.filename; + if(!filename.startsWith("/")) filename = "/"+filename; + if (razhroscevanje) Serial.print("(razhroscevanje) -> handleFileUpload Name: "); Serial.println(filename); + fsUploadFile = SPIFFS.open(filename, "w"); // Open the file for writing in SPIFFS (create if it doesn't exist) + filename = String(); + } else if(upload.status == UPLOAD_FILE_WRITE){ + if(fsUploadFile) + fsUploadFile.write(upload.buf, upload.currentSize); // Write the received bytes to the file + } else if(upload.status == UPLOAD_FILE_END){ + if(fsUploadFile) { // If the file was successfully created + fsUploadFile.close(); // Close the file again + Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize); + server.send(200, "text/html", fihr(200, "prenos uspel")); + } else { + server.send(500, "text/html", fihr(500, "izdelava datoteke ni uspela")); + } + } +} +bool handleFileRead(String path) { // send the right file to the client (if it exists) + if (!preveriprijavo()) return false; + // Serial.println("handleFileRead: " + path); // 2hc + if (path.endsWith("/")) path += "index.html"; // If a folder is requested, send the index file + if(path.indexOf("/403/") >= 0) { + server.send(403, "text/html", fihr(403, "prepovedano")); + return true; + } + String contentType = getContentType(path); // Get the MIME type + if (SPIFFS.exists(path)) { // If the file exists + File file = SPIFFS.open(path, "r"); // Open it + size_t sent = server.streamFile(file, contentType); // And send it to the client + file.close(); // Then close the file again + return true; + } + return false; // If the file doesn't exist, return false +} diff --git a/f020_setup.ino b/f020_setup.ino new file mode 100644 index 0000000..28de3b5 --- /dev/null +++ b/f020_setup.ino @@ -0,0 +1,71 @@ +void setup() { + SPIFFS.begin(); + if (SPIFFS.exists("/403/pwmfreq.txt")) { + if (readfile("/403/pwmfreq.txt").toInt() > 0) { + analogWriteFreq(readfile("/403/pwmfreq.txt").toInt()); + } else { + writefile("/403/pwmfreq.txt", "20000"); + analogWriteFreq(20000); + } + } + if (!SPIFFS.exists("/403/webgeslo.txt")) { + writefile("/403/webgeslo.txt", "sijaneciot"); + } + if (!SPIFFS.exists("/403/hostname.txt")) { + writefile("/403/hostname.txt", String(program_ime) + "" + String(ESP.getChipId())); + } + if (razhroscevanje) Serial.setDebugOutput(true); + Serial.begin(9600); + Serial.println(); + String dostopnatocka[4]; + if (SPIFFS.exists("/403/wifi-ap.txt")) { + explode(readfile("/403/wifi-ap.txt"), ",", dostopnatocka, 4); + } else { + if (razhroscevanje) Serial.println("(razhroscevanje): /403/wifi-ap.txt ne obstaja, privzeta wifi konfiguracija"); + dostopnatocka[0] = String(program_ime) + "-" + String(ESP.getChipId()); + dostopnatocka[1] = ""; + dostopnatocka[2] = "1"; // kanal + dostopnatocka[3] = "0"; // skrito omrežje? + } + Serial.print("nastavljam dostopno tocko. SSID: " + String(dostopnatocka[0]) + " geslo: " + String(dostopnatocka[1]) + " ... "); + WiFi.mode(WIFI_AP); + WiFi.softAP(dostopnatocka[0].c_str(), dostopnatocka[1].c_str(), dostopnatocka[2].toInt(), dostopnatocka[3].toInt()); + if (razhroscevanje) Serial.println("(razhroscevanje): wifi.softap --> IPv4 " + String(WiFi.softAPIP().toString())); + if (MDNS.begin(readfile("/403/hostname.txt"))) { // Start the mDNS responder for esp8266.local + if (razhroscevanje) Serial.println("(razhroscevanje): mDNS dela, " + readfile("/403/hostname.txt")); + } else { + if (razhroscevanje) Serial.println("(razhroscevanje): mDNS fejl"); + } + ftpSrv.begin(program_ime, readfile("/403/webgeslo.txt")); + + setSyncProvider(getNtpTime); + setSyncInterval(300); + + + + server.on("/", handleRoot); + server.onNotFound([]() { // If the client requests any URI + if (!handleFileRead(server.uri())) // send it if it exists + server.send(404, "text/html", fihr(404, "Napačen ukaz ali napačno ime datoteke.")); // otherwise, respond with a 404 (Not Found) error + }); + server.on("/api/upload", HTTP_POST, // if the client posts to the upload page + [](){ server.send(200); }, // Send status 200 (OK) to tell the client we are ready to receive + handleFileUpload // Receive and save the file + ); + server.on("/api/pin", handlePin); + server.on("/api/res", handleRes); + server.on("/api/sap", handleSetAP); + server.on("/api/sta", handleSetSTA); + server.on("/api/gid", handleGetID); + server.on("/api/pwm", handlePWM); + server.on("/api/rst", handleRestart); + server.on("/api/slp", handleDeepSleep); + server.on("/api/now", handleUnixTimestamp); + server.on("/api/pwd", handleNewPassword); + server.on("/api/tms", handleTms); + server.on("/api/ren", handleRename); // \ prvi primer + server.on("/api/mov", handleRename); // / uporabe aliasa + server.on("/test", handleTest); + server.begin(); + if (razhroscevanje) Serial.println("(razhroscevanje): HTTP dela, vrata 80"); +} diff --git a/f030_httpserver.ino b/f030_httpserver.ino new file mode 100644 index 0000000..162eea7 --- /dev/null +++ b/f030_httpserver.ino @@ -0,0 +1 @@ +// ti samo pritisni restart, jejhe! diff --git a/f050_loop.ino b/f050_loop.ino new file mode 100644 index 0000000..8baca32 --- /dev/null +++ b/f050_loop.ino @@ -0,0 +1,4 @@ +void loop() { + server.handleClient(); + ftpSrv.handleFTP(); +} -- cgit v1.2.3