meteoFront/frontend.ino

339 lines
9.0 KiB
Arduino
Raw Normal View History

2018-05-07 23:01:41 +03:00
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
2018-06-02 22:28:21 +03:00
// #include <ESP8266WebServer.h>
2018-05-07 23:01:41 +03:00
#include <ESP8266mDNS.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "SSD1306Brzo.h"
#include <ArduinoJson.h>
2018-06-02 22:28:21 +03:00
// #include <FS.h>
2018-05-09 12:06:48 +03:00
#include "wifi.h"
2018-05-07 23:01:41 +03:00
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
double inTemp,outTemp,pressure,humid;
2018-06-02 22:28:21 +03:00
unsigned short int onTime = 5, offTime = 23, beepDelay = 60, lastBeep, lastWifi;
2018-05-07 23:01:41 +03:00
bool mqttAvail;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
2018-05-29 16:29:09 +03:00
SSD1306Brzo display(0x3C, 5, 4); //oled display w/ address 0x3C with SDA on GPIO4 and SCL on GPIO5 //address == offset
2018-05-07 23:01:41 +03:00
WiFiClient client;
2018-06-02 22:28:21 +03:00
// ESP8266WebServer server(80);
2018-05-29 16:29:09 +03:00
Adafruit_MQTT_Client mqtt(&client, "192.168.100.100", 1883);
2018-05-07 23:01:41 +03:00
Adafruit_MQTT_Subscribe pressureFeed = Adafruit_MQTT_Subscribe(&mqtt, "pressure");
Adafruit_MQTT_Subscribe inFeed = Adafruit_MQTT_Subscribe(&mqtt, "bmpTemp");
Adafruit_MQTT_Subscribe outFeed = Adafruit_MQTT_Subscribe(&mqtt, "externalTemp");
Adafruit_MQTT_Subscribe humidFeed = Adafruit_MQTT_Subscribe(&mqtt, "humid");
void wifiConnect() {
int beginMillis = millis();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED && millis() - beginMillis < 30000) {
delay(250);
displayStatus(1);
Serial.print(".");
}
if (WiFi.status() != WL_CONNECTED) {
displayStatus(2);
delay(10000);
ESP.reset();
2018-05-09 12:06:48 +03:00
} else {
MDNS.begin("esp8266-frontend");
Serial.print("Connected to " + String(ssid) + "; IP address: ");
Serial.println(WiFi.localIP());
displayStatus(0);
}
2018-05-07 23:01:41 +03:00
}
void setup(){
Serial.begin(115200);
//==DISPLAY INIT==
display.init();
display.flipScreenVertically();
display.setContrast(255);
//==WIFI CONNECT==
WiFi.mode(WIFI_STA);
wifiConnect();
//==READ CONFIG==
2018-06-02 22:28:21 +03:00
// if (!SPIFFS.begin())
// SPIFFS.format();
2018-06-02 22:28:21 +03:00
// if (!readConfig())
// defConfig();
2018-05-07 23:01:41 +03:00
//==NTP INIT==
timeClient.begin();
timeClient.setTimeOffset(10800);
//MQTT
pressureFeed.setCallback(pressureCall);
inFeed.setCallback(inCall);
outFeed.setCallback(outCall);
humidFeed.setCallback(humidCall);
mqtt.subscribe(&pressureFeed);
mqtt.subscribe(&outFeed);
mqtt.subscribe(&inFeed);
mqtt.subscribe(&humidFeed);
2018-06-02 22:28:21 +03:00
// server.on("/edit", editConfig);
// server.begin();
updateNtp();
2018-05-07 23:01:41 +03:00
}
void loop(){
if (WiFi.status() != WL_CONNECTED) { //check wifi status
2018-05-07 23:01:41 +03:00
wifiConnect();
}
2018-06-02 22:28:21 +03:00
// server.handleClient();
if (timeClient.getHours()*60+timeClient.getMinutes() - lastWifi >= 60){ // due to powersaving
lastWifi = timeClient.getHours()*60+timeClient.getMinutes();
MQTT_connect();//check connection and get packets for 0.5s
mqtt.processPackets(750);
updateNtp();//update time
}
else delay(900);
2018-05-07 23:13:41 +03:00
mainScreen();//it could be cool and smooth if we could update screen independently, in some kind of separate thread or smthn similar
2018-05-31 21:44:15 +03:00
if ((timeClient.getHours()*60 + timeClient.getMinutes() - lastBeep >= beepDelay)&&(!nightMode())){ //beep every $lastBeep
2018-05-07 23:01:41 +03:00
tone(15,1000);
delay(100);
noTone(15);
2018-05-09 12:06:48 +03:00
lastBeep = timeClient.getHours()*60;
2018-05-07 23:01:41 +03:00
}
2018-05-07 23:01:41 +03:00
}
//second screen
2018-05-07 23:01:41 +03:00
//GRAPH
/*
get json from server
~12 values
hourly values + hourly display
if pressure lowers then weather gonna be bad
if pressure uppers then weather gonna be good
*/
//====================IN PROGRESS===================
2018-06-02 22:28:21 +03:00
// void editConfig(){
// if (server.args() > 0 ) {
// for ( uint8_t i = 0; i < server.args(); i++ ){
// String Argument_Name = server.argName(i);
// String client_response = server.arg(i);
// if (Argument_Name == "beepDelay"){
// beepDelay = client_response.toInt();
// }
// if (Argument_Name == "onTime"){
// onTime = client_response.toInt();
// }
// if (Argument_Name == "offTime"){
// offTime = client_response.toInt();
// }
// updateConfig();
// server.send(200, "text/plain", "updatedConfig");
// }
// } else {
// server.send(200, "text/plain", "to update config, goto " + String(WiFi.localIP()) + "/edit?parameter=value");
// }
// }
2018-06-02 22:28:21 +03:00
// bool updateConfig() {
// StaticJsonBuffer<200> jsonBuffer;
// JsonObject& json = jsonBuffer.createObject();
// json["onTime"] = onTime;
// json["offTime"] = offTime;
// json["beepDelay"] = beepDelay;
// File configFile = SPIFFS.open("/config.json", "w");
// if (!configFile) {
// Serial.println("Failed to open config file for writing");
// return false;
// }
2018-06-02 22:28:21 +03:00
// json.printTo(configFile);
// return true;
2018-06-02 22:28:21 +03:00
// }
2018-05-07 23:01:41 +03:00
2018-06-02 22:28:21 +03:00
// bool readConfig() {
// File configFile = SPIFFS.open("/config.json", "r");
// if (!configFile) {
// Serial.println("Failed to open config file");
2018-06-02 22:28:21 +03:00
// return false;
// }
2018-06-02 22:28:21 +03:00
// size_t size = configFile.size();
// if (size > 1024) {
// Serial.println("Config file size is too large");
// return false;
// }
2018-06-02 22:28:21 +03:00
// // Allocate a buffer to store contents of the file.
// std::unique_ptr<char[]> buf(new char[size]);
2018-06-02 22:28:21 +03:00
// // We don't use String here because ArduinoJson library requires the input buffer to be mutable. If you don't use ArduinoJson, you may as well use configFile.readString instead.
// configFile.readBytes(buf.get(), size);
2018-06-02 22:28:21 +03:00
// StaticJsonBuffer<200> jsonBuffer;
// JsonObject& json = jsonBuffer.parseObject(buf.get());
2018-06-02 22:28:21 +03:00
// if (!json.success()) {
// Serial.println("Failed to parse config file");
// return false;
// }
2018-06-02 22:28:21 +03:00
// offTime = int(json["offTime"]);
// onTime = int(json["onTime"]);
// beepDelay = int(json["beepDelay"]);
// return true;
2018-05-07 23:01:41 +03:00
2018-06-02 22:28:21 +03:00
// }
// bool defConfig() {
// StaticJsonBuffer<200> jsonBuffer;
// JsonObject& json = jsonBuffer.createObject();
// json["onTime"] = "6";
// json["offTime"] = "23";
// json["beepDelay"] = "60";
// File configFile = SPIFFS.open("/config.json", "w");
// if (!configFile) {
// Serial.println("Failed to open config file for writing");
// return false;
// }
2018-06-02 22:28:21 +03:00
// json.printTo(configFile);
// return true;
// }
2018-05-07 23:01:41 +03:00
//====================paused===================
2018-05-07 23:01:41 +03:00
// void secondDisplay() {
// display.clear();
// display.setFont(ArialMT_Plain_16);
// display.setTextAlignment(TEXT_ALIGN_CENTER);
// display.drawString(0, 30, timeClient.getFormattedTime());
// display.drawRect(0,18,128,53); //frame
// /*
// 128/12=10px
// 128x32 resolution
// 32-19=13px for graph
// */
// int x = 0;
// for (int i=0;i<12;++i){
// display.drawLine(x+i*10, y[x], x+i*10+10, y[x]);
// }
// }
//===================WELL DONE=======================
void mainScreen() {
display.clear();
2018-05-07 23:01:41 +03:00
if (!nightMode()) { //turn off screen at night
int x = (timeClient.getHours()*60+timeClient.getMinutes())/11;
//Time
display.setFont(ArialMT_Plain_24);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 22, timeClient.getFormattedTime());
//progress bar
display.drawLine(0,22,x,22);
if (mqttAvail){ //do not show info if mqtt not available
//external temp //top left
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 0, "o:"+String(outTemp));
//pressure //top right
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_RIGHT);
display.drawString(128, 0, "p:"+String(pressure));
//inside temp //bottom left
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 53, "i:"+String(inTemp));
//humid //bottom right
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_RIGHT);
display.drawString(128, 53, "h:"+String(humid)+"%");
}
else {
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 53, "mqtt unavailable");
}
}
display.display();
}
2018-05-07 23:01:41 +03:00
void displayStatus(int state){
display.clear();
2018-05-29 16:29:09 +03:00
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_CENTER);
switch (state) {
case 0:
display.drawString(64, 22, "Connected!");
2018-05-29 16:29:09 +03:00
break;
case 1:
display.drawString(64, 22, "Connecting...");
2018-05-29 16:29:09 +03:00
break;
case 2:
display.drawString(64, 22, "Not connected!");
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 53, "we will die in 10s! :0");
2018-05-29 16:29:09 +03:00
break;
}
display.display();
}
2018-05-07 23:01:41 +03:00
void MQTT_connect() {
if (mqtt.connected()) {
return;
}
int8_t ret;
2018-05-07 23:01:41 +03:00
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) {
displayStatus(3);
mqtt.disconnect();
delay(5000);
retries--;
if (retries == 0) {
mqttAvail = false;
}
2018-05-07 23:01:41 +03:00
}
if (mqtt.connected())
mqttAvail = true;
2018-05-07 23:01:41 +03:00
}
void pressureCall(double x) {
pressure = x;
}
void inCall(double x) {
inTemp = x;
}
void outCall(double x) {
outTemp = x;
}
void humidCall(double x){
humid = x;
}
void updateNtp() {
2018-06-02 22:28:21 +03:00
// if (lastNtp != timeClient.getHours()) {
// if (timeClient.update())
while (!timeClient.update()) {
delay(100);
2018-05-07 23:01:41 +03:00
}
2018-06-02 22:28:21 +03:00
// lastNtp = timeClient.getHours();
// }
2018-05-07 23:01:41 +03:00
}
bool nightMode() {
if ((timeClient.getHours() > offTime)||(timeClient.getHours() < onTime)) { //turn off screen between loaded time
return true;
}
else
return false;
}