basically finished, need testing

feature/web_interface
Arne Schroeder 2019-12-02 21:47:51 +01:00
parent 0e213afd22
commit 293f19e4e0
1 changed files with 310 additions and 57 deletions

View File

@ -3,18 +3,7 @@
// Update these with values suitable for your network. // Update these with values suitable for your network.
const int CONFIG_PIN = D0;
const char *ssid = "AcS";
const char *password = "67993776724373201548";
const char* mqtt_server = "192.168.1.98";
const String mqtt_client = "home/S000";
const String mqtt_topic_t = mqtt_client + String("/temperatur");
const String mqtt_topic_h = mqtt_client + String("/humidity");
const String mqtt_topic_p = mqtt_client + String("/pressure");
const String mqtt_topic_l = mqtt_client + String("/lux");
const String mqtt_topic_led_state = mqtt_client + String("/led_state");
const String mqtt_topic_led = mqtt_client + String("/led");
WiFiClient espClient; WiFiClient espClient;
PubSubClient client(espClient); PubSubClient client(espClient);
@ -44,13 +33,257 @@ Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 1234
unsigned long delayTime; unsigned long delayTime;
void setup() { //##########################################
//pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output // Config
//digitalWrite(BUILTIN_LED, HIGH); #include <EEPROM.h>
#define CONFIG_MAX_SIZE 1024
const int CONFIG_PIN = D0;
enum CONFIG_STATE {
CONFIG_NONE = 0x00,
CONFIG_VALID = 0x01,
};
///const String mqtt_topic_l = mqtt_client + String("/lux");
///const String mqtt_topic_led_state = mqtt_client + String("/led_state");
///const String mqtt_topic_led = mqtt_client + String("/led");
struct config_map {
char state;
char version;
char ssid[50];
char password[50];
byte mqtt_ip[4];
unsigned short mqtt_port;
char topic_base[20];
char topic_temperature[40];
char topic_pressure[40];
char topic_humidity[40];
//char topic_lux[20];
};
config_map config;
//##########################################
//##########################################
// Mode
enum RUN_MODE {
MODE_CONFIGURE,
MODE_RUN,
MODE_TEST
};
RUN_MODE mode = MODE_RUN;
//##########################################
//##########################################
// Config Server
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
#define CONFIG_SSID "WeatherConfig"
#define DISABLE_LOG 1
void print_init() {
#ifndef DISABLE_LOG
Serial.begin(115200); Serial.begin(115200);
#endif
}
template <class T>
void print(T val, bool newLine = true) {
#ifndef DISABLE_LOG
if (newLine) {
Serial.println(val);
} else {
Serial.print(val);
}
#endif
}
void setup_access_point() {
print<const char *>("Configuring access point...");
/* You can remove the password parameter if you want the AP to be open. */
WiFi.softAPConfig(IPAddress(192,168,4,1), IPAddress(192,168,4,1), IPAddress(255,255,255,0));
WiFi.softAP(CONFIG_SSID);
IPAddress myIP = WiFi.softAPIP();
print("AP IP address: ", false);
print<IPAddress>(myIP);
server.on("/", handleRoot);
server.on("/config", handleWriteConfig);
server.on("/reset", handleReset);
server.begin();
print<const char*>("HTTP server started");
}
void handleRoot() {
server.send(200, "text/html", "<html><head>"
"<title>WeatherSensor Config</title>"
"<style>label { display: inline-block; width: 165px; } h1 { text-align: center; } div { margin: 10px 0px; }</style>"
"</head><body>"
"<div style='margin: 0 auto; width: 400px;'>"
"<h1>Weather Sensor</h1>"
"<form id='SensorConfig' action='config' method='POST'>"
"<fieldset><legend>Config Details</legend>"
"<div><label for='ssid'>WLAN SSID:</label><input name='ssid' type='text' placeholder='WeatherSensorWiFi' value='' required autofocus></div>"
"<div><label for='pw'>WLAN Password:</label><input name='pw' type='text' placeholder='123456' required></div>"
"<div><label for='srv'>MQTT-Server IP:</label><input name='srv' type='text' placeholder='127.0.0.1' required></div>"
"<div><label for='port'>MQTT-Server Port:</label><input name='port' type='text' placeholder='1883' required></div>"
"<div><label for='dev'>Device Name:</label><input name='dev' type='text' placeholder='home/S000' required></div>"
"<div><label for='temperature'>Tag Temperatur:</label><input name='temperature' type='text' value='/temperature' required></div>"
"<div><label for='humidity'>Tag Humidity:</label><input name='humidity' type='text' value='/humidity' required></div>"
"<div><label for='pressure'>Tag Pressure:</label><input name='pressure' type='text' value='/pressure' required></div>"
"<div><input name='config' type='submit' value='Save'></div>"
"</fieldset></form>"
"<form method='POST' action='update' enctype='multipart/form-data'><fieldset disabled='disabled'>"
"<legend>Firmware Update</legend>"
"<div><input type='file' name='update'><input type='submit' value='Update'></div>"
"</fieldset></form></div></body></html>");
}
void handleWriteConfig() {
int args = server.args();
int errors = 0x1F;
if (args > 0) {
/*for(int i=0; i< args; ++i) {
Serial.print(server.argName(i));
Serial.print(" = ");
Serial.println(server.arg(i));
}*/
if (server.hasArg("ssid")) {
const String &ssid = server.arg("ssid");
ssid.toCharArray(config.ssid, 50);
errors &= ~(0x01);
}
if (server.hasArg("pw")) {
const String &pw = server.arg("pw");
pw.toCharArray(config.password, 50);
errors &= ~(0x02);
}
if (server.hasArg("dev")) {
const String &device = server.arg("dev");
device.toCharArray(config.topic_base, 20);
if (server.hasArg("temperature")) {
const String temperature = device + server.arg("temperature");
temperature.toCharArray(config.topic_temperature, 40);
errors &= ~(0x10);
}
if (server.hasArg("humidity")) {
const String humidity = device + server.arg("humidity");
humidity.toCharArray(config.topic_humidity, 40);
errors &= ~(0x10);
}
if (server.hasArg("pressure")) {
const String pressure = device + server.arg("pressure");
pressure.toCharArray(config.topic_pressure, 40);
errors &= ~(0x10);
}
}
if (server.hasArg("port")) {
int port = server.arg("port").toInt();
if (0 < port && port < 65535) {
config.mqtt_port = port;
errors &= ~(0x04);
}
}
if (server.hasArg("srv")) {
String addr = server.arg("srv");
for (int i=0; i<4; ++i) {
int val = addr.toInt();
if (0<=val && val<256) {
config.mqtt_ip[i] = val;
} else {
server.send(500, "text/html", "<div style='margin: 0 auto; width: 400px; text-align: center;background: #0F0; border: 1px solid #F00;'>"
"<h1>Weather Sensor</h1>"
"<div style='background: #FFF;'>ERROR - 4</div>"
"<div>Error while parsing the IP address!</div></div>");
errors &= ~(0x08);
}
int pos = addr.indexOf('.');
addr = addr.substring(pos+1);
}
errors &= ~(0x08);
}
print<int>(errors);
if (errors == 0x00) {
EEPROM.begin(CONFIG_MAX_SIZE);
config.state = CONFIG_VALID;
EEPROM.put(0, config);
EEPROM.end();
server.send(200, "text/html", "<div style='margin: 0 auto; width: 400px; text-align: center;background: #0F0; border: 1px solid #0F0;'>"
"<h1>Weather Sensor</h1>"
"<div style='background: #FFF;'>OK</div>"
"<div>Disable config mode and reboot device!</div></div>");
// @todo add reset link to html content
// @todo add current memory content to input boxes
return;
} else {
server.send(500, "text/html", "<div style='margin: 0 auto; width: 400px; text-align: center;background: #F00; border: 1px solid #F00;'>"
"<h1>Weather Sensor</h1>"
"<div style='background: #FFF;'>ERROR - 2</div>"
"<div>Error while parsing config values! Code: " + String(errors) + "</div></div>");
}
}
server.send(500, "text/html", "<div style='margin: 0 auto; width: 400px; text-align: center;background: #F00; border: 1px solid #0F0;'>"
"<h1>Weather Sensor</h1>"
"<div style='background: #FFF;'>ERROR - 1</div>"
"<div>Disable config mode and reboot device! </div></div>");
}
void handleReset() {
server.send(405, "text/html", "<div style='margin: 0 auto; width: 400px; text-align: center;background: #F00; border: 1px solid #0F0;'>"
"<h1>Weather Sensor</h1>"
"<div style='background: #FFF;'>ERROR - 3</div>"
"<div>Not implemented yet!</div></div>");
}
//##########################################
void setup() {
print_init();
//enable configuration Pin
pinMode(CONFIG_PIN, INPUT);
// read config from EEPROM
EEPROM.begin(CONFIG_MAX_SIZE);
EEPROM.get(0, config);
EEPROM.end();
if (digitalRead(CONFIG_PIN) == HIGH) {
mode = MODE_CONFIGURE;
//mode = MODE_TEST;
}
if (config.state != CONFIG_VALID && mode != MODE_CONFIGURE) {
mode = MODE_CONFIGURE;
}
switch(mode) {
case MODE_CONFIGURE:
print<const char*>("config");
pinMode(D4, OUTPUT);
digitalWrite(D4, LOW);
setup_access_point();
return;
case MODE_RUN:
print<const char*>("run");
setup_wifi(); setup_wifi();
setup_sensor(); setup_sensor();
client.setServer(mqtt_server, 1883); print<const char *>("MQTT Addr: ");
print<int>(config.mqtt_ip[0], false);
print<const char *>(".", false);
print<int>(config.mqtt_ip[1], false);
print<const char *>(".", false);
print<int>(config.mqtt_ip[2], false);
print<const char *>(".", false);
print<int>(config.mqtt_ip[3], false);
print<const char *>(":", false);
print<long>(config.mqtt_port);
client.setServer(IPAddress(config.mqtt_ip[0], config.mqtt_ip[1], config.mqtt_ip[2], config.mqtt_ip[3]), config.mqtt_port);
//client.setCallback(callback); //client.setCallback(callback);
if (!client.connected()) { if (!client.connected()) {
@ -63,7 +296,25 @@ void setup() {
delay(500); delay(500);
client.loop(); client.loop();
delay(500); delay(500);
ESP.deepSleep(300e6); ESP.deepSleep(300e6); // 300 sec = 5 min
return;
case MODE_TEST:
print<const char *>("testing");
WiFi.mode(WIFI_AP_STA);
WiFi.begin("AcS", "67993776724373201548");
if (WiFi.waitForConnectResult() == WL_CONNECTED) {
print<const char *>("Connected ", false);
print<IPAddress>(WiFi.localIP());
//server.on("/", handleRoot);
//server.on("/config", handleWriteConfig);
//todo file upload
server.begin();
print<const char *>("HTTP server started");
} else {
print<const char *>("WiFi Failed");
}
return;
}
} }
@ -71,27 +322,26 @@ void setup() {
void setup_wifi() { void setup_wifi() {
delay(10); delay(10);
// We start by connecting to a WiFi network // We start by connecting to a WiFi network
Serial.println(); print<const char*>("Connecting to ");
Serial.print("Connecting to "); print<const char*>(config.ssid);
Serial.println(ssid);
WiFi.begin(ssid, password); WiFi.begin(config.ssid, config.password);
while (WiFi.status() != WL_CONNECTED) { while (WiFi.status() != WL_CONNECTED) {
delay(500); delay(500);
Serial.print("."); print<const char*>(".", false);
} }
Serial.println(""); print<const char *>("");
Serial.println("WiFi connected"); print<const char*>("WiFi connected");
Serial.println("IP address: "); print<const char*>("IP address: ", false);
Serial.println(WiFi.localIP()); print<IPAddress>(WiFi.localIP());
} }
void setup_sensor() { void setup_sensor() {
Serial.print(F("BME280 setup... ")); print<const __FlashStringHelper*>(F("BME280 setup... "));
bool status; bool status;
// default settings // default settings
@ -99,7 +349,7 @@ void setup_sensor() {
status = bme.begin(); status = bme.begin();
if (!status) { if (!status) {
while(1) { while(1) {
Serial.println("Could not find a valid BME280 sensor, check wiring!"); print<const char*>("Could not find a valid BME280 sensor, check wiring!");
//while (1); //while (1);
delay(2000); delay(2000);
} }
@ -137,20 +387,19 @@ void callback(char* topic, byte* payload, unsigned int length) {
void reconnect() { void reconnect() {
// Loop until we're reconnected // Loop until we're reconnected
const String start_topic = mqtt_client + String("/client"); const String start_topic = config.topic_base + String("/client");
while (!client.connected()) { while (!client.connected()) {
Serial.print("Attempting MQTT connection..."); print<const char*>("Attempting MQTT connection...", false);
// Attempt to connect // Attempt to connect
if (client.connect(mqtt_client.c_str())) { if (client.connect(config.topic_base)) {
Serial.println("connected"); print<const char*>("connected");
// Once connected, publish an announcement... // Once connected, publish an announcement...
client.publish(start_topic.c_str(), "hello world"); client.publish(start_topic.c_str(), "hello world");
// ... and resubscribe // ... and resubscribe
client.subscribe(mqtt_topic_led.c_str()); ///client.subscribe(mqtt_topic_led.c_str());
} else { } else {
Serial.print("failed, rc="); sprintf(msg, "failed, rc=%d try again in 5 seconds", client.state());
Serial.print(client.state()); print<char *>(msg);
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying // Wait 5 seconds before retrying
delay(5000); delay(5000);
} }
@ -161,8 +410,8 @@ void reconnect() {
void process_sensor() { void process_sensor() {
unsigned long t1 = millis(); unsigned long t1 = millis();
Serial.print("ReadSensor: "); print<const char*>("ReadSensor: ", false);
Serial.println(t1-t0); print<unsigned long>(t1-t0);
t0 = t1; t0 = t1;
auto temperatur = bme.readTemperature(); auto temperatur = bme.readTemperature();
auto humidity = bme.readHumidity(); auto humidity = bme.readHumidity();
@ -179,16 +428,20 @@ void process_sensor() {
snprintf(msg, 75, "T: %0.2f *C, P: %0.2f hPa, H: %0.2f, L: %0.0f LED: %d", snprintf(msg, 75, "T: %0.2f *C, P: %0.2f hPa, H: %0.2f, L: %0.0f LED: %d",
temperatur, pressure, humidity, light, led); temperatur, pressure, humidity, light, led);
client.publish(mqtt_topic_t.c_str(), String(temperatur).c_str()); client.publish(config.topic_temperature, String(temperatur).c_str());
client.publish(mqtt_topic_h.c_str(), String(humidity).c_str()); client.publish(config.topic_humidity, String(humidity).c_str());
client.publish(mqtt_topic_p.c_str(), String(pressure).c_str()); client.publish(config.topic_pressure, String(pressure).c_str());
client.publish(mqtt_topic_l.c_str(), String(light).c_str()); ///client.publish(mqtt_topic_l.c_str(), String(light).c_str());
client.publish(mqtt_topic_led_state.c_str(), String(led).c_str()); ///client.publish(mqtt_topic_led_state.c_str(), String(led).c_str());
Serial.println(msg); print<char*>(msg);
} }
void loop() { void loop() {
if (MODE_CONFIGURE == mode) {
server.handleClient();
} else {
delay(500); delay(500);
}
} }