";
s += HTTP_TEXT_END;
}
else if (argument == "/setup") {
s = HTTP_ANSWER;
s += HTTP_HEAD_PWR;
s += ""; s += cPWR.getPName(); s += "";
s += HTTP_BODYSTYLE_PWR; s += "";
s += HTTP_DIV_FIELD;
s += "
";
s += HTTP_TEXT_END;
}
else if (argument == "/favicon.ico") {
s = HTTP_ANSWER;
s += "none";
}
else if (argument == "/searchLogger") {
s = HTTP_ANSWER;
int argBegin = line.indexOf("?");
s += "{\"DTZLOGGER\":\"" + PWRVersion + "\"}";
}
else if (argument == "/" || argument == "/back") {
// Prepare the response
s = HTTP_ANSWER;
s += HTTP_HEAD_PWR;
s += ""; s += cPWR.getPName(); s += "";
s += HTTP_BODYSTYLE_PWR; s += "";
s += HTTP_DIV_FIELD;
s += "
"; s += cPWR.getPName(); s += " aktiv: ";
if(cPWR.getActionOn()) s+="✅"; else s += "😞";
s +="
";
s += "Verbunden mit Zähler: ";
if(_receivedOK == true)s += "✅"; // show a red bubble when StromLog not connect on server at the first time
else s += "😞";
s += " Status Relais: ";
if(digitalRead(RELAIS))s += "👍"; // show status of relais
else s += "👎";
s += " ";
s += "Tages Einschaltzeit: "; s+=_onTime/60; s+=" Minuten ";
s += "
Aktuelle Leistung: "; s+=_actualConsumption; s += " W ";
if(cPWR.getActionOn()){
s += "Relais AN < "; s+=cPWR.getValueON(); s+=" W AUS > "; s+=cPWR.getValueOFF(); s+="W";
} else {
s += " ";
s += "";
}
s += "
";
s += "Einschalt Wartezeit: "; s+= cPWR.getWaitAction()-_waitTimeCount; s+=" s ";
s += "Protokoll Errors: "; s+= _errorCount; s+=" ";
s += HTTP_HISTORY_BUTTON;
s += HTTP_SETUP_BUTTON;
// s += "Text\n";
s += "
";
s += "\n";
s += "";
s += HTTP_JS_SCRIPT;
}
else if (argument == "/memory") {
s = HTTP_ANSWER;
s += "Free space: "; s += cPWR.FREESPACE; s += " ";
s += HTTP_TEXT_END;
}
else if (argument == "/history") {
s = HTTP_ANSWER;
s += HTTP_HEAD_PWR;
s += HTTP_BODYSTYLE_PWR; s += "";
s += HTTP_DIV_FIELD;
s += " PWR-Schalter History:
";
s += getHistory();
s += "
History End
";
s += " ";
s += HTTP_TEXT_END;
}
else if (argument == "/delHistory") {
s = HTTP_ANSWER;
s += "Saved history will delete now!";
s += HTTP_TEXT_END;
cPWR.delSavedHistory();
}
else if(argument == "/savedhistory"){
s = HTTP_ANSWER;
s += cPWR.readSavedHistory();
s += HTTP_TEXT_END;
}
else if(argument == "/shutdown"){
saveHistoryStatus(SHUTDOWN);
cPWR.saveHistory(getRawHistory());
s = HTTP_ANSWER;
s += "Restart power-regler now! ";
s += HTTP_TEXT_END;
delay(500);
ESP.restart();
}
#ifdef OTA_on
else if (argument == "/firmware"){
s = HTTP_ANSWER;
s += "Your PWRegler versions number: "+Version+" ";
s += "Check for new firmware now. ";
s += getFilesFromServer(WiFi.localIP());
s += HTTP_TEXT_END;
}
else if (argument == "/upDate"){
int valueBegin = line.indexOf("?");
s = HTTP_ANSWER;
if(valueBegin > 0){
int valueEnd = line.indexOf("HTTP");
String argumentValue = line.substring(valueBegin+1,valueEnd-1);
if(argumentValue.indexOf(ESPRAM)>0){ // check if the right firmware and memory of esp (1M,2M,4M....)
s += "Update will be start now. ";
s += "Update-file: "+argumentValue+" ";
s += "Don't turn off power during update!
";
s += "After update, the reconnection only via IP, without arguments behind it!
";
s += "Click here for reconnect after update ";
} else{
s += "Wrong firmware for this IoT. Update canceled. ";
argument ="";
}
} else {
s += "Error: Missing name of update file! ";
s += "Update canceled. ";
argument ="";
}
s += HTTP_TEXT_END;
}
#endif
else if(argument == "/setTime"){
s = HTTP_ANSWER;
s += HTTP_BODYSTYLE_PWR; s += "";
s += HTTP_DIV_FIELD;
s += "
Die Uhr wird jetzt neu synchronisiert.
";
s += "
Zeit:
";
if (syncron_NTP_Time() == true){
getTime2Value(_timestamp);
s += "Neue Zeit:
";
} else {
s += "Serverfehler! Aktuallisierung nicht erfolgt. Bitte eine Wartezeit von 2 Minuten, bis zur wiederholten, manuellen Aktuallisierung einhalten. ";
}
s += "
";
s += HTTP_TEXT_END;
}
else s = "HTTP/1.1 403 OK\r\nContent-Type: text/html\r\n\r\n";
// Send the response to the client
client.print(s);
delay(1);
#ifdef OTA_on
if(argument == "/upDate"){
turnAllOff();
int valueBegin = line.indexOf("?");
if(valueBegin > 0){
int valueEnd = line.indexOf("HTTP");
argument = line.substring(valueBegin+1,valueEnd-1);
delay(1000); //wait one second
updateStromLog(argument); // start update now
}
}
#endif
}
}
}
//*********** update new software for StromLog ***************************/
//*********** get available files ****************************************/
#ifdef OTA_on
String getFilesFromServer(IPAddress ip){
String files = "";
if (WiFiMulti.run() == WL_CONNECTED) {
WiFiClient client;
HTTPClient http;
String target = "http://"; target+=cPWR.getUpdateServer(); target+="/fwpwr/getFiles.php";
if (http.begin(client,target)){
http.addHeader("Content-Type","application/json;charset=utf-8");
int httpCode = http.POST("{\"userIP\":\""+ip.toString()+"\",\"build\":\""+Version+"\"}");
if(httpCode >= 100){
files = http.getString();
}
else files = "Error: no connection.";
}
http.end();
}
return files;
}
//********** update, input file-name ************************************/
String updateStromLog(String file){
saveHistoryStatus(UPDATE);
cPWR.saveHistory(getRawHistory());
String result = "ERROR: Update failed!";
ESPhttpUpdate.rebootOnUpdate(false); // remove automatic update
digitalWrite(LEDred,ON);
WiFiClient client;
t_httpUpdate_return ret = ESPhttpUpdate.update(client, cPWR.getUpdateServer(), 80, "/fwpwr/"+file);
switch (ret) {
case HTTP_UPDATE_FAILED:
break;
case HTTP_UPDATE_NO_UPDATES:
break;
case HTTP_UPDATE_OK:
String result = "Update successful.";
delay(500); // Wait a second and restart
ESP.restart();
break;
}
return result;
}
#endif
//*********** update end *************************************************/
//*********** send status as JSON for controling *************************/
String getStatus(){
String json = "{\"status\":{\"relais\":"; json+=digitalRead(RELAIS); json+=",\"power\":"; json+=_actualConsumption; json+="}}";
return json;
}
String getOnTime(){
String json = "{\"ontime\":{\"value\":"; json+=_onTime; json+=",\"unit\":\"sec\"},\"errors\":"; json+=_errorCount; json+="}";
return json;
}
String getData(){
String json = "{\"ac\":"; json+=_actualConsumption;
json+= ",\"re\":"; json+=digitalRead(RELAIS);
json+= ",\"ot\":"; json+=_onTime/60;
json+= ",\"wt\":"; json+=cPWR.getWaitAction()-_waitTimeCount;
json+= ",\"er\":"; json+=_errorCount;
json+= ",\"co\":"; json+=_receivedOK;
json+= "}";
return json;
}
//*********** get json data from meter *******************/
bool getConsumptionMeter(){
bool r=false;
if (WiFiMulti.run() == WL_CONNECTED) {
WiFiClient client;
HTTPClient http;
String target = "http://"; target += cPWR.getTargetMeter(); target+="/consumption";
int httpCode = 0;
if (http.begin(client,target)){
httpCode = http.GET();
if (httpCode == HTTP_CODE_OK){
_TransmitResult = http.getString();
r=true;
#ifdef DEBUG_PAYLOAD
Serial.println(httpCode);
Serial.println(_TransmitResult);
#endif
} else {_TransmitResult ="Missing answer! "; _TransmitResult +=httpCode;}
} else _TransmitResult ="Target not found!";
http.end();
}
return r;
}
/***********************************************************
* convert a unix-timestamp into single bytes as value
* function works up to 1972 until 19.01.2038
***********************************************************/
void Timestamp2DateTime(uint32_t unixTime){
int dummy = 0; int years=0;
uint32_t SecOfYear; uint32_t timeDummy;
bool leapYear = false; // default: don't be a leap-year
timeDummy = unixTime - 31536000 *2; // sub two years (1970 and 1971) add the years later
years= (timeDummy / 126230400) *4; // get the periodes of four years cycle; 3Y+leapY = 126230400 seconds
timeDummy = timeDummy % 126230400; // get the rest of timestamp without the cycles like above this line
if (timeDummy >= 31622400) {
timeDummy -= 31622400; // sub the first leap-year if it's over
years++; // add the leapyear
years += timeDummy / 31536000; // get the rest of years between 0 until 2 years
}
years = years + 1972; // add start-year +2: now, we know the actual year and can figure out if is a leap-year
_date_time[YEAR]=years;
// if (year % 4 == 0) leapYear = true; // if year divison by four without some rest, then is a leap-year...yeeeh -> it works until 2036 only
if ( bitRead(years,0)==0 && bitRead(years,1)==0) { // it's very faster than %-arithmetic
leapYear = true;
SecOfYear = 31622400; // set the counts of seconds leap-year
// Serial.print("LeapYear ");
} else SecOfYear = 31536000; // or don't be a leap-year -> regulary seconds
_date_time[DAY] = (timeDummy % SecOfYear) / 86400; // get the days of actual year
_date_time[MONTH] = 0; // set zero
for (int i=0; _date_time[DAY]>=0; i++ ) { // do it until the day(s) are negativ, this loop has be exicute one time -> to set month at ones
dummy = _date_time[DAY]; // store the value befor result is negativ for break, because the last one was the day of actual month
_date_time[DAY] = _date_time[DAY] - DaysPerMonth[i]; // sub the days of month until it's negativ, according byte-array
if (i == 1 && leapYear == true) {_date_time[DAY] -= 1;} // sub the 29. of february on leapyears ;-)
_date_time[MONTH]++; // add one month on every loop
if (i > 11) return; // if this function wild ;-) then break (max. months are 0 - 11)
}
_date_time[DAY] = dummy+1; // add one, because the start was on 1. january (start of timstamp = 01.01.1970 and we have to add it)
/****** get time ******/
_date_time[HOUR] = (timeDummy % 86400) / 3600; // the value of _timeDummy contents the rest of hours, minutes and seconds only
_date_time[MINUTE] = (timeDummy % 3600) / 60; // it's shorter to take reduced _timeDummy than the whole timestamp
_date_time[SECOND] = timeDummy % 60;
// return values are in array "unsigned int _date_time[6]; //[YEAR][MONTH][DAY][HOUR][MINUTE][SECOND]"
}
void writeTime(){
_year = _date_time[YEAR];
_month = _date_time[MONTH];
_day = _date_time[DAY];
_hour = _date_time[HOUR];
_minute = _date_time[MINUTE];
_second = _date_time[SECOND];
}
void getTime2Value(uint32_t unixTime){
Timestamp2DateTime(unixTime);
writeTime();
}
//****************************** show received a protocol on red LED ***************************
void showProtocolOnLED(){
}
//*********************** decode value from JSON *********************************
void decodeValue(){
_receivedOK=true;
int valueBegin = _TransmitResult.indexOf("value");
if(valueBegin >= 0){
int valueEnd = _TransmitResult.indexOf(",",valueBegin);
if (valueEnd != -1){
String value = _TransmitResult.substring(valueBegin+7, valueEnd);
#ifdef DEBUG_VALUE
Serial.println(value);
#endif
_actualConsumption=value.toInt();
}
} else _actualConsumption=0;
}
//********************* error handling ***********************************
void errorConnect(){
_errorCount++;
saveHistoryStatus(LOST);
if(_errorWait>=cPWR.getErrorWait()){
turnAllOff();
}
}
//******************** turn off relais and set variable on zero **********
void turnAllOff(){
_receivedOK=false;
_TransmitResult="";
_actualConsumption=0;
digitalWrite(RELAIS, OFF);
_waitTimeCount=0;
saveHistoryRelais();
}
//****************** time counter until switch on ************************
bool ifWaitTimeOver(){
_waitTimeCount += cPWR.getScanTime();
if(_waitTimeCount >= cPWR.getWaitAction()){
_waitTimeCount = cPWR.getWaitAction();
return true;
}
else return false;
}
//*********************** handle turn on or off relais *******************
void switchRelais(){
if(cPWR.getActionOn()){
if(_actualConsumption < cPWR.getValueON()){if(ifWaitTimeOver())digitalWrite(RELAIS, ON);saveHistoryRelais();}else _waitTimeCount=0;
if(_actualConsumption > cPWR.getValueOFF()){digitalWrite(RELAIS, OFF); _waitTimeCount=0;saveHistoryRelais();}
}else
turnAllOff();
}
//*********************** handle status for history **********************
//*** save history ***
void saveHistoryRelais(){
int x=digitalRead(RELAIS);
if(x != _valueMem){
_history[_historyPointer][0]=_timestamp;
_history[_historyPointer][1]=x;
_valueMem=x;
historyPointerPlus();
}
}
void saveHistoryStatus(int stat){
_history[_historyPointer][0]=_timestamp;
_history[_historyPointer][1]=stat;
historyPointerPlus();
}
void historyPointerPlus(){
if(_historyPointeraus"; break; // 0
case ON: h+="an"; break; // 1
case ESPstart: h+="Start"; break; // 2
case LOST: h+="lost";break; // 3
case WIFIerror: h+="WIFIlost";break; // 4
case RESTART: h+="Reset"; break; // 5
case UPDATE: h+="Update"; break; // 6
case NEWSSID: h+="Set WLAN"; // 7
case SHUTDOWN: h+="RESTART"; break; // 8 NEWTIME
case NEWTIME: h+="TimeSync"; break; // 9
default: h+="?";
}
h += " ";
h += "";
}
y++;
if(y>=bufferLength)y=0;
#ifdef DEBUG_VALUE
Serial.println(_historyPointer);
Serial.println(_history[i][0]);
#endif
}
return h;
}
//**** get raw history ***************************************************
String getRawHistory(){
String h = "Pointer:"; h+=_historyPointer; h+="&";
for(int i=0;i0){
int pointerEnd = s.indexOf("&",8);
String pointer=s.substring(8,pointerEnd);
oldPointer=pointer.toInt();
for(int i=0;i 0){ // Flash LED when errors occurs or for information
if (digitalRead(LEDred) == HIGH)digitalWrite(LEDred,OFF); else digitalWrite(LEDred,ON);
_flashCounter --;
} else digitalWrite(LEDred,OFF); // if flashtime over turn off LED
if (_hour == 23 && _minute==1 && _second==3){ // update _timestamp
if (syncron_NTP_Time() == true){
getTime2Value(_timestamp);
saveHistoryStatus(NEWTIME);
}
cPWR.saveHistory(getRawHistory());
_onTime=0;
_errorCount=0;
}
if (_timestamp < TimeOf2021 && _second == 50) {
if (syncron_NTP_Time() == true) getTime2Value(_timestamp); // get timestamp again if sync was failure, perhaps after power down
}
if(_second % cPWR.getScanTime() == 0){ // handle get data from meter and switch relais
if(cPWR.getActionOn()){ // is automatic on
if(getConsumptionMeter()){ // get value of consumption from meter
decodeValue(); // decode value of consumption
_TransmitResult="Connect with Target (Meter or Master)";
_errorWait=0; // set error wait of zero
switchRelais(); // handle turn on of relais
} else {
_errorWait++; // count error wait
errorConnect(); // if connection lost turn off relais after errorWait value
_TransmitResult="Target not found! Timeout!";
if(!WiFi.isConnected()){
_flashCounter=20;
saveHistoryStatus(WIFIerror);
if(_errorWait > 20){
saveHistoryStatus(RESTART);
cPWR.saveHistory(getRawHistory());
delay(500);
ESP.restart(); // connect lost do restart
}
}
}
#ifdef DEBUG_CONNECT
Serial.print("Status: "); Serial.println(WiFi.status());
Serial.print("RRSI: "); Serial.println(WiFi.RSSI());
Serial.print("ErroWait: "); Serial.println(_errorWait);
#endif
}// else turnAllOff();
}
if(digitalRead(RELAIS)==1)_onTime++;
}
check4Client(); // thats it's if with the browser show data on port 80 by html
}