From d8e4a5b71da218293214acc9c9b6be2ccb095271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20L=2E=20=C5=A0ijanec?= Date: Thu, 16 Apr 2020 21:37:16 +0200 Subject: weather station + http time --- data/www/1.html | 7 ++- data/www/2.html | 3 ++ data/www/kazalo.html | 2 +- f000_sijaneciot.ino | 15 +++++-- f010_raznefunkcije.ino | 59 ++++++++++++++++++++++++ f015_apihandler.ino | 24 +++++++++- f020_setup.ino | 9 ++-- f040_weather.ino | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ f050_loop.ino | 2 + 9 files changed, 229 insertions(+), 12 deletions(-) create mode 100644 f040_weather.ino diff --git a/data/www/1.html b/data/www/1.html index d708f5f..0d98d23 100644 --- a/data/www/1.html +++ b/data/www/1.html @@ -2,13 +2,13 @@ Nadzorna plošča
Anton Luka Šijanec, 13. december 2019

- +
zadnja zahteva na strežnik: @@ -60,6 +60,9 @@ zadnja zahteva na strežnik:
+
+ +
diff --git a/data/www/2.html b/data/www/2.html index 04eb96a..95afd26 100644 --- a/data/www/2.html +++ b/data/www/2.html @@ -33,6 +33,9 @@ Spodaj so našteti podprti ukazi, za argumente posameznega ukaza pa zahtevajte u /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 + /api/fil - nastavljanje vrednosti datoteke + /api/tud - vsili posodobitev časa + /api/upload - POST nalaganje datoteke /test - vedno vrne 200: OK, za namen testiranje povezave, npr. če je kontrolna plošča še vedno povezana na napravo. diff --git a/data/www/kazalo.html b/data/www/kazalo.html index 9d94830..0376265 100644 --- a/data/www/kazalo.html +++ b/data/www/kazalo.html @@ -8,7 +8,7 @@
. Glavna stran
. Navodila:
.. API dokumentacija -
. Nadzorna plošča +
. Nadzorna plošča diff --git a/f000_sijaneciot.ino b/f000_sijaneciot.ino index 7d98b88..da56405 100644 --- a/f000_sijaneciot.ino +++ b/f000_sijaneciot.ino @@ -6,9 +6,18 @@ #include #include #include +// for weather +#include +#include +#include +#include +#include +// end for weather + extern "C" { #include } +#define DISALLOW_403 (false) IPAddress ipas(10, 82, 66, 1); IPAddress gatewayas(10, 82, 66, 1); IPAddress subnetas(255, 255, 255, 0); @@ -20,7 +29,7 @@ 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[] = "us.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"; @@ -35,7 +44,5 @@ const int timeZone = 1; // Central European Time WiFiUDP Udp; unsigned int localPort = 8888; // local port to listen for UDP packets -time_t getNtpTime(); -void digitalClockDisplay(); -void printDigits(int digits); +time_t getTime(); void sendNTPpacket(IPAddress &address); diff --git a/f010_raznefunkcije.ino b/f010_raznefunkcije.ino index 9613049..b940625 100644 --- a/f010_raznefunkcije.ino +++ b/f010_raznefunkcije.ino @@ -71,6 +71,7 @@ String getContentType(String filename) { // convert the file extension to the MI 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"; + else if (filename.endsWith(".csv")) return "text/csv"; return "application/octet-stream"; } @@ -109,6 +110,60 @@ String fihr(int code, String text) { // format inline html response 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 getHttpTime() { + const char * headerKeys[] = {"date"} ; + const size_t numberOfHeaders = 1; + HTTPClient http; + http.begin("http://razor.arnes.si/.well-known/time"); + http.collectHeaders(headerKeys, numberOfHeaders); + int httpCode = http.GET(); + String headerDate; + if (httpCode > 0) { + for(int i = 0; i< http.headers(); i++){ + Serial.println(http.header(i)); + } + headerDate = http.header("date"); + + } else { + if(razhroscevanje) Serial.println("unable to get http time"); + return 0; + } + http.end(); + // string, delimeter, array, length + String locenoSPresledki[5]; + String locenoZDvopicjem[3]; + explode(headerDate, " ", locenoSPresledki, 5); + int dan = locenoSPresledki[1].toInt(); + String mesc = locenoSPresledki[2]; + int leto = locenoSPresledki[3].toInt(); + explode(locenoSPresledki[4], ":", locenoZDvopicjem, 3); + int ura = locenoZDvopicjem[0].toInt(); + int minuta = locenoZDvopicjem[1].toInt(); + int sekund = locenoZDvopicjem[2].toInt(); + int mesec; + if(mesc == "Jan") mesec=1; + else if(mesc == "Feb") mesec=2; + else if(mesc == "Mar") mesec=3; + else if(mesc == "Apr") mesec=4; + else if(mesc == "May") mesec=5; + else if(mesc == "Jun") mesec=6; + else if(mesc == "Jul") mesec=7; + else if(mesc == "Aug") mesec=8; + else if(mesc == "Sep") mesec=9; + else if(mesc == "Oct") mesec=10; + else if(mesc == "Nov") mesec=11; + else if(mesc == "Dec") mesec=12; + tmElements_t tm; + tm.Hour = ura; + tm.Minute = minuta; + tm.Second = sekund; + tm.Day = dan; + tm.Month = mesec; + tm.Year = leto-1970; + if(razhroscevanje) Serial.println("httpUpdate ("+mesc+","+mesec+"): "+String(makeTime(tm))); + return makeTime(tm); +} + time_t getNtpTime() { IPAddress ntpServerIP; // NTP server's ip address @@ -162,3 +217,7 @@ void sendNTPpacket(IPAddress &address) Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); } + +time_t timeSyncProvider() { + return getHttpTime(); +} diff --git a/f015_apihandler.ino b/f015_apihandler.ino index eeb974d..add1088 100644 --- a/f015_apihandler.ino +++ b/f015_apihandler.ino @@ -27,6 +27,7 @@ void handleRename() { server.send(500, "text/html", fihr(500, "premikanje ni uspelo!")); } } + void handleTms() { // timeset if (!preveriprijavo()) return; if (!server.hasArg("s") || server.arg("s") == NULL) { @@ -123,13 +124,15 @@ void handleSetSTA() { 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")); + server.send(400, "text/html", fihr(400, "obvezni argument: k(aj s(ta MAC)/a(p MAC)/i(p)/c(hipId)/h(ostname/u(ra))). 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("u")) { + server.send(200, "text/plain", String(now())); } else if (server.arg("k").startsWith("i")) { server.send(200, "text/plain", WiFi.localIP().toString()); } else if (server.arg("k").startsWith("c")) { @@ -197,6 +200,12 @@ void handleNewPassword() { } writefile("/403/webgeslo.txt", String(server.arg("g"))); } + +void handleForcedTimeUpdate() { + setTime(timeSyncProvider()); + server.send(200, "text/html", fihr(200, "ok")); +} + void handleFileUpload() { if (!preveriprijavo()) return; HTTPUpload& upload = server.upload(); @@ -219,11 +228,22 @@ void handleFileUpload() { } } } + +void handleFile() { + if (!preveriprijavo()) return; + if (!server.hasArg("i") || server.arg("i") == NULL || !server.hasArg("v")) { + server.send(400, "text/html", fihr(400, "obvezena argumenta: i(me), v(sebina)")); + return; + } + writefile(String(server.arg("i")), String(server.arg("v"))); + server.send(200, "text/html", fihr(200, "ok")); +} + 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) { + if(path.indexOf("/403/") >= 0 && DISALLOW_403) { server.send(403, "text/html", fihr(403, "prepovedano")); return true; } diff --git a/f020_setup.ino b/f020_setup.ino index 8e50af7..5c0c7e3 100644 --- a/f020_setup.ino +++ b/f020_setup.ino @@ -16,7 +16,7 @@ void setup() { } if (razhroscevanje) Serial.setDebugOutput(true); Serial.begin(9600); - Serial.println(); + Serial.println(""); String dostopnatocka[4]; if (SPIFFS.exists("/403/wifi-ap.txt")) { explode(readfile("/403/wifi-ap.txt"), ",", dostopnatocka, 4); @@ -27,6 +27,7 @@ void setup() { dostopnatocka[2] = "1"; // kanal dostopnatocka[3] = "0"; // skrito omrežje? } + Serial.println(""); Serial.print("nastavljam dostopno tocko. SSID: " + String(dostopnatocka[0]) + " geslo: " + String(dostopnatocka[1]) + " ... "); WiFi.mode(WIFI_AP); WiFi.softAPConfig(ipas, gatewayas, subnetas); @@ -34,8 +35,8 @@ void setup() { if (razhroscevanje) Serial.println("(razhroscevanje): wifi.softap --> IPv4 " + String(WiFi.softAPIP().toString())); ftpSrv.begin(program_ime, readfile("/403/webgeslo.txt")); - setSyncProvider(getNtpTime); - setSyncInterval(300); + setSyncProvider(timeSyncProvider); + setSyncInterval(30); @@ -61,6 +62,8 @@ void setup() { server.on("/api/tms", handleTms); server.on("/api/ren", handleRename); // \ prvi primer server.on("/api/mov", handleRename); // / uporabe aliasa + server.on("/api/fil", handleFile); + server.on("/api/tud", handleForcedTimeUpdate); server.on("/test", handleTest); server.begin(); if (razhroscevanje) Serial.println("(razhroscevanje): HTTP dela, vrata 80"); diff --git a/f040_weather.ino b/f040_weather.ino new file mode 100644 index 0000000..1786d64 --- /dev/null +++ b/f040_weather.ino @@ -0,0 +1,120 @@ +#define SEALEVELPRESSURE_HPA (1021) +bool weatherInited = false; +int previousWeather = -69420; +int weatherUpdateInterval = 10; +Adafruit_BME280 bme1; +Adafruit_BME280 bme2; +unsigned long delayTime; +BH1750 lightMeter1(0x23); +BH1750 lightMeter2(0x5C); +void weatherInit() { + Wire.begin(D3, D4); + if (razhroscevanje) Serial.println(F("BME280 initialising ...")); + unsigned status[2]; + status[0] = bme1.begin(0x76); + status[1] = bme2.begin(0x77); + if (!status[0]) { + if(razhroscevanje) { + Serial.println("[1] Could not find a valid BME280 sensor, check wiring, address, sensor ID!"); + Serial.print("SensorID was: 0x"); Serial.println(bme1.sensorID(),16); + Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n"); + Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n"); + Serial.print(" ID of 0x60 represents a BME 280.\n"); + Serial.print(" ID of 0x61 represents a BME 680.\n"); + Serial.println(); + } + } + if (!status[1]) { + if(razhroscevanje) { + Serial.println("[1] Could not find a valid BME280 sensor, check wiring, address, sensor ID!"); + Serial.print("SensorID was: 0x"); Serial.println(bme2.sensorID(),16); + Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n"); + Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n"); + Serial.print(" ID of 0x60 represents a BME 280.\n"); + Serial.print(" ID of 0x61 represents a BME 680.\n"); + Serial.println(); + } + } + float lux1 = lightMeter1.readLightLevel(); + float lux2 = lightMeter2.readLightLevel(); + if(razhroscevanje) { + Serial.print("[1] Temperature = "); + Serial.print(bme1.readTemperature()); + Serial.println(" *C"); + Serial.print("[1] Pressure = "); + Serial.print(bme1.readPressure() / 100.0F); + Serial.println(" hPa"); + Serial.print("[1] Approx. Altitude = "); + Serial.print(bme1.readAltitude(SEALEVELPRESSURE_HPA)); + Serial.println(" m"); + Serial.print("[1] Humidity = "); + Serial.print(bme1.readHumidity()); + Serial.println(" %"); + Serial.print("[1] Luminance= "); + Serial.print(lightMeter1.readLightLevel()); + Serial.println(" lux"); + Serial.println(); + Serial.print("[2] Temperature = "); + Serial.print(bme2.readTemperature()); + Serial.println(" *C"); + Serial.print("[2] Pressure = "); + Serial.print(bme2.readPressure() / 100.0F); + Serial.println(" hPa"); + Serial.print("[2] Approx. Altitude = "); + Serial.print(bme2.readAltitude(SEALEVELPRESSURE_HPA)); + Serial.println(" m"); + Serial.print("[2] Humidity = "); + Serial.print(bme2.readHumidity()); + Serial.println(" %"); + Serial.print("[2] Luminance= "); + Serial.print(lightMeter2.readLightLevel()); + Serial.println(" lx"); + Serial.println(); + } + if (lightMeter1.begin(BH1750::CONTINUOUS_HIGH_RES_MODE_2)) { + if (razhroscevanje )Serial.println(F("[1] BH1750 Advanced begin")); + } else { + if (razhroscevanje )Serial.println(F("[1] Error initialising BH1750")); + } + if (lightMeter2.begin(BH1750::CONTINUOUS_HIGH_RES_MODE_2)) { + if (razhroscevanje )Serial.println(F("[2] BH1750 Advanced begin")); + } else { + if (razhroscevanje )Serial.println(F("[2] Error initialising BH1750")); + } + if(!SPIFFS.exists("/www/var/weather.csv")) { + writefile("/www/var/weather.csv", "ura,temperatura1,pritisk1,visina1,vlaznost1,temperatura2,pritisk2,visina2,vlaznost2,svetlost1,svetlost2\n"); + } + if(readfile("/403/weatherUpdateInterval.txt").length() < 1) { + writefile("/403/weatherUpdateInterval.txt", "10"); + } + weatherInited = true; + previousWeather = now(); +} +void weatherHeartbeat () { + if(weatherInited == false) { + weatherInit(); + } else { + if(previousWeather + weatherUpdateInterval < now()) { + weatherUpdateInterval = readfile("/403/weatherUpdateInterval.txt").toInt(); // for updating the time + File file = SPIFFS.open("/www/var/weather.csv", "a+"); + if (!file) { + if (razhroscevanje) Serial.println("There was an error opening the file for writing (weather.csv)"); + return; + } + String temperatura1 = String(bme1.readTemperature()); + String pritisk1 = String(bme1.readPressure() / 100.0F); + String visina1 = String(bme1.readAltitude(SEALEVELPRESSURE_HPA)); + String vlaznost1 = String(bme1.readHumidity()); + String temperatura2 = String(bme2.readTemperature()); + String pritisk2 = String(bme2.readPressure() / 100.0F); + String visina2 = String(bme2.readAltitude(SEALEVELPRESSURE_HPA)); + String vlaznost2 = String(bme2.readHumidity()); + String svetlost1 = String(lightMeter1.readLightLevel()); + String svetlost2 = String(lightMeter2.readLightLevel()); + if (!file.println(String(now())+","+temperatura1+","+pritisk1+","+visina1+","+vlaznost1+","+temperatura2+","+pritisk2+","+visina2+","+vlaznost2+","+svetlost1+","+svetlost2)) { + if (razhroscevanje) Serial.println("File write failed (weather.csv)"); + } + previousWeather = now(); + } + } +} diff --git a/f050_loop.ino b/f050_loop.ino index 8baca32..bf3deb0 100644 --- a/f050_loop.ino +++ b/f050_loop.ino @@ -1,4 +1,6 @@ void loop() { + // loop must take less than a minute! server.handleClient(); ftpSrv.handleFTP(); + weatherHeartbeat(); } -- cgit v1.2.3