1
0
Fork 0
Browse Source

weather station + http time

master
Anton L. Šijanec 2 years ago
parent
commit
d8e4a5b71d
  1. 7
      data/www/1.html
  2. 3
      data/www/2.html
  3. 2
      data/www/kazalo.html
  4. 15
      f000_sijaneciot.ino
  5. 59
      f010_raznefunkcije.ino
  6. 24
      f015_apihandler.ino
  7. 9
      f020_setup.ino
  8. 120
      f040_weather.ino
  9. 2
      f050_loop.ino

7
data/www/1.html

@ -2,13 +2,13 @@ @@ -2,13 +2,13 @@
<meta charset=UTF-8>
<link rel="stylesheet" type="text/css" href="css/main.css">
<style>
table, tr, td { border: 1px solid red; }
table, tr, td { border: 1px solid red; } iframe {background: white}
</style>
</head>
<b><text style=font-size:25px>Nadzorna plošča</text> <!--<img align=right src=img.png alt=SLIKA width=300 height=170 />-->
<br><i>Anton Luka Šijanec, 13. december 2019</i><br></b>
<br>
<table height=89% width=100%>
<table height=89% width=80%>
<tr>
<td width=33%>
zadnja zahteva na strežnik:
@ -60,6 +60,9 @@ zadnja zahteva na strežnik: @@ -60,6 +60,9 @@ zadnja zahteva na strežnik:
<form action="/api/now" method="GET" target="zadnjaiframe">
<input type="submit" value="pridobi trenutni čas (UNIX časovni žig)" />
</form>
<form action="/api/tud" method="GET" target="zadnjaiframe">
<input type="submit" value="vsili posodobitev časa" />
</form>
</td><td>
<form action="/api/sap" method="GET" target="zadnjaiframe">
<input required type=text name=s placeholder="SSID">

3
data/www/2.html

@ -33,6 +33,9 @@ Spodaj so našteti podprti ukazi, za argumente posameznega ukaza pa zahtevajte u @@ -33,6 +33,9 @@ Spodaj so našteti podprti ukazi, za argumente posameznega ukaza pa zahtevajte u
<a href=/api/tms>/api/tms - nastavitev časa (ob povezavi v splet se čas sicer vsakih 300 sekund posodobi iz 0.pool.ntp.org)</a>
<a href=/api/ren>/api/ren - preimenovanje datotek, pod "haubo" isto kot /api/mov</a>
<a href=/api/mov>/api/mov - premikanje datotek, pod "haubo" isto kot /api/ren</a>
<a href=/api/fil>/api/fil - nastavljanje vrednosti datoteke</a>
<a href=/api/fil>/api/tud - vsili posodobitev časa</a>
<a href=/api/fil>/api/upload - POST nalaganje datoteke</a>
<a href=/test>/test - vedno vrne 200: OK, za namen testiranje povezave, npr. če je kontrolna plošča še vedno povezana na napravo.</a>
</pre>

2
data/www/kazalo.html

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
<br><a href=0.html target=clanekiframe><font face=Monospace><b>. </b></font><text style=font-size:16px>Glavna stran</text></a>
<br><!--<a href=1.html target=clanekiframe>--><font face=Monospace><b>. </b></font><text style=font-size:16px>Navodila:</text><!--</a>-->
<br><a href=2.html target=clanekiframe><font face=Monospace><b>.. </b></font><text style=font-size:16px>API dokumentacija</text></a>
<br><a href=1.html target=clanekiframe><font face=Monospace><b>. </b></font><text style=font-size:16px>Nadzorna plošča</text></a>
<br><a href=1.html target=nadzornaplosca><font face=Monospace><b>. </b></font><text style=font-size:16px>Nadzorna plošča</text></a>
<!--<br><a href=3.html target=clanekiframe><font face=Monospace><b>.</b></font><text style=font-size:20px>POVEZAVA3</text></a>
<br><a href=4.html target=clanekiframe><font face=Monospace><b>.</b></font><text style=font-size:20px>POVEZAVA4</text></a>-->
</body>

15
f000_sijaneciot.ino

@ -6,9 +6,18 @@ @@ -6,9 +6,18 @@
#include <WiFiUdp.h>
#include <ESP8266FtpServer.h>
#include <ESP8266httpUpdate.h>
// for weather
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <BH1750.h>
// end for weather
extern "C" {
#include <user_interface.h>
}
#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; @@ -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 @@ -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);

59
f010_raznefunkcije.ino

@ -71,6 +71,7 @@ String getContentType(String filename) { // convert the file extension to the MI @@ -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 @@ -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) @@ -162,3 +217,7 @@ void sendNTPpacket(IPAddress &address)
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
time_t timeSyncProvider() {
return getHttpTime();
}

24
f015_apihandler.ino

@ -27,6 +27,7 @@ void handleRename() { @@ -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() { @@ -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() { @@ -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() { @@ -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;
}

9
f020_setup.ino

@ -16,7 +16,7 @@ void setup() { @@ -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() { @@ -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() { @@ -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() { @@ -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");

120
f040_weather.ino

@ -0,0 +1,120 @@ @@ -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();
}
}
}

2
f050_loop.ino

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
void loop() {
// loop must take less than a minute!
server.handleClient();
ftpSrv.handleFTP();
weatherHeartbeat();
}

Loading…
Cancel
Save