897 lines
40 KiB
C++
897 lines
40 KiB
C++
/*
|
|
"THE433"
|
|
"ESP8266 RF433 Interface"
|
|
"control 433MHz (compatible with Arduino libs) sockets/devices through web and time rules"
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
- thanks goes to fivosv for his patience to help me
|
|
|
|
----------------
|
|
|
|
used Arduino IDE: 1.6.5-r5
|
|
|
|
/*
|
|
"THE433"
|
|
"control 433MHz (compatible with Arduino libs) sockets/devices through web and time rules"
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
- thanks goes to fivosv for his patience to help me
|
|
|
|
----------------
|
|
|
|
used Arduino IDE: 1.6.5-r5
|
|
|
|
Files:
|
|
- THE433.ino // main sketch
|
|
- NKTP.h & NKNTP.ino // get NTP time and convert to local time.
|
|
- espWiFi2eeprom.h & espWiFi2eeprom.ino // esp8266 WiFi configuration to eeprom manager for Arduino IDE, check espWiFi2eeprom.h
|
|
|
|
Libraries needed:
|
|
- ESP/Arduino core (used working version 2.3.0)
|
|
- RCSwitch library for 433MHz RF control // https://github.com/sui77/rc-switch/
|
|
- RFControl library for 433MHz too.. // https://github.com/pimatic/RFControl
|
|
- (not a library) espWiFi2eeprom // https://github.com/nikant/espWiFi2eeprom
|
|
- Time library // https://github.com/PaulStoffregen/Time
|
|
- TimeAlarms library modified dtNBR_ALARMS from 6 to 20, NO NEED WITH THE NEW LIBRARY // https://github.com/PaulStoffregen/TimeAlarms
|
|
- TimeZone library // https://github.com/JChristensen/Timezone
|
|
|
|
----------------
|
|
|
|
To use this you have to know how to work with RF 433MHz switches/sockets and have
|
|
the needed transmitters/receivers for your esp8266 or NodeMCU dev kit.
|
|
|
|
In order to connect to WiFi this uses the espWiFi2eeprom added files.
|
|
You can read an example of how they work here: https://github.com/nikant/espWiFi2eeprom
|
|
and see some screenshots here: https://nobugsjustfeatures.wordpress.com/2016/03/27/esp8266-yet-another-esp-wifi-config-to-eeprom/
|
|
|
|
You must also set your own time zone in the NKNTP.h file.
|
|
|
|
Remember to set the appropriate 433 MHz RCSwitch codes to the "433 functions" section add new functions if needed
|
|
and their names to the TcommandsFunctions array.
|
|
Also the equal number of names to the TcommandsFNames array. Those last strings are also used from the main form of the web interface
|
|
to command an RF switch.
|
|
|
|
--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "FS.h" // https://github.com/esp8266/Arduino/blob/master/doc/filesystem.md
|
|
#include <ESP8266WiFi.h>
|
|
#include <ESP8266WebServer.h>
|
|
#include <WiFiClient.h>
|
|
#include <RCSwitch.h>
|
|
#include <RFControl.h>
|
|
#include "espWiFi2eeprom.h" // https://github.com/nikant/espWiFi2eeprom
|
|
#include "NKNTP.h"
|
|
#include <Time.h>
|
|
#include <TimeAlarms.h> // https://www.pjrc.com/teensy/td_libs_TimeAlarms.html
|
|
|
|
#define THE433_VERSION "0.8 NTP"
|
|
|
|
// Initialize the 433MHz RF switch
|
|
RCSwitch mySwitch = RCSwitch();
|
|
|
|
// Update these with values suitable for your network.
|
|
IPAddress nkip(192, 168, 1, 101); //Node static IP
|
|
IPAddress nkgateway(192, 168, 1, 1);
|
|
IPAddress nksubnet(255, 255, 255, 0);
|
|
|
|
// Port of esp8266 webserver
|
|
ESP8266WebServer server(80);
|
|
|
|
// 433MHz RF pins for esp8266 and the onboard led
|
|
// pin 4 is GPIO4 which is D2 in the NodeMCU v1.0 board.
|
|
#define RCSwitchPin 4
|
|
#define RFrepeatTimes 30
|
|
|
|
// set this to 1 for the NodeMCU devboard on board LED
|
|
#define HASONBOARDLED 0
|
|
#define ONBOARDLED 2
|
|
|
|
|
|
// Filename of SPIFFS savefile with TimeCommands
|
|
// ! Always with a / at the beginning of the filename !
|
|
#define TCSaveFile "/TCconfig.ini"
|
|
// Delimiter used in TimeCommands savefile: 1 character
|
|
#define TCSaveFileDelimiter ","
|
|
|
|
// Keyword to enter the Time Commands center from the start page
|
|
#define TCOMMANDWORD "ENTERTIMECOMMANDS"
|
|
|
|
// The number of alarms can be changed in the TimeAlarms header file TimeAlarms.h set by the constant dtNBR_ALARMS
|
|
// note that the RAM used equals dtNBR_ALARMS * 11 bytes
|
|
// right now for THE433 project it is set to #define dtNBR_ALARMS 20
|
|
// for 10 Time Alarms possible + spares for other internal functions
|
|
#define MAXTCommands 10
|
|
|
|
// Array that holds the Time Commands that are executed Once in RAM so they can be deleted from SPIFFS save file in the future
|
|
String alarmepochs[MAXTCommands][2];
|
|
int countTCommands = 0;;
|
|
|
|
// NTPInterval is how long we wait until NTP next NTP server poll
|
|
#define NTPinterval 1 * 24 * 3600000 // days * hours * milliseconds (1 day)
|
|
int NTPcountdown = 0;
|
|
#define NTPreboot 2
|
|
// Tracks the time since last NTP check
|
|
unsigned long NTPpreviousMillis = 0;
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
String webPageHeader(String webtitle, String webpagetitle, String backcolor, String fontcolor);
|
|
String TCommandsCall();
|
|
void RCSwitchCall(int PulseL, char* RCSCode, String thepinstate);
|
|
void switchon1();
|
|
void switchoff1();
|
|
void RFControlCall(unsigned long RFCbuckets[], char* RFCTimings, String thepinstate );
|
|
void switchon2();
|
|
void switchoff2();
|
|
String calcDigits(int digits);
|
|
time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss);
|
|
void nullFillalarmepochs();
|
|
void CleanupTC();
|
|
void SetupCleanTimer(String inTC, String OnceTCepoch, int inLine);
|
|
void SetupAlarms(int tmpTCommand, String tmpAlarmType, String tmpDOW, int tmpTChour, int tmpTCminute);
|
|
void parseTC(String inTC, int inLine);
|
|
String parseTC2HTML(String inTC, int inLine);
|
|
String timestamp();
|
|
void handle_restart();
|
|
void handle_timecommands();
|
|
void handle_TCsubmit();
|
|
void handle_TCsubmitRemove();
|
|
void handle_root();
|
|
void handle_submit();
|
|
void formatspiffs();
|
|
void removeTCSaveFile();
|
|
void readSpiffsTC();
|
|
void writeSpiffsTC(String inputline);
|
|
void RemoveLinesSpiffsTC(String Line2Remove);
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
// Available commands for all the 433MHz devices to be controled
|
|
// All functions available at the "433 functions" section below
|
|
// Function names
|
|
void (*TCommandsFunctions[])() = {switchon1, switchoff1, switchon2, switchoff2};
|
|
// Keywords that fire the 433MHz functions from the start page
|
|
char* TCommandsFNames[] = {"SWITCH-1-ON", "SWITCH-1-OFF", "SWITCH-2-ON", "SWITCH-2-OFF"};
|
|
// Calculate number of functions
|
|
#define numAvailFuncs (sizeof(TCommandsFNames)/sizeof(char *))
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
// -------------------------------- setup & loop ---------------------------------
|
|
|
|
void setup(void) {
|
|
WiFi.persistent(false);
|
|
|
|
if (HASONBOARDLED) pinMode(ONBOARDLED, OUTPUT);
|
|
byte ledStatus = HIGH;
|
|
|
|
mySwitch.enableTransmit(RCSwitchPin);
|
|
mySwitch.setRepeatTransmit(RFrepeatTimes);
|
|
|
|
Serial.begin(57600);
|
|
|
|
WiFi.mode(WIFI_STA);
|
|
// uncomment the following if you set a static IP in the begining
|
|
WiFi.config(nkip, nkgateway, nksubnet);
|
|
WiFi.setOutputPower(20.5);
|
|
|
|
// call espWiFi2eeprom to connect to saved to eeprom AP or
|
|
// to create an AP to store new values for SSID and password
|
|
espNKWiFiconnect();
|
|
//--
|
|
|
|
Serial.print(F("IP address: "));
|
|
Serial.println(WiFi.localIP());
|
|
|
|
// espWiFi2eeprom: with the two following you can restart or clear eeprom
|
|
// from your main esp8266 server
|
|
server.on(restartcommand, handle_APrestart);
|
|
server.on(cleareepromcommand, handle_clearAPeeprom);
|
|
//--
|
|
|
|
// get NTP time and convert it to local
|
|
// NKNTP.h and NKNTP.ino files must be present
|
|
// in NKNTP.h you can set your time zone and DST
|
|
NTP2localTime();
|
|
|
|
if (HASONBOARDLED) digitalWrite(ONBOARDLED, HIGH);
|
|
|
|
delay(100);
|
|
|
|
// Empty array of Time Commands at boot
|
|
nullFillalarmepochs();
|
|
|
|
delay(100);
|
|
|
|
// If we got NTP time then Time Commands are available
|
|
if (NTPsuccess) {
|
|
readSpiffsTC();
|
|
server.on("/TCsubmit", handle_TCsubmit);
|
|
server.on("/removeTCSaveFile", removeTCSaveFile);
|
|
server.on("/formatspiffs", formatspiffs);
|
|
server.on("/TClistdelline", handle_TCsubmitRemove);
|
|
}
|
|
server.on("/esp433restart", handle_restart);
|
|
|
|
server.on("/", handle_root);
|
|
server.on("/submit", handle_submit);
|
|
|
|
server.begin();
|
|
|
|
delay(100);
|
|
// Set up the cleanup function of Once only executed Time Commands and poll NTP server
|
|
Alarm.timerRepeat(33 * 59, CleanupTC); // (minutes * seconds) that must have passed in order to clean the alarm events, also poll NTP server
|
|
Alarm.delay(0);
|
|
Serial.println("Cleanup set");
|
|
|
|
Serial.println(F("HTTP server started"));
|
|
//debug
|
|
//for (int i = 0; i <= 10; i++) Serial.println(Alarm.read(i));
|
|
}
|
|
|
|
void loop(void) {
|
|
server.handleClient();
|
|
// the following is needed for the TimeAlarms libray
|
|
Alarm.delay(0);
|
|
}
|
|
|
|
// -------------------------------- START WEB and MESSAGES ---------------------------------
|
|
// HTML Strings etc.
|
|
String TCsubmitResult = "";
|
|
|
|
String SPIFFSstatus;
|
|
|
|
String SPIFFSTCommandsList;
|
|
|
|
String pinstate = "<h2>-</h2>";
|
|
|
|
const char webPageClearTCButton[] PROGMEM = "<br><form action=\"/removeTCSaveFile\" target=\"_top\"><input type=\"submit\" value=\"! Delete TimeCommands file !\"></form>\n";
|
|
|
|
const char webPageHomeButton[] PROGMEM = "<br><form action=\"/\" target=\"_top\"><input type=\"submit\" value=\"home\"></form>\n";
|
|
|
|
const char webPage433form[] PROGMEM = "\n<form action='/submit' method='POST'><input type=\"text\" name=\"pin\" value=\"\"><br><input type=\"submit\" value=\"Submit\"></form>\n";
|
|
|
|
const char webPageTC_0[] PROGMEM = "<table style=\"margin-left: auto;margin-right: auto;width:80%;border: 1px solid #fff;\"><tr>"
|
|
"<td style=\"text-align:center;width:10%;\"> </td><td style=\"text-align:left;width:40%;\"><br>";
|
|
|
|
const char webPageTC_1[] PROGMEM = "<br><br><form action='/TCsubmit' method='POST'><b>Time Command:</b> <input type=\"text\" name=\"tmcommand\" id=\"formtmcommand\" value=\"\" required=\"required\"><br><br><br><b>Schedule:</b> <br><br>"
|
|
"<input type=\"radio\" name=\"AlarmType\" value=\"AlarmOnce\"> <b>Alarm Once</b><br>(once when the time next reaches the given hour, minute)<br><br><input type=\"radio\" name=\"AlarmType\" value=\"AlarmRepeatDaily\"> <b>Daily Alarm Repeat</b><br>(every day at the given hour, minute)<br><br>"
|
|
"<input type=\"radio\" name=\"AlarmType\" value=\"AlarmOnceDOW\"> <b>Weekly Alarm Once</b><br>(once only on the next DayOfWeek, hour, minute)<br><br><input type=\"radio\" name=\"AlarmType\" value=\"AlarmRepeatDOW\"> <b>Weekly Alarm Repeat</b><br>(every week on the given DayOfWeek, hour, minute)<br><br><br><br><b>Time:</b> <br><br>"
|
|
"Day: <select size=\"1\" name=\"tcdow\" required=\"required\" id=\"formtcdow\">"
|
|
"<option value=\"\"> </option><option value=\"nodow\" selected>none</option><option value=\"1\">Sunday</option><option value=\"2\">Monday</option><option value=\"3\">Tuesday</option><option value=\"4\">Wednesday</option><option value=\"5\">Thursday</option><option value=\"6\">Friday</option><option value=\"7\">Saturday</option>"
|
|
"</select> Hour: <select size=\"1\" name=\"tchour\" required=\"required\" id=\"formtchour\">"
|
|
"<option value=\"\"> </option><option value=\"0\" selected>00</option><option value=\"1\">1</option><option value=\"2\">2</option><option value=\"3\">3</option><option value=\"4\">4</option><option value=\"5\">5</option><option value=\"6\">6</option><option value=\"7\">7</option><option value=\"8\">8</option><option value=\"9\">9</option>"
|
|
"<option value=\"10\">10</option><option value=\"11\">11</option><option value=\"12\">12</option><option value=\"13\">13</option><option value=\"14\">14</option><option value=\"15\">15</option><option value=\"16\">16</option><option value=\"17\">17</option><option value=\"18\">18</option><option value=\"19\">19</option><option value=\"20\">20</option><option value=\"21\">21</option><option value=\"22\">22</option><option value=\"23\">23</option>"
|
|
"</select> Minutes: <select size=\"1\" name=\"tcminutes\" required=\"required\" id=\"formtcminutes\">"
|
|
"<option value=\"\"> </option><option value=\"0\" selected>00</option><option value=\"1\">1</option><option value=\"2\">2</option><option value=\"3\">3</option><option value=\"4\">4</option><option value=\"5\">5</option><option value=\"6\">6</option><option value=\"7\">7</option><option value=\"8\">8</option><option value=\"9\">9</option>"
|
|
"<option value=\"10\">10</option><option value=\"11\">11</option><option value=\"12\">12</option><option value=\"13\">13</option><option value=\"14\">14</option><option value=\"15\">15</option><option value=\"16\">16</option><option value=\"17\">17</option><option value=\"18\">18</option><option value=\"19\">19</option><option value=\"20\">20</option><option value=\"21\">21</option><option value=\"22\">22</option><option value=\"23\">23</option>"
|
|
"<option value=\"24\">24</option><option value=\"25\">25</option><option value=\"26\">26</option><option value=\"27\">27</option><option value=\"28\">28</option><option value=\"29\">29</option><option value=\"30\">30</option><option value=\"31\">31</option><option value=\"32\">32</option><option value=\"33\">33</option><option value=\"34\">34</option><option value=\"35\">35</option><option value=\"36\">36</option><option value=\"37\">37</option>"
|
|
"<option value=\"38\">38</option><option value=\"39\">39</option><option value=\"40\">40</option><option value=\"41\">41</option><option value=\"42\">42</option><option value=\"43\">43</option><option value=\"44\">44</option><option value=\"45\">45</option><option value=\"46\">46</option><option value=\"47\">47</option>"
|
|
"<option value=\"48\">48</option><option value=\"49\">49</option><option value=\"50\">50</option><option value=\"51\">51</option><option value=\"52\">52</option><option value=\"53\">53</option><option value=\"54\">54</option><option value=\"55\">55</option><option value=\"56\">56</option><option value=\"57\">57</option><option value=\"58\">58</option><option value=\"59\">59</option>"
|
|
"</select> <br><br><input type=\"submit\" value=\"Submit\"></form><br>"
|
|
"</td><td style=\"text-align:center;width:10%;\"> </td><td style=\"text-align:left;width:40%;\"><br><br>";
|
|
|
|
const char webPageTC_2[] PROGMEM = "<br><br></td></tr></table>\n";
|
|
|
|
const char NTPfail[] PROGMEM = "<br><br><p style=\"font-size:medium\"><b>NTP Time failure. TimeCommands are not available!</b></p>\n";
|
|
const char SPIFFSTCommandsList_1[] PROGMEM = "<hr><br><b>--- TimeCommands in SPIFFS ---</b>";
|
|
const char SPIFFSTCommandsList_2[] PROGMEM = "<br><b>--- - ---</b><br><br>";
|
|
const char SPIFFSTCommandsList_3[] PROGMEM = "<form action=\"/TClistdelline\" target=\"_top\"><ul style=\"list-style-type:none\">";
|
|
const char SPIFFSTCommandsList_4[] PROGMEM = "<li><input type=\"radio\" name=\"TC2Remove\" value=\"";
|
|
const char SPIFFSTCommandsList_5[] PROGMEM = "</ul><input type=\"submit\" value=\"delete selected TimeCommand\"></form>\n";
|
|
const char esprestartmsg[] PROGMEM = "<br>Restart esp in order to activate TimeCommands!";
|
|
const char webPageRestartButton[] PROGMEM = "<br><form action=\"/esp433restart\" target=\"_top\"><input type=\"submit\" value=\"! RESTART ESP !\"></form>\n";
|
|
|
|
String webPageFooter = "\n<br>- version: " THE433_VERSION " -\n<br>ESP Free Heap: " + String(ESP.getFreeHeap()) + "\n</body></html>";
|
|
|
|
String webPageHeader(String webtitle, String webpagetitle, String backcolor, String fontcolor) {
|
|
return "<!DOCTYPE HTML>\n"
|
|
"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><title>" + webtitle + "</title>\n"
|
|
"<style type=\"text/css\">body {text-align:center;font-family: sans-serif;background-color: " + backcolor + ";color: " + fontcolor + ";} a:link, a:visited, a:hover, a:active {color:" + fontcolor + ";}</style>\n"
|
|
"</head>\n"
|
|
"<body>\n"
|
|
"<h1>" + webpagetitle + "</h1>\n";
|
|
}
|
|
|
|
// Lists the available Time Commands for the web interface
|
|
String TCommandsCall() {
|
|
String TCwebstring = "<ul style=\"list-style-type:none\">";
|
|
for (int i = 0; i < numAvailFuncs; ++i) {
|
|
String thetcommand = TCommandsFNames[i];
|
|
TCwebstring += "<li>";
|
|
TCwebstring += i + 1;
|
|
TCwebstring += ": <b>";
|
|
TCwebstring += "<a href=\"#\" target=\"_top\" onClick=\"document.getElementById(\'formtmcommand\').value=\'" + thetcommand + "\'\">";
|
|
TCwebstring += thetcommand;
|
|
TCwebstring += "</a>";
|
|
TCwebstring += "</b> <br><br>";
|
|
TCwebstring += "</li>";
|
|
}
|
|
TCwebstring += "</ul>";
|
|
return TCwebstring;
|
|
}
|
|
|
|
// -------------------------------- END WEB ---------------------------------
|
|
|
|
// -------------------------------- START 433 functions ---------------------------------
|
|
// Main 433MHz RF functions. Can be called from main page of the web interface with the keyowrds at the top.
|
|
|
|
// -------------------------------- with RCSwitch library -------------
|
|
|
|
void RCSwitchCall(int PulseL, char* RCSCode, String thepinstate) {
|
|
if (HASONBOARDLED) digitalWrite(ONBOARDLED, LOW);
|
|
mySwitch.setPulseLength(PulseL);
|
|
mySwitch.send(RCSCode);
|
|
//Serial.println(F("RF SEND"));
|
|
pinstate = thepinstate;
|
|
if (HASONBOARDLED) digitalWrite(ONBOARDLED, HIGH);
|
|
}
|
|
|
|
void switchon1() {
|
|
RCSwitchCall(260, "010001111000101001010101", "<h2>RC switch 1 ON</h2>");
|
|
//Pulse Length-^^
|
|
//Binary Code-------------^^^^
|
|
//HTML string for web page------------------------------^^^^^
|
|
}
|
|
|
|
void switchoff1() {
|
|
RCSwitchCall(260, "000010000000100101010100", "<h2>RC switch 1 OFF</h2>");
|
|
}
|
|
|
|
|
|
// -------------------------------- with RFControl library -------------
|
|
void RFControlCall(unsigned long RFCbuckets[], char* RFCTimings, String thepinstate ) {
|
|
if (HASONBOARDLED) digitalWrite(ONBOARDLED, LOW);
|
|
RFControl::sendByCompressedTimings(RCSwitchPin, RFCbuckets, RFCTimings, RFrepeatTimes);
|
|
//Serial.println(F("RF SEND"));
|
|
pinstate = thepinstate;
|
|
if (HASONBOARDLED) digitalWrite(ONBOARDLED, HIGH);
|
|
}
|
|
|
|
void switchon2() {
|
|
unsigned long nsigbuckets[] = {1256, 496, 2984, 6256, 0, 0, 0, 0};
|
|
RFControlCall(nsigbuckets, "01101010010000000101011111011001101001000100101024", "<h2>RC2-1</h2>");
|
|
}
|
|
|
|
void switchoff2() {
|
|
unsigned long nsigbuckets[] = {1256, 492, 2984, 6258, 0, 0, 0, 0};
|
|
RFControlCall(nsigbuckets, "01101101100100000110011111011010011001001010101024", "<h2>RC2-0</h2>");
|
|
}
|
|
|
|
|
|
// -------------------------------- END 433 functions ---------------------------------
|
|
|
|
// -------------------------------- START general functions ---------------------------------
|
|
|
|
// Pad time digits with zeros for HTML
|
|
String calcDigits(int digits) {
|
|
// utility function for digital clock display: prints preceding colon and leading 0
|
|
String stringDigi = "";
|
|
if (digits < 10) stringDigi = "0" + String(digits);
|
|
else stringDigi = String(digits);
|
|
return stringDigi;
|
|
}
|
|
|
|
// Time.h (library) function to convert given time to seconds
|
|
time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss)
|
|
{
|
|
tmElements_t tmSet;
|
|
tmSet.Year = YYYY - 1970;
|
|
tmSet.Month = MM;
|
|
tmSet.Day = DD;
|
|
tmSet.Hour = hh;
|
|
tmSet.Minute = mm;
|
|
tmSet.Second = ss;
|
|
return makeTime(tmSet); //convert to time_t
|
|
}
|
|
|
|
// -------------------------------- END general functions ---------------------------------
|
|
|
|
// -------------------------------- START ALARM functions ---------------------------------
|
|
|
|
// Empty array of Time Commands at boot
|
|
void nullFillalarmepochs() {
|
|
for (int i = 0; i < MAXTCommands; i++)
|
|
for (int j = 0; j < 2; j++) {
|
|
alarmepochs[i][j] = "";
|
|
}
|
|
}
|
|
|
|
// Function to delete Time Commands that have been executed and where set to execute Once only from SPIFFS save file
|
|
void CleanupTC() {
|
|
//debug
|
|
//Serial.print("tic "); Serial.println(second());
|
|
if (NTPsuccess) {
|
|
for (int i = 0; i < MAXTCommands; i++) {
|
|
if ((alarmepochs[i][0] != "") && (alarmepochs[i][1] != "")) {
|
|
unsigned long chcktm = alarmepochs[i][0].toInt();
|
|
if (chcktm > 0) {
|
|
// No need to set it here. It is set at main setup function at the end.
|
|
//chcktm = chcktm + (2 * 60); // (minutes * seconds) that must have passed in order to clean the alarm event
|
|
if (now() > chcktm) {
|
|
RemoveLinesSpiffsTC(alarmepochs[i][1]);
|
|
delay(100);
|
|
for (int j = 0; j < 2; j++) {
|
|
alarmepochs[i][j] = "";
|
|
}
|
|
Serial.println(F("periodic cleanup: TimeCommand removed!"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// NTP time poll every NTPinterval
|
|
unsigned long NTPcurrentMillis = millis();
|
|
if ((unsigned long)(NTPcurrentMillis - NTPpreviousMillis) >= NTPinterval) {
|
|
NTP2localTime();
|
|
Alarm.delay(0);
|
|
NTPpreviousMillis = NTPcurrentMillis;
|
|
if (!NTPsuccess) {
|
|
NTPcountdown++;
|
|
if (NTPcountdown = NTPreboot) handle_restart();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add Time Commands that are set to execute Once only to an array to be cleaned from SPIFFS save file
|
|
void SetupCleanTimer(String inTC, String OnceTCepoch, int inLine) {
|
|
inTC.replace("\n", "");
|
|
inTC.trim();
|
|
alarmepochs[inLine - 1][0] = OnceTCepoch;
|
|
alarmepochs[inLine - 1][1] = inTC;
|
|
}
|
|
|
|
// Set Time Commands to Alarms from TimeAlarms library at boot
|
|
void SetupAlarms(int tmpTCommand, String tmpAlarmType, String tmpDOW, int tmpTChour, int tmpTCminute) {
|
|
if (tmpAlarmType == "AlarmRepeatDaily") {
|
|
Alarm.alarmRepeat(tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
Serial.println(F("Alarm set!"));
|
|
} else if (tmpAlarmType == "AlarmOnce") {
|
|
Alarm.alarmOnce(tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
Serial.println(F("Alarm set!"));
|
|
} else {
|
|
//dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, or dowSaturday
|
|
if (tmpAlarmType == "AlarmRepeatDOW") {
|
|
if (tmpDOW == "1") {
|
|
Alarm.alarmRepeat(dowSunday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "2") {
|
|
Alarm.alarmRepeat(dowMonday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "3") {
|
|
Alarm.alarmRepeat(dowTuesday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "4") {
|
|
Alarm.alarmRepeat(dowWednesday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "5") {
|
|
Alarm.alarmRepeat(dowThursday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "6") {
|
|
Alarm.alarmRepeat(dowFriday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "7") {
|
|
Alarm.alarmRepeat(dowSaturday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
}
|
|
Serial.println(F("Alarm set!"));
|
|
} else if (tmpAlarmType == "AlarmOnceDOW") {
|
|
if (tmpDOW == "1") {
|
|
Alarm.alarmOnce(dowSunday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "2") {
|
|
Alarm.alarmOnce(dowMonday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "3") {
|
|
Alarm.alarmOnce(dowTuesday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "4") {
|
|
Alarm.alarmOnce(dowWednesday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "5") {
|
|
Alarm.alarmOnce(dowThursday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "6") {
|
|
Alarm.alarmOnce(dowFriday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
} else if (tmpDOW == "7") {
|
|
Alarm.alarmOnce(dowSaturday, tmpTChour, tmpTCminute, 0, TCommandsFunctions[tmpTCommand]);
|
|
}
|
|
Serial.println(F("Alarm set!"));
|
|
}
|
|
}
|
|
// Alarm.delay to feed the TimeAlarms library
|
|
Alarm.delay(100);
|
|
}
|
|
|
|
// Parse lines from the SPIFFS save file into SetupAlarms function above
|
|
// and also to the commands to be cleaned array
|
|
void parseTC(String inTC, int inLine) {
|
|
int tmpTCommand, tmpTChour, tmpTCminute, ind1, ind2, ind3, ind4, ind5, ind6;
|
|
String tmpAlarmType, TCcc, TChh, TCmm, tmpDOW, tmpOnceTCepoch, tmpisOnce;
|
|
|
|
ind1 = inTC.indexOf(TCSaveFileDelimiter);
|
|
ind2 = inTC.indexOf(TCSaveFileDelimiter, ind1 + 1);
|
|
ind3 = inTC.indexOf(TCSaveFileDelimiter, ind2 + 1);
|
|
ind4 = inTC.indexOf(TCSaveFileDelimiter, ind3 + 1);
|
|
ind5 = inTC.indexOf(TCSaveFileDelimiter, ind4 + 1);
|
|
ind6 = inTC.indexOf(TCSaveFileDelimiter, ind5 + 1);
|
|
|
|
TCcc = inTC.substring(0, ind1);
|
|
tmpTCommand = TCcc.toInt();
|
|
tmpAlarmType = inTC.substring(ind1 + 1, ind2);
|
|
tmpDOW = inTC.substring(ind2 + 1, ind3);
|
|
TChh = inTC.substring(ind3 + 1, ind4);
|
|
tmpTChour = TChh.toInt();
|
|
TCmm = inTC.substring(ind4 + 1, ind5);
|
|
tmpTCminute = TCmm.toInt();
|
|
tmpOnceTCepoch = inTC.substring(ind5 + 1, ind6);
|
|
tmpisOnce = inTC.substring(ind6 + 1);
|
|
SetupAlarms(tmpTCommand, tmpAlarmType, tmpDOW, tmpTChour, tmpTCminute);
|
|
// set commands that are Once only to an array to be cleaned from SPIFFS save file
|
|
if (tmpisOnce == "1") SetupCleanTimer(inTC, tmpOnceTCepoch, inLine);
|
|
//Serial.println(inLine); Serial.println(tmpOnceTCepoch);
|
|
}
|
|
|
|
// Parse lines from the SPIFFS save file for HTML show
|
|
String parseTC2HTML(String inTC, int inLine) {
|
|
String tmpAlarmType, TCcc, tmpTChour, tmpTCminute, TCdd, parsed2html;
|
|
int ind1, ind2, ind3, ind4, ind5, ind6, tmpTCommand, tmpDOW;
|
|
|
|
ind1 = inTC.indexOf(TCSaveFileDelimiter);
|
|
ind2 = inTC.indexOf(TCSaveFileDelimiter, ind1 + 1);
|
|
ind3 = inTC.indexOf(TCSaveFileDelimiter, ind2 + 1);
|
|
ind4 = inTC.indexOf(TCSaveFileDelimiter, ind3 + 1);
|
|
ind5 = inTC.indexOf(TCSaveFileDelimiter, ind4 + 1);
|
|
ind6 = inTC.indexOf(TCSaveFileDelimiter, ind5 + 1);
|
|
|
|
TCcc = inTC.substring(0, ind1);
|
|
tmpTCommand = TCcc.toInt();
|
|
tmpAlarmType = inTC.substring(ind1 + 1, ind2);
|
|
TCdd = inTC.substring(ind2 + 1, ind3);
|
|
tmpDOW = TCdd.toInt();
|
|
tmpTChour = inTC.substring(ind3 + 1, ind4);
|
|
tmpTCminute = inTC.substring(ind4 + 1, ind5);
|
|
//tmpOnceTCepoch = inTC.substring(ind5 + 1, ind6);
|
|
//tmpisOnce = inTC.substring(ind6 + 1);
|
|
parsed2html = "<b>" + String(inLine) + ". type:</b>" + tmpAlarmType + " <b>command:</b>";
|
|
parsed2html += String(TCommandsFNames[tmpTCommand]);
|
|
if (tmpDOW > 0) parsed2html += " <b>day:</b>" + String(dayStr(tmpDOW));
|
|
parsed2html += " <b>hour:</b>" + String(tmpTChour) + " <b>minute:</b>" + tmpTCminute + "<br><br>";
|
|
return parsed2html;
|
|
}
|
|
|
|
// -------------------------------- END ALARM functions ---------------------------------
|
|
|
|
// -------------------------------- START server functions ---------------------------------
|
|
// Timestamp function for the web interface
|
|
String timestamp() {
|
|
if (NTPsuccess) {
|
|
String theday = dayStr(weekday());
|
|
String themonth = monthStr(month());
|
|
return "<br><br><p>local time timestamp: <b>" + theday + ", " + String(day()) + " " + themonth + " " + String(year()) + "</b> -- <b>" + calcDigits(hour()) + ":" + calcDigits(minute()) + ":" + calcDigits(second()) + "</b></p>\n";
|
|
} else return FPSTR(NTPfail);
|
|
}
|
|
|
|
// When the Restart button is pressed at the web interface
|
|
void handle_restart() {
|
|
String tmppinstate;
|
|
tmppinstate = pinstate;
|
|
pinstate = F("<b>Please wait a few seconds.<br>! Device will reboot !</b><br><br>");
|
|
pinstate += tmppinstate;
|
|
delay(100);
|
|
handle_root();
|
|
delay(500);
|
|
handle_APrestart();
|
|
}
|
|
|
|
// Main Time Commands web interface
|
|
void handle_timecommands() {
|
|
String SServerSend;
|
|
SServerSend = webPageHeader("THE433 TimeCommands control", "THE433 TimeCommands control", "#333", "#fff");
|
|
if (NTPsuccess) {
|
|
SServerSend += TCsubmitResult + SPIFFSstatus + "<br>";
|
|
SServerSend += FPSTR(webPageTC_0);
|
|
SServerSend += F("<b>You can add up to ");
|
|
SServerSend += MAXTCommands;
|
|
SServerSend += F(" Time Commands<br>(used Time Command slots: ");
|
|
SServerSend += countTCommands;
|
|
SServerSend += F(")</b>");
|
|
SServerSend += FPSTR(webPageTC_1);
|
|
SServerSend += TCommandsCall();
|
|
SServerSend += FPSTR(webPageTC_2);
|
|
}
|
|
SServerSend += timestamp();
|
|
SServerSend += FPSTR(webPageHomeButton);
|
|
if (NTPsuccess) SServerSend += FPSTR(SPIFFSTCommandsList_1);
|
|
if (NTPsuccess) SServerSend += SPIFFSTCommandsList;
|
|
if (NTPsuccess) SServerSend += FPSTR(SPIFFSTCommandsList_2);
|
|
if (NTPsuccess) SServerSend += FPSTR(webPageClearTCButton);
|
|
SServerSend += FPSTR(webPageRestartButton);
|
|
SServerSend += webPageFooter;
|
|
delay(100);
|
|
server.send(200, "text/html", SServerSend);
|
|
}
|
|
|
|
// When a new Time Command is added from the web interface
|
|
void handle_TCsubmit() {
|
|
String state = server.arg("tmcommand");
|
|
if (countTCommands < MAXTCommands) {
|
|
int TCommandPos = -1;
|
|
for (int i = 0; i < numAvailFuncs; ++i) {
|
|
if (state == TCommandsFNames[i]) {
|
|
TCommandPos = i;
|
|
}
|
|
}
|
|
if (TCommandPos == -1) {
|
|
TCsubmitResult = F("Command not found!");
|
|
} else {
|
|
if ((server.arg("AlarmType") == "") || (server.arg("tchour") == "") || (server.arg("tcminutes") == "")) {
|
|
TCsubmitResult = F("Wrong or no selection in Schedule or Time!");
|
|
} else if (((server.arg("tcdow") == "") || (server.arg("tcdow") == "nodow")) && ((server.arg("AlarmType") == "AlarmRepeatDOW") || (server.arg("AlarmType") == "AlarmOnceDOW"))) {
|
|
TCsubmitResult = F("You have to select a Day with that alarm type!");
|
|
} else if (((server.arg("tchour").toInt() >= 0) && (server.arg("tchour").toInt() < 24)) || ((server.arg("tcminutes").toInt() >= 0) && (server.arg("tcminutes").toInt() < 59))) {
|
|
String S2Write;
|
|
int s2d, s2h, s2m;
|
|
s2d = server.arg("tcdow").toInt();
|
|
s2h = server.arg("tchour").toInt();
|
|
s2m = server.arg("tcminutes").toInt();
|
|
S2Write = String(TCommandPos) + TCSaveFileDelimiter;
|
|
S2Write += server.arg("AlarmType") + TCSaveFileDelimiter;
|
|
if ((server.arg("AlarmType") == "AlarmRepeatDaily") || (server.arg("AlarmType") == "AlarmOnce")) {
|
|
S2Write += "nodow";
|
|
S2Write += TCSaveFileDelimiter;
|
|
} else S2Write += server.arg("tcdow") + TCSaveFileDelimiter;
|
|
S2Write += server.arg("tchour") + TCSaveFileDelimiter;
|
|
S2Write += server.arg("tcminutes") + TCSaveFileDelimiter;
|
|
time_t s_tm;
|
|
if (server.arg("AlarmType") == "AlarmOnce") {
|
|
if (s2h > hour()) {
|
|
s_tm = tmConvert_t(year(), month(), day(), s2h, s2m, 0);
|
|
} else if ((s2h == hour()) && (s2m > minute())) {
|
|
s_tm = tmConvert_t(year(), month(), day(), s2h, s2m, 0);
|
|
} else {
|
|
s_tm = tmConvert_t(year(), month(), day() + 1, s2h, s2m, 0);
|
|
}
|
|
S2Write += String(s_tm) + String(TCSaveFileDelimiter) + "1";
|
|
} else if (server.arg("AlarmType") == "AlarmOnceDOW") {
|
|
if (s2d == weekday()) {
|
|
if (s2h > hour()) {
|
|
s_tm = tmConvert_t(year(), month(), day(), s2h, s2m, 0);
|
|
} else if ((s2h == hour()) && (s2m > minute())) {
|
|
s_tm = tmConvert_t(year(), month(), day(), s2h, s2m, 0);
|
|
} else {
|
|
s_tm = tmConvert_t(year(), month(), day() + 7, s2h, s2m, 0);
|
|
}
|
|
} else {
|
|
int s2dd = s2d - weekday();
|
|
if (s2dd < 0) {
|
|
s2dd = s2dd + 7;
|
|
}
|
|
s_tm = tmConvert_t(year(), month(), day() + s2dd, s2h, s2m, 0);
|
|
}
|
|
S2Write += String(s_tm) + String(TCSaveFileDelimiter) + "1";
|
|
} else S2Write += "0" + String(TCSaveFileDelimiter) + "0";
|
|
writeSpiffsTC(S2Write);
|
|
}
|
|
}
|
|
} else {
|
|
TCsubmitResult = F("Up to ");
|
|
TCsubmitResult += MAXTCommands;
|
|
TCsubmitResult += F(" TimeCommands are allowed!");
|
|
}
|
|
delay(100);
|
|
handle_timecommands();
|
|
}
|
|
|
|
// Execute Time Command remove from save file from web interface
|
|
void handle_TCsubmitRemove() {
|
|
delay(100);
|
|
if (server.arg("TC2Remove") != "") {
|
|
RemoveLinesSpiffsTC(server.arg("TC2Remove"));
|
|
} else TCsubmitResult = F("No Time Command selected to delete!");
|
|
delay(100);
|
|
handle_timecommands();
|
|
}
|
|
|
|
// Main web page for controling 433MHz switches directly
|
|
void handle_root() {
|
|
String SServerSend;
|
|
SServerSend = webPageHeader("THE433 control", "THE433 control", "#000", "#fff") + pinstate;
|
|
SServerSend += FPSTR(webPage433form);
|
|
SServerSend += timestamp();
|
|
SServerSend += SPIFFSstatus;
|
|
SServerSend += FPSTR(webPageHomeButton);
|
|
SServerSend += webPageFooter;
|
|
server.send(200, "text/html", SServerSend);
|
|
}
|
|
|
|
// Form of the main web page, activates a 433MHz switch or enters Time Commands interface
|
|
void handle_submit() {
|
|
String state = server.arg("pin");
|
|
if (state == TCOMMANDWORD) { //"ENTERTIMECOMMANDS"
|
|
delay(1000);
|
|
handle_timecommands();
|
|
} else {
|
|
int TCommandPos = -1;
|
|
for (int i = 0; i < numAvailFuncs; ++i) {
|
|
if (state == TCommandsFNames[i]) {
|
|
TCommandPos = i;
|
|
}
|
|
}
|
|
if (TCommandPos != -1) {
|
|
TCommandsFunctions[TCommandPos]();
|
|
delay(3000);
|
|
handle_root();
|
|
} else {
|
|
pinstate = F("<h2>-</h2>");
|
|
if (HASONBOARDLED) digitalWrite(ONBOARDLED, HIGH);
|
|
delay(3000);
|
|
handle_root();
|
|
}
|
|
}
|
|
}
|
|
|
|
// -------------------------------- END server functions ---------------------------------
|
|
|
|
// -------------------------------- START SPIFFS functions ---------------------------------
|
|
// Format SPIFFS of esp8266, not accessible from the web interface
|
|
void formatspiffs() {
|
|
String SServerSend;
|
|
SServerSend = webPageHeader("THE433 control", "THE433 control", "#000", "#fff");
|
|
SServerSend += F("<h2>! formatting SPIFFS !<br>Please wait 30 seconds.<br>! Device will reboot then !</h2>");
|
|
SServerSend += timestamp();
|
|
SServerSend += webPageFooter;
|
|
server.send(200, "text/html", SServerSend);
|
|
SPIFFS.begin();
|
|
SPIFFS.format();
|
|
delay(30000);
|
|
Serial.println(F("SPIFFS formatted!"));
|
|
handle_APrestart();
|
|
}
|
|
|
|
// Deletes the TCSaveFile that Time Commands are stored in from SPIFFS
|
|
void removeTCSaveFile() {
|
|
SPIFFS.remove(TCSaveFile);
|
|
delay(1000);
|
|
Serial.println(TCSaveFile " removed.");
|
|
//handle_APrestart();
|
|
handle_restart();
|
|
}
|
|
|
|
// Reads the TCSaveFile that Time Commands are stored in from SPIFFS
|
|
// at boot and sets the needed Alarm timers.
|
|
// Also lists stored Time Commands for the web interface
|
|
void readSpiffsTC() {
|
|
SPIFFSstatus = "";
|
|
SPIFFSTCommandsList = "";
|
|
if (SPIFFS.begin()) {
|
|
SPIFFSstatus = F("SPIFFS mounted.\n");
|
|
Serial.println(SPIFFSstatus);
|
|
if (SPIFFS.exists(TCSaveFile)) {
|
|
Serial.println("reading " TCSaveFile);
|
|
File TCconfigFile = SPIFFS.open(TCSaveFile, "r");
|
|
if (TCconfigFile) {
|
|
SPIFFSTCommandsList = FPSTR(SPIFFSTCommandsList_3);
|
|
Serial.println("opened " TCSaveFile);
|
|
while (TCconfigFile.available()) {
|
|
String line = TCconfigFile.readStringUntil('\n');
|
|
line.replace("\n", "");
|
|
line.trim();
|
|
Serial.println(line);
|
|
countTCommands++;
|
|
parseTC(line, countTCommands);
|
|
delay(100);
|
|
SPIFFSTCommandsList += FPSTR(SPIFFSTCommandsList_4);
|
|
SPIFFSTCommandsList += line + "\"> ";
|
|
SPIFFSTCommandsList += parseTC2HTML(line, countTCommands);
|
|
SPIFFSTCommandsList += "</li>";
|
|
delay(100);
|
|
}
|
|
SPIFFSstatus += " " + String(countTCommands) + " commands read.\n";
|
|
SPIFFSTCommandsList += FPSTR(SPIFFSTCommandsList_5);
|
|
} else {
|
|
Serial.println("Error opening " TCSaveFile "!");
|
|
SPIFFSstatus = "Error opening " TCSaveFile "!\n";
|
|
}
|
|
TCconfigFile.close();
|
|
} else {
|
|
Serial.println(TCSaveFile " not found!");
|
|
SPIFFSstatus += F(" TimeCommands file not found!\n");
|
|
}
|
|
} else {
|
|
SPIFFSstatus = F("SPIFFS mount failed!\n");
|
|
}
|
|
SPIFFSstatus = "<p>" + SPIFFSstatus + "</p>\n";
|
|
}
|
|
|
|
// Writes a newly entered Time Command in TCSaveFile stored in SPIFFS
|
|
void writeSpiffsTC(String inputline) {
|
|
TCsubmitResult = "";
|
|
File TCconfigFile = SPIFFS.open(TCSaveFile, "a");
|
|
if (!TCconfigFile) {
|
|
Serial.println(TCSaveFile " doesn't exist yet. Creating it");
|
|
File TCconfigFile = SPIFFS.open(TCSaveFile, "w");
|
|
if (!TCconfigFile) {
|
|
Serial.println(TCSaveFile "file creation failed!!!");
|
|
TCsubmitResult = TCSaveFile "file creation failed!!!";
|
|
return;
|
|
}
|
|
}
|
|
TCconfigFile.println(inputline);
|
|
delay(100);
|
|
TCconfigFile.close();
|
|
TCsubmitResult = "TimeCommand written in " TCSaveFile;
|
|
TCsubmitResult += FPSTR(esprestartmsg);
|
|
TCsubmitResult += FPSTR(webPageRestartButton);
|
|
}
|
|
|
|
// Removes a given line from TCSaveFile
|
|
void RemoveLinesSpiffsTC(String Line2Remove) {
|
|
TCsubmitResult = "";
|
|
if (SPIFFS.begin()) {
|
|
SPIFFSstatus = F("SPIFFS mounted.\n");
|
|
Serial.println(SPIFFSstatus);
|
|
if (SPIFFS.exists(TCSaveFile)) {
|
|
Serial.println("reading " TCSaveFile);
|
|
File TCconfigFile = SPIFFS.open(TCSaveFile, "r");
|
|
File tempTCconfigFile = SPIFFS.open("/TCconfig.temp", "w");
|
|
if (!TCconfigFile || !tempTCconfigFile) {
|
|
Serial.println(F("/TCconfig.temp file creation failed!!! Aborting!"));
|
|
TCsubmitResult = F("/TCconfig.temp file creation failed!!! Aborting!");
|
|
return;
|
|
}
|
|
Serial.println("opened " TCSaveFile);
|
|
Serial.println(F("opened /TCconfig.temp"));
|
|
while (TCconfigFile.available()) {
|
|
String line = TCconfigFile.readStringUntil('\n');
|
|
line.replace("\n", "");
|
|
line.trim();
|
|
if (Line2Remove != line) {
|
|
Serial.println(line);
|
|
tempTCconfigFile.println(line);
|
|
}
|
|
delay(100);
|
|
}
|
|
Serial.println(F("/TCconfig.temp written."));
|
|
delay(10);
|
|
// close files
|
|
tempTCconfigFile.close();
|
|
TCconfigFile.close();
|
|
// replace config file
|
|
if (SPIFFS.exists("/TCconfig.temp")) {
|
|
SPIFFS.remove(TCSaveFile);
|
|
delay(100);
|
|
Serial.println(TCSaveFile " removed.");
|
|
SPIFFS.rename("/TCconfig.temp", TCSaveFile);
|
|
if (SPIFFS.exists(TCSaveFile)) {
|
|
Serial.println(TCSaveFile " replaced.");
|
|
TCsubmitResult = "TimeCommand removed!";
|
|
TCsubmitResult += FPSTR(esprestartmsg);
|
|
TCsubmitResult += FPSTR(webPageRestartButton);
|
|
}
|
|
}
|
|
} else {
|
|
Serial.println(TCSaveFile " not found!");
|
|
SPIFFSstatus += F(" TimeCommands file not found!\n");
|
|
}
|
|
} else {
|
|
SPIFFSstatus = F("SPIFFS mount failed!\n");
|
|
}
|
|
SPIFFSstatus = "<p>" + SPIFFSstatus + "</p>\n";
|
|
}
|
|
|
|
// -------------------------------- END SPIFFS functions ---------------------------------
|