const char SSID[] = ""; const char PASSWORD[] = ""; #include "globalvars.h" #include #include #include #include #include #include #include #include #include ESP8266WebServer server; IPAddress staticIP(192, 168, 2, 4); // static IP address IPAddress gateway(192, 168, 2, 1); // Router's IP address IPAddress subnet(255, 255, 255, 0); IPAddress dns(192, 168, 2, 1); Timezone myTime; const u_int r = 0; // D3 on Amica const u_int oneWireBus = 0; OneWire oneWire(oneWireBus); DallasTemperature sensors(&oneWire); int temperature, temperatureSet, minTemperatureSet; static unsigned long lastTempCycle = -5000; static unsigned long lastTimeCycle = -5000; char time_all[8][8][3] = { {}, {}, {}, {}, {}, {}, {}, {}}; // 3D array for load_EEPROM() and handleTime() const unsigned int pins[] = {4}; // D2 on Amica char stat[][4] = {"AUS"}; // text on button char t_stat[][4] = {""}; // for "status of timer changed" bool override[] = {false}; // for manual override char home_html[1346]; char settings_html[987]; const char settings_html_pre[] PROGMEM = {"\ \ \ \ \ \ Einstellungen\ \ \ \
\
\ \
\ \ - \
\ \ - \
"}; void reload_home(); void reload_settings(); void handleToggle(); void handleReset(); void handleRestart(); void load_EEPROM() { unsigned int EEPROM_Addr = 0; for (unsigned int i0 = 0; i0 < 8; i0++) { for (unsigned int i = 0; i < 8; i++) { sprintf(time_all[i0][i], "%02d", EEPROM.read(EEPROM_Addr)); EEPROM_Addr += 4; yield(); } } temperatureSet = EEPROM.read(256); minTemperatureSet = EEPROM.read(260); } void handleHome() { reload_home(); server.send(200, "text/html", home_html); debugln(ESP.getFreeHeap(), DEC); } void handleSettings() { reload_settings(); server.setContentLength(strlen(settings_html_pre) + strlen(settings_html)); server.send(200, "text/html", settings_html_pre); server.sendContent(settings_html); debugln(ESP.getFreeHeap(), DEC); } void handleReset() { for (int i = 0; i < 264; i++) { EEPROM.put(i, 0); EEPROM.commit(); } server.send(200, "text/html", "

EEPROM has been " "reset.

"); } void handleRestart() { server.send(200, "text/html", "

Restarting...

"); server.close(); delay(1000); ESP.restart(); } void handleTime() { bool changed = false; if (server.arg("rule") != "") { debugln("write main"); const char args[4][9] = {"time_o", "time_f", "time_o_1", "time_f_1"}; for (unsigned int arg = 0; arg < 4; arg++) { if (server.arg(args[arg]) != "") { char buff_h[2][2] = {server.arg(args[arg])[0], server.arg(args[arg])[1]}; char buff_m[2][2] = {server.arg(args[arg])[3], server.arg(args[arg])[4]}; sprintf(time_all[arg * 2][server.arg("rule").toInt()], "%s%s", buff_h[0], buff_h[1]); sprintf(time_all[arg * 2 + 1][server.arg("rule").toInt()], "%s%s", buff_m[0], buff_m[1]); EEPROM.put(server.arg("rule").toInt() * 4 + arg * 64, atoi(time_all[arg * 2][server.arg("rule").toInt()])); EEPROM.commit(); EEPROM.put( server.arg("rule").toInt() * 4 + arg * 64 + 32, atoi(time_all[arg * 2 + 1][server.arg("rule").toInt()])); EEPROM.commit(); changed = true; } } } if (server.arg("temperature").toInt() != temperatureSet) { debugln("write temperature"); temperatureSet = server.arg("temperature").toInt(); EEPROM.put(256, temperatureSet); EEPROM.commit(); changed = true; } if (server.arg("min_temperature").toInt() != minTemperatureSet) { debugln("write minTemperature"); minTemperatureSet = server.arg("min_temperature").toInt(); EEPROM.put(260, minTemperatureSet); EEPROM.commit(); changed = true; } if (changed) { lastTimeCycle = -5000; // trigger timer() reload_settings(); server.sendHeader(F("Location"), F("/settings"), true); server.send(302); } else { server.send(204); // nothing changed (except maybe current temperature), // so no page update needed } } void timer() { if (millis() - lastTimeCycle > 5000) { int ri = 0; bool isOn = false; while (ri <= 7) { if (((((myTime.hour() * 60 + myTime.minute() >= atoi(time_all[0][ri]) * 60 + atoi(time_all[1][ri])) and (myTime.hour() * 60 + myTime.minute() < atoi(time_all[2][ri]) * 60 + atoi(time_all[3][ri]))) // first range or ((myTime.hour() * 60 + myTime.minute() >= atoi(time_all[4][ri]) * 60 + atoi(time_all[5][ri])) and (myTime.hour() * 60 + myTime.minute() < atoi(time_all[6][ri]) * 60 + atoi(time_all[7][ri]))) or ((atoi(time_all[0][ri]) == atoi(time_all[2][ri])) and ((atoi(time_all[1][ri]) == atoi(time_all[3][ri])) and (atoi(time_all[0][ri]) + atoi(time_all[1][ri]) != 0)))) // second range and temperature <= temperatureSet) or temperature <= minTemperatureSet) { isOn = true; } ri++; } if (isOn) { if ((override[r]) and (strcmp(t_stat[r], "off") == 0)) { override[r] = false; debugln(F("debug#1")); } sprintf(t_stat[r], "on"); if (!override[r]) { digitalWrite(pins[r], HIGH); analogWrite(LED_BUILTIN_AUX, 100); // LED if (strcmp(stat[r], "AUS") == 0) { debug(r); debugln(F(" is on")); sprintf(stat[r], "AN"); } } } else { if ((override[r]) and (strcmp(t_stat[r], "on") == 0)) { override[r] = false; } sprintf(t_stat[r], "off"); if (!override[r]) { digitalWrite(pins[r], LOW); analogWrite(LED_BUILTIN_AUX, 0); // LED if (strcmp(stat[r], "AN") == 0) { debug(r); debugln(F(" is off")); sprintf(stat[r], "AUS"); } } } lastTimeCycle = millis(); } } uint ledBrightness = 0; int ledBrightnessStep = 20; uint lastLedCycle; void pulseLed() { if (millis() - lastLedCycle > 100) { analogWrite(LED_BUILTIN_AUX, ledBrightness); ledBrightness += ledBrightnessStep; if (ledBrightness <= 0 || ledBrightness >= 255) { ledBrightnessStep = -ledBrightnessStep; } lastLedCycle = millis(); } } void emergencyStop() { for (uint pin = 0; pin < sizeof(pins) / sizeof(pins[0]); pin++) { debug("Emergency stop, pulling down pin: "); debugln(pin); digitalWrite(pins[pin], LOW); } server.close(); char apSSID[32]; sprintf(apSSID, "ESP-%06X has an issue", ESP.getChipId()); WiFi.softAP(apSSID, "", 1, false, 0); unsigned long lastTry = millis(); while (millis() - lastTry < (1000 * 60)) { analogWrite(LED_BUILTIN, 255); analogWrite(LED_BUILTIN_AUX, 0); delay(125); analogWrite(LED_BUILTIN, 0); analogWrite(LED_BUILTIN_AUX, 255); delay(125); analogWrite(LED_BUILTIN, 255); analogWrite(LED_BUILTIN_AUX, 255); delay(250); } ESP.restart(); } void getCurrentTemperature() { if (millis() - lastTempCycle > 5000) { sensors.requestTemperatures(); temperature = int(sensors.getTempCByIndex(0)); lastTempCycle = millis(); if (temperature == -127) { emergencyStop(); } } } void setup() { pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN_AUX, OUTPUT); analogWrite(LED_BUILTIN, 255); analogWrite(LED_BUILTIN_AUX, 255); uint p = 0; while (p <= sizeof(pins) / sizeof(pins[0])) { pinMode(pins[p], OUTPUT); digitalWrite(pins[p], LOW); p++; } Serial.begin(74880); EEPROM.begin(264); // 4 bits for EEPROM, address 0-263, value 0-255 sensors.begin(); debug(F("\nver. ")); debug(BUILD_VERSION); debugln(BUILD_DEBUG ? "-debug" : ""); debugln(F("check for updates at " "https://somepi.ddns.net/gitea/gilex-dev/ESP8266-IOT-timer/\n")); load_EEPROM(); // WiFI-config // WiFi.mode(WIFI_STA); // comment to force use of staticIP // WiFi.config(staticIP, gateway, subnet, dns); WiFi.hostname("esp8266-iot-dev"); WiFi.begin(SSID, PASSWORD); uint32_t notConnectedCounter = 0; debug(F("Connecting to ")); debugln(WiFi.SSID()); while (WiFi.status() != WL_CONNECTED) { delay(250); debug(F(".")); analogWrite(LED_BUILTIN_AUX, 255 * (notConnectedCounter % 2)); // LED notConnectedCounter++; if (notConnectedCounter > (1000 / 250) * 15) { // Reset board if not connected after 15s debugln("\nResetting due to Wifi not connecting"); ESP.restart(); } } analogWrite(LED_BUILTIN_AUX, 0); debug(F("\nConnected to ")); debugln(WiFi.SSID()); debug(F("IP address: ")); debugln(WiFi.localIP()); ArduinoOTA.begin(); // Time-config myTime.setLocation("de"); // setServer("192.168.2.1"); // uncomment to set custom NTP server if (!waitForSync(TIMEZONED_TIMEOUT / 1000)) { // Reset instead of using fallback timezone debugln("\nResetting due to NTP not syncing"); ESP.restart(); } debug(F("Local time: ")); debugln(myTime.dateTime("H:i:s")); setInterval(60 * 60 * 11); // + NTP_STALE_AFTER=3602 = sync every ~ 12 h // Server-config server.on("/", HTTP_GET, handleHome); server.on("/settings", HTTP_GET, handleSettings); server.on("/settings", HTTP_POST, handleTime); server.on("/toggle", HTTP_GET, handleToggle); server.on("/reset", HTTP_GET, handleReset); server.on("/restart", HTTP_GET, handleRestart); server.on("/version", HTTP_GET, [] { char softwareVersion[32]; sprintf(softwareVersion, "%s%s", BUILD_VERSION, BUILD_DEBUG ? "-debug" : ""); server.send(200, "text/html", softwareVersion); }); getCurrentTemperature(); server.begin(); debugln(F("Webserver started")); } void loop() { server.handleClient(); getCurrentTemperature(); timer(); yield(); delay(50); events(); ArduinoOTA.handle(); pulseLed(); }