add prediction and stuff
This commit is contained in:
parent
1e4704b5bc
commit
a22a059ac3
2 changed files with 175 additions and 49 deletions
|
@ -4,27 +4,39 @@
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include "DHT.h"
|
#include "DHT.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "proj_password.h"
|
#include "proj_conf.h"
|
||||||
|
|
||||||
#define LED 2 //On board LED
|
#define LED 2 // On board LED
|
||||||
#define DHTTYPE DHT22 // DHT 11
|
#define DHTTYPE DHT22 // DHT 11
|
||||||
uint8_t DHTPin = 12;
|
uint8_t DHTPin = 12;
|
||||||
DHT dht(DHTPin, DHTTYPE);
|
DHT dht(DHTPin, DHTTYPE);
|
||||||
|
|
||||||
|
const char *ntpServer = "pool.ntp.org";
|
||||||
|
const long gmtOffset_sec = 3600; // Replace with your GMT offset (seconds)
|
||||||
|
const int daylightOffset_sec = 0; // Replace with your daylight offset (seconds)
|
||||||
|
|
||||||
|
// Generally, you should use "unsigned long" for variables that hold time
|
||||||
|
// The value will quickly become too large for an int to store
|
||||||
|
unsigned long previousMillis = 0;
|
||||||
|
// constants won't change :
|
||||||
|
float time_till_update = 10;
|
||||||
|
|
||||||
// define device I2C address: 0x76 or 0x77 (0x77 is library default address)
|
// define device I2C address: 0x76 or 0x77 (0x77 is library default address)
|
||||||
#define BMP280_I2C_ADDRESS 0x76
|
#define BMP280_I2C_ADDRESS 0x76
|
||||||
// initialize Adafruit BMP280 library
|
// initialize Adafruit BMP280 library
|
||||||
Adafruit_BMP280 bmp280;
|
Adafruit_BMP280 bmp280;
|
||||||
|
|
||||||
float humidity, temperature, temperature_2, pressure;
|
float humidity, temperature, temperature_2, pressure;
|
||||||
ESP8266WebServer server(80); //Server on port 80
|
int currZambretti = 26;
|
||||||
|
ESP8266WebServer server(80); // Server on port 80
|
||||||
const char MAIN_page[] PROGMEM = R"=====(
|
const char MAIN_page[] PROGMEM = R"=====(
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Weather</title>
|
<title>Weather</title>
|
||||||
<h1 style="text-align:center; color:red;">Some Weather ....</h1>
|
<h1 style="text-align:center; color:red;">Some Weather</h1>
|
||||||
<h3 style="text-align:center;">NodeMCU Data Logger</h3>
|
<h3 style="text-align:center;">NodeMCU Data Logger</h3>
|
||||||
<style>
|
<style>
|
||||||
canvas{
|
canvas{
|
||||||
|
@ -63,21 +75,26 @@ const char MAIN_page[] PROGMEM = R"=====(
|
||||||
<th>Temperature 2 (°C)</th>
|
<th>Temperature 2 (°C)</th>
|
||||||
<th>Humidity (%)</th>
|
<th>Humidity (%)</th>
|
||||||
<th>Pressure (hPa)</th>
|
<th>Pressure (hPa)</th>
|
||||||
|
<th>Zambretti</th>
|
||||||
|
<th>next update in (m)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<script>
|
<script>
|
||||||
|
var z_forecast = new Array("Settled fine", "Fine weather", "Becoming fine", "Fine, becoming less settled", "Fine, possible showers", "Fairly fine, improving", "Fairly fine, possible showers early", "Fairly fine, showery later", "Showery early, improving", "Changeable, mending", "Fairly fine, showers likely", "Rather unsettled clearing later", "Unsettled, probably improving", "Showery, bright intervals", "Showery, becoming less settled", "Changeable, some rain", "Unsettled, short fine intervals", "Unsettled, rain later", "Unsettled, some rain", "Mostly very unsettled", "Occasional rain, worsening", "Rain at times, very unsettled", "Rain at frequent intervals", "Rain, very unsettled", "Stormy, may improve", "Stormy, much rain", "NaN");
|
||||||
var Tvalues = [];
|
var Tvalues = [];
|
||||||
var Hvalues = [];
|
var Hvalues = [];
|
||||||
var timeStamp = [];
|
var timeStamp = [];
|
||||||
var T2value = [];
|
var T2value = [];
|
||||||
var Pvalue = [];
|
var Pvalue = [];
|
||||||
|
var Zvalue = [];
|
||||||
|
var dTvalue = [];
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
// Call a function repetatively with 5 Second interval
|
// Call a function repetatively with 5 Second interval
|
||||||
getData();
|
getData();
|
||||||
}, 5000); //5000mSeconds update rate
|
}, 60000); //5000mSeconds update rate
|
||||||
function getData() {
|
function getData() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
|
@ -90,6 +107,8 @@ function getData() {
|
||||||
Hvalues.push(obj.Humidity);
|
Hvalues.push(obj.Humidity);
|
||||||
T2value.push(obj.Temperature_2);
|
T2value.push(obj.Temperature_2);
|
||||||
Pvalue.push(obj.Pressure);
|
Pvalue.push(obj.Pressure);
|
||||||
|
Zvalue.push(obj.forcast_num);
|
||||||
|
dTvalue.push(obj.time_till_update);
|
||||||
timeStamp.push(time);
|
timeStamp.push(time);
|
||||||
|
|
||||||
if(Tvalues.length > 10){
|
if(Tvalues.length > 10){
|
||||||
|
@ -98,6 +117,8 @@ function getData() {
|
||||||
timeStamp.pop();
|
timeStamp.pop();
|
||||||
T2value.pop();
|
T2value.pop();
|
||||||
Pvalue.pop();
|
Pvalue.pop();
|
||||||
|
Zvalue.pop();
|
||||||
|
dTvalue.pop();
|
||||||
document.getElementById("dataTable").deleteRow(10);
|
document.getElementById("dataTable").deleteRow(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,12 +130,16 @@ function getData() {
|
||||||
var cell3 = row.insertCell(2);
|
var cell3 = row.insertCell(2);
|
||||||
var cell4 = row.insertCell(3);
|
var cell4 = row.insertCell(3);
|
||||||
var cell5 = row.insertCell(4);
|
var cell5 = row.insertCell(4);
|
||||||
|
var cell6 = row.insertCell(5);
|
||||||
|
var cell7 = row.insertCell(6);
|
||||||
|
|
||||||
cell1.innerHTML = time;
|
cell1.innerHTML = time;
|
||||||
cell2.innerHTML = obj.Temperature;
|
cell2.innerHTML = obj.Temperature;
|
||||||
cell3.innerHTML = obj.Temperature_2;
|
cell3.innerHTML = obj.Temperature_2;
|
||||||
cell4.innerHTML = obj.Humidity;
|
cell4.innerHTML = obj.Humidity;
|
||||||
cell5.innerHTML = obj.Pressure;
|
cell5.innerHTML = obj.Pressure;
|
||||||
|
cell6.innerHTML = obj.forcast_num + " | " + z_forecast[obj.forcast_num];
|
||||||
|
cell7.innerHTML = obj.time_till_update;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "readData", true); //Handle readData server on ESP8266
|
xhttp.open("GET", "readData", true); //Handle readData server on ESP8266
|
||||||
|
@ -126,29 +151,40 @@ function getData() {
|
||||||
|
|
||||||
)=====";
|
)=====";
|
||||||
|
|
||||||
|
void handleRoot()
|
||||||
void handleRoot() {
|
{
|
||||||
String s = MAIN_page; //Read HTML contents
|
String s = MAIN_page; // Read HTML contents
|
||||||
server.send(200, "text/html", s); //Send web page
|
server.send(200, "text/html", s); // Send web page
|
||||||
}
|
}
|
||||||
|
|
||||||
void readData() {
|
void readData()
|
||||||
|
{
|
||||||
|
|
||||||
String data = "{\"Temperature\":\"" + String(temperature) + "\", \"Humidity\":\"" + String(humidity) + "\", \"Temperature_2\":\"" + String(temperature_2) + "\", \"Pressure\":\"" + String(pressure) + "\" }";
|
String data = "{\"Temperature\":\"" + String(temperature)
|
||||||
digitalWrite(LED,!digitalRead(LED)); //Toggle LED on data request ajax
|
+ "\", \"Humidity\":\"" + String(humidity)
|
||||||
server.send(200, "text/plane", data); //Send ADC value, temperature and humidity JSON to client ajax request
|
+ "\", \"Temperature_2\":\"" + String(temperature_2)
|
||||||
delay(2000);
|
+ "\", \"Pressure\":\"" + String(pressure)
|
||||||
temperature = (dht.readTemperature());
|
+ "\", \"forcast_num\": " + String(currZambretti)
|
||||||
humidity = dht.readHumidity();
|
+ ", \"time_till_update\": " + String(time_till_update) + " }";
|
||||||
|
digitalWrite(LED, !digitalRead(LED)); // Toggle LED on data request ajax
|
||||||
|
server.send(200, "text/plane", data); // Send ADC value, temperature and humidity JSON to client ajax request
|
||||||
|
delay(2000);
|
||||||
|
temperature = (dht.readTemperature());
|
||||||
|
humidity = dht.readHumidity();
|
||||||
|
|
||||||
// read temperature and pressure from BMP280 sensor
|
// read temperature and pressure from BMP280 sensor
|
||||||
temperature_2 = (bmp280.readTemperature()); // get temperature
|
temperature_2 = (bmp280.readTemperature()); // get temperature
|
||||||
pressure = (bmp280.readPressure()/100); // get pressure
|
pressure = (bmp280.readPressure() / 100); // get pressure
|
||||||
|
|
||||||
Serial.println("T1: " + String(temperature) + " T2:" + String(temperature_2) + " H:" + String(humidity) + " P: " + String(pressure));
|
Serial.println("T1: " + String(temperature)
|
||||||
|
+ " T2:" + String(temperature_2)
|
||||||
|
+ " H:" + String(humidity)
|
||||||
|
+ " P: " + String(pressure)
|
||||||
|
+ " Z: " + String(currZambretti)
|
||||||
|
+ " dT: " + String(time_till_update));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup ()
|
void setup()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
@ -156,39 +192,132 @@ void setup ()
|
||||||
dht.begin();
|
dht.begin();
|
||||||
|
|
||||||
// initialize the BMP280 sensor
|
// initialize the BMP280 sensor
|
||||||
//Wire.begin(D1, D2); // set I2C pins [SDA = D2, SCL = D1], default clock is 100kHz
|
// Wire.begin(D1, D2); // set I2C pins [SDA = D2, SCL = D1], default clock is 100kHz
|
||||||
//Wire.begin(4, 0);
|
// Wire.begin(4, 0);
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
while(!bmp280.begin(BMP280_I2C_ADDRESS)){
|
while (!bmp280.begin(BMP280_I2C_ADDRESS))
|
||||||
|
{
|
||||||
Serial.println("BPM280 put");
|
Serial.println("BPM280 put");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFi.begin(ssid, password); //Connect to your WiFi router
|
WiFi.begin(ssid, password); // Connect to your WiFi router
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
//Onboard LED port Direction output
|
// Onboard LED port Direction output
|
||||||
pinMode(LED,OUTPUT);
|
pinMode(LED, OUTPUT);
|
||||||
|
|
||||||
// Wait for connection
|
// Wait for connection
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
while (WiFi.status() != WL_CONNECTED)
|
||||||
|
{
|
||||||
delay(500);
|
delay(500);
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
//If connection successful show IP address in serial monitor
|
// If connection successful show IP address in serial monitor
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
Serial.print("Connected to ");
|
Serial.print("Connected to ");
|
||||||
Serial.println(ssid);
|
Serial.println(ssid);
|
||||||
Serial.print("IP address: ");
|
Serial.print("IP address: ");
|
||||||
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
|
Serial.println(WiFi.localIP()); // IP address assigned to your ESP
|
||||||
|
|
||||||
server.on("/", handleRoot); //Which routine to handle at root location. This is display page
|
server.on("/", handleRoot); // Which routine to handle at root location. This is display page
|
||||||
server.on("/readData", readData); //This page is called by java Script AJAX
|
server.on("/readData", readData); // This page is called by java Script AJAX
|
||||||
|
|
||||||
|
server.begin(); // Start server
|
||||||
|
|
||||||
|
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
||||||
|
|
||||||
server.begin(); //Start server
|
|
||||||
Serial.println("HTTP server started");
|
Serial.println("HTTP server started");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(void){
|
void loop(void)
|
||||||
server.handleClient(); //Handle client requests
|
{
|
||||||
|
server.handleClient(); // Handle client requests
|
||||||
|
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
|
time_till_update = ((interval - (currentMillis - previousMillis)) / 60000.0);
|
||||||
|
|
||||||
|
if (currentMillis - previousMillis >= interval)
|
||||||
|
{
|
||||||
|
// save the last time you blinked the LED
|
||||||
|
previousMillis = currentMillis;
|
||||||
|
|
||||||
|
zembretti_number_calc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// WEATHER PREDICTION
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
int rise_options[] = {25, 25, 25, 24, 24, 19, 16, 12, 11, 9, 8, 6, 5, 2, 1, 1, 0, 0, 0, 0, 0, 0};
|
||||||
|
int steady_options[] = {25, 25, 25, 25, 25, 25, 23, 23, 22, 18, 15, 13, 10, 4, 1, 1, 0, 0, 0, 0, 0, 0};
|
||||||
|
int fall_options[] = {25, 25, 25, 25, 25, 25, 25, 25, 23, 23, 21, 20, 17, 14, 7, 3, 1, 1, 1, 0, 0, 0};
|
||||||
|
|
||||||
|
float prev_pressure = 0;
|
||||||
|
|
||||||
|
void zembretti_number_calc(){
|
||||||
|
|
||||||
|
Serial.println("Calc new Zembretti");
|
||||||
|
|
||||||
|
float curr_pressure = (bmp280.readPressure() / 100); // get pressure
|
||||||
|
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm *timeinfo;
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
|
||||||
|
int mon = timeinfo->tm_mon;
|
||||||
|
|
||||||
|
float pressureRange = (maxAvgPressure - minAvgPressure);
|
||||||
|
float calculus = (float) curr_pressure;
|
||||||
|
int isRising = 0;
|
||||||
|
|
||||||
|
// calc if pressure is rising or not, default is equal
|
||||||
|
if (curr_pressure > prev_pressure)
|
||||||
|
isRising = 1;
|
||||||
|
else if (prev_pressure > curr_pressure)
|
||||||
|
isRising = -1;
|
||||||
|
|
||||||
|
if (isNorthern){
|
||||||
|
// no wind data so ignore calculation for it
|
||||||
|
if ( mon >= 4 && mon <= 9 ) {// if Summer
|
||||||
|
if (isRising == 1) {
|
||||||
|
calculus += (7 / 100) * pressureRange;
|
||||||
|
} else if (isRising == -1) {
|
||||||
|
calculus -= (7 / 100) * pressureRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no wind data so ignore calculation for it
|
||||||
|
if ( mon < 4 || mon > 9 ) {// if Summer
|
||||||
|
if (isRising == 1) {
|
||||||
|
calculus += (7 / 100) * pressureRange;
|
||||||
|
} else if (isRising == -1) {
|
||||||
|
calculus -= (7 / 100) * pressureRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculus = (curr_pressure - minAvgPressure) / (pressureRange / 22);
|
||||||
|
prev_pressure = curr_pressure;
|
||||||
|
// non expectet values
|
||||||
|
if (calculus < 0){
|
||||||
|
currZambretti = 26;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (calculus >= 22) {
|
||||||
|
currZambretti = 26;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isRising > 0)
|
||||||
|
currZambretti = rise_options[(int) calculus];
|
||||||
|
else if (isRising < 0)
|
||||||
|
currZambretti = fall_options[(int) calculus];
|
||||||
|
else
|
||||||
|
currZambretti = steady_options[(int) calculus];
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
//SSID and Password of your WiFi router
|
|
||||||
const char* ssid = "";
|
|
||||||
const char* password = "";
|
|
Loading…
Reference in a new issue