/** * WEB client interface StromLog * Version 7.04 * 28.06.2024 P. Rebesky * author Creator P.Rebesky * Copyright (©): 2022-2032 by Peter Rebesky * This code can use in private cases only. Every business or companies using of this codes or codes parts is required an approval of us (me) * Every private using can exchange some parts of code or modify some code-lines. This code is allowed change for private use only. * This software is basicly owned by Peter Rebesky and any comercial using is forbidden without approval of us (me). **/ #ifndef WEB_CLIENT_H_ #define WEB_CLIENT_H_ #define ShowIniFile #include "global.h" #include "configDTZ.h" #ifdef SML_DIN #include "decodeMeterSML.h" #endif #ifdef ISKRA_MT174 #include "decodeMeterMT174.h" #endif #ifdef VDE_DIN #include "decodeMeterDIN.h" #endif #ifdef ZE311_DR #include "decodeMeterZE311.h" #endif #ifdef LG_E350 #include "decodeMeterE350.h" #endif #ifdef MBUS_DLMS #include "decodeMeterDLMS.h" #endif #ifdef PAF_EC3 #include "dMeterPAFec3.h" #endif #ifdef LG_E320 #include "decodeMeterE320.h" #endif #ifdef DIN_EBZ #include "decodeDIN_EBZ.h" #endif extern configDTZ cDTZ; extern decodeMeter dMETER; extern String sendConsumptionValue(); extern String getValuesAsJSON(); extern String prepareSendValuesAsJSON(); extern String getFilesFromServer(IPAddress ip,String actVersion, String updateServer); extern String getTime2String(int hour,int minute,int second); extern String getDate2String(int year,int month,int day); extern bool syncron_NTP_Time(bool correctOn); extern void getTime2Value(); //*** set build type **************************// String Version = "7.04"; String LoggerVersion = "Build "+dMETER.getProtocolType()+Version+" 28.06.2024"; //*** end ***********************************// //*** declarations *** String prepareRefreshJSON(); String getValuesAsJSON(); String sendConsumptionValue(); String prepareSendValuesAsJSON(); String showSetup(); //*** declaration end ***// String webConsumption(){ String ret = HTTP_ANSWERJSON; ret += sendConsumptionValue(); return ret; } //*** end *** String webCurrentData(){ String ret = HTTP_ANSWERJSON; ret += getValuesAsJSON(); return ret; } //*** end *** String webAllData(){ String ret = HTTP_ANSWERJSON; ret += prepareSendValuesAsJSON(); return ret; } //*** end *** String webSave(String PostValues){ cDTZ.savePostValues(PostValues); String ret = HTTP_ANSWER; ret += HTTP_HEAD_DTZ; ret += ""; ret += cDTZ.getNameDTZ(); ret += ""; ret += FPSTR(HTTP_BODYSTYLE_DTZ); ret += ""; ret += HTTP_DIV_FIELD; ret += "

Ihre Eingaben wurden gespeichert.

"; ret += "

"; ret += HTTP_TEXT_END; return ret; } //*** end *** String webSetup(){ String ret = HTTP_ANSWER; ret += HTTP_HEAD_DTZ; ret += ""; ret += cDTZ.getNameDTZ(); ret += ""; ret += FPSTR(HTTP_BODYSTYLE_DTZ); ret += ""; ret += HTTP_DIV_FIELD; ret += "

Grundeinstellungen

"; ret += "
"; ret += "


"; #ifdef MBUS_DLMS ret += "


"; #endif ret += "


"; ret += "


"; ret += "


"; ret += "


"; #ifdef VDE_DIN ret += "


"; ret += "


"; #endif ret += "


"; ret += "
MQTT Service einschalten:"; if (cDTZ.SendMQTT==1) ret += "checked=\"checked\">"; else{ ret += ">"; BrokerHidden=""; ret += "
Show Protokoll an LED:"; else ret += ">"; ret += "

"; ret += "

"; ret += "
StromLog-Version: "; ret += LoggerVersion; ret += "
Check for update firmware"; ret += "

Hilfe & Impressum

"; ret += "

StromLog-Optionen

"; ret += FPSTR(HTTP_JS_SETUP); return ret; } //*** end *** String webShowSetup(){ String ret = HTTP_ANSWER; ret += FPSTR(HTTP_BODYSTYLE_DTZ); ret += ""; ret += HTTP_DIV_FIELD; ret += showSetup(); //debug ret += HTTP_TEXT_END; return ret; } //*** end *** String webFavicon(){ String ret = HTTP_ANSWER; ret += "none"; return ret; } //*** end *** String webSearchStromLog(String payload) { String ret = HTTP_ANSWER; int argBegin = payload.indexOf("?"); if (argBegin != -1){ int valueEnd = payload.indexOf("HTTP"); int idEx = payload.substring(argBegin+1,valueEnd-1).toInt(); if(idEx == cDTZ.getUserID() || cDTZ.getUserID() == 0){ ret += "{\"DTZLOGGER\":\"" + LoggerVersion + "\"}"; } } return ret; } //*** end *** String webMain(String payload){ // Prepare the response main screen float DispValue; String ret = HTTP_ANSWER; ret += HTTP_HEAD_DTZ_REFRESH; ret += ""; ret += cDTZ.getNameDTZ(); ret += ""; ret += FPSTR(HTTP_BODYSTYLE_DTZ); ret += ""; ret += HTTP_DIV_FIELD; ret += "

"; ret+=cDTZ.getNameDTZ(); ret+="

"; ret += getDate2String(_act_date_time[_YEAR],_act_date_time[_MONTH],_act_date_time[_DAY]); ret += " - "; ret += getTime2String(_act_date_time[_HOUR],_act_date_time[_MINUTE],_act_date_time[_SECOND]); ret+=""; ret += "🔄
"; if(_protocolError)ret+= FPSTR(PROTOCOL_ERROR); ret += "
"; ret += "1.8.0 Bezug Summe:

"; if(dMETER.MeterKWH[_FROMGRID_1]>0){ ret += "1.8.1 Bezug Tarif 1:

"; } if(dMETER.MeterKWH[_FROMGRID_2]>0){ ret += "1.8.2 Bezug Tarif 2:

"; } if(dMETER.MeterKWH[_FEEDIN]>0){ ret += "2.8.0 Einspeisung:

"; } ret += "
"; if(dMETER.Electric_data[_CONSUMPTION]!=0){ ret += "Summen-Leistung:

"; ret += "

"; } if(dMETER.Electric_data[_P_L1]!=0 || dMETER.Electric_data[_P_L2]!=0 || dMETER.Electric_data[_P_L3]!=0){ ret += "Leistung L1:

"; ret += "Leistung L2:

"; ret += "Leistung L3:

"; } if(dMETER.Electric_data[_I_L1]>0 || dMETER.Electric_data[_I_L2]>0 || dMETER.Electric_data[_I_L3]>0){ ret += "Strom L1:

"; ret += "Strom L2:

"; ret += "Strom L3:

"; } if(dMETER.Electric_data[_U_L1]>0 || dMETER.Electric_data[_U_L2]>0 || dMETER.Electric_data[_U_L3]>0){ ret += "Spannung L1:

"; ret += "Spannung L2:

"; ret += "Spannung L3:

"; } if(dMETER.Electric_data[_FREQ]>0){ ret += "Netzfrequenz:

"; } ret += "
"; ret += payload; ret += "

StromLog & Zähler

"; ret += "

Stromlog-IP:

"; ret += "Signalstärke: "; ret+=WiFi.RSSI(); ret+=" dBm

"; ret += "(Zähler) Hersteller-ID:

"; ret += "(Zähler) Server-ID:

"; ret += "Received protocols:

"; #if(defined SML_DIN || defined MBUS_DLMS) ret += "Protocol errors:

"; #endif #ifdef VDE_DIN if(dMETER.MeterTime.length()>5){ ret += "(Zähler) Datum Zeit:

"; } #endif if(_sendingOK == false)ret += "🔴"; // show a red bubble when StromLog not connect on server at the first time ret += "Saved protocols:"; ret += "

"; ret += "

"; if(cDTZ.SendMQTT==1){ ret += "

MQTT Client ist eingeschaltet.

"; } else { ret += "

MQTT Client ist ausgeschaltet.

"; } if(_mqttBrokerOK==0 && cDTZ.SendMQTT==1){ ret += "

🔴Error: MQTT Broker ist nicht erreichbar!
Oder Nutzer und Passwort sind nicht erlaubt.
Neuer Verbindungsversuch in "; ret+=_mqttWaitTime2Connect; ret+=" Sekunden.

"; } ret += HTTP_SETUP_BUTTON; ret += "

Hilfe & Impressum

"; // ret += HTTP_TEXT_END; ret += FPSTR(HTTP_JS_SCRIPT); return ret; } //*** end *** String webMemory(){ String ret = HTTP_ANSWER; ret += "Free space: "; ret += cDTZ.FREESPACE; ret += "
"; ret += cDTZ.readDir(); #ifdef ShowIniFile File Fconfig = LittleFS.open("/config.ini","r"); if (Fconfig){ ret+=Fconfig.readString(); Fconfig.close(); } else ret +="File empty"; #endif ret+="
"; if(cDTZ.saveCounter > 0){ for(int i=1;i<=cDTZ.saveCounter;i++){ ret += cDTZ.readSavedValues(i); ret += "
"; } } else ret += "No saved data.
"; ret += HTTP_TEXT_END; return ret; } //*** end *** String webSendProtocols(){ dMETER.SendProtocols = 10; String ret = HTTP_ANSWER; ret += "10 RAW Protocols will be send to server now.
"; ret += HTTP_TEXT_END; return ret; } //*** end *** String webSetTime(){ String ret = HTTP_ANSWER; ret += FPSTR(HTTP_BODYSTYLE_DTZ); ret += ""; ret += HTTP_DIV_FIELD; ret += "

Die Uhr wird jetzt neu synchronisiert.

"; ret += "

Zeit:

"; ret += "Unix-Time: "; ret += _timestamp; ret +="
"; if (syncron_NTP_Time(true) == true){ getTime2Value(); ret += "Neue Zeit:

"; ret += "Unix-Time: "; ret += _timestamp; ret +="
"; } else { ret += "NTP Serverfehler! Aktuallisierung nicht erfolgt.
Bitte eine Wartezeit von 2 Minuten,
bis zur wiederholten, manuellen Aktuallisierung einhalten.
"; } ret += "


"; ret += HTTP_TEXT_END; return ret; } //**** update firmware part info to user interface *********// String getUpdateFiles(IPAddress userIP){ String ret=HTTP_ANSWER; ret += "Your StromLog versions number: "+dMETER.getProtocolType()+Version+"
"; ret += "Check for new firmware now.
"; ret += getFilesFromServer(userIP,dMETER.getProtocolType()+Version,cDTZ.getTargetServer()); ret += HTTP_TEXT_END; return ret; } String prepareUpdate(String line){ String ret = HTTP_ANSWER; int valueBegin = line.indexOf("?"); if(valueBegin > 0){ int valueEnd = line.indexOf("HTTP"); String argumentValue = line.substring(valueBegin+1,valueEnd-1); ret += "Update will be start now.
"; ret += "Update-file: "+argumentValue+"
"; ret += "Don't turn off power during update!

"; ret += "After update, the reconnection only via IP, without arguments behind it!

"; ret += "Click here for reconnect after update
"; } else { ret += "Error: Missing name of update file!
"; ret += "Update canceled.
"; line =""; } ret += HTTP_TEXT_END; return ret; } String getRefreshJSON(){ String ret = HTTP_ANSWERJSON; ret += prepareRefreshJSON(); return ret; } //***** get return json for refresh display on browser or *****// String prepareRefreshJSON(){ String json = "{\"time\":\""; json+=getTime2String(_act_date_time[_HOUR],_act_date_time[_MINUTE],_act_date_time[_SECOND]); json+="\","; json += "\"vL1\":"; json+=dMETER.Electric_data[_U_L1]; json+=","; json += "\"vL2\":"; json+=dMETER.Electric_data[_U_L2]; json+=","; json += "\"vL3\":"; json+=dMETER.Electric_data[_U_L3]; json+=","; json += "\"cL1\":"; json+=dMETER.Electric_data[_I_L1]; json+=","; json += "\"cL2\":"; json+=dMETER.Electric_data[_I_L2]; json+=","; json += "\"cL3\":"; json+=dMETER.Electric_data[_I_L3]; json+=","; json += "\"pL1\":"; json+=dMETER.Electric_data[_P_L1]; json+=","; json += "\"pL2\":"; json+=dMETER.Electric_data[_P_L2]; json+=","; json += "\"pL3\":"; json+=dMETER.Electric_data[_P_L3]; json+=","; json += "\"frq\":"; json+=dMETER.Electric_data[_FREQ]; json+=","; json += "\"prot\":"; json+=dMETER.ProtocolCounter; json+=","; json += "\"db\":"; json+=WiFi.RSSI(); json+=","; json += "\"cmq\":"; json+=_mqttWaitTime2Connect; json+=","; json += "\"psum\":"; json+=dMETER.Electric_data[_CONSUMPTION]; json+="}"; return json; } //*********** build an JSON code of values and return it *****************/ String getValuesAsJSON(){ String json = "{\"timestamp\":"; json += _timestamp; json += ",\"meterData\":"; json += "{\"consumption\":{\"value\":"; json += dMETER.Electric_data[_CONSUMPTION]; json += ",\"unit\":\"W\"},"; json += "\"FromGridSum\":{\"value\":"; json+= dMETER.MeterKWH[_FROMGRID_0]; json += ",\"unit\":\"dWh\"},"; json += "\"FromGridA\":{\"value\":"; json+= dMETER.MeterKWH[_FROMGRID_1]; json += ",\"unit\":\"dWh\"},"; json += "\"FromGridB\":{\"value\":"; json+= dMETER.MeterKWH[_FROMGRID_2]; json += ",\"unit\":\"dWh\"},"; json += "\"FeedIn\":{\"value\":"; json+= dMETER.MeterKWH[_FEEDIN]; json += ",\"unit\":\"dWh\"}"; json += "},\"electricsData\":{"; json += "\"voltageL1\":{\"value\":"; json+= dMETER.Electric_data[_U_L1]; json += ",\"unit\":\"dV\"},"; json += "\"voltageL2\":{\"value\":"; json+= dMETER.Electric_data[_U_L2]; json += ",\"unit\":\"dV\"},"; json += "\"voltageL3\":{\"value\":"; json+= dMETER.Electric_data[_U_L3]; json += ",\"unit\":\"dV\"},"; json += "\"currentL1\":{\"value\":"; json+= dMETER.Electric_data[_I_L1]; json += ",\"unit\":\"cI\"},"; json += "\"currentL2\":{\"value\":"; json+= dMETER.Electric_data[_I_L2]; json += ",\"unit\":\"cI\"},"; json += "\"currentL3\":{\"value\":"; json+= dMETER.Electric_data[_I_L3]; json += ",\"unit\":\"cI\"},"; json += "\"powerL1\":{\"value\":"; json+= dMETER.Electric_data[_P_L1]; json += ",\"unit\":\"W\"},"; json += "\"powerL2\":{\"value\":"; json+= dMETER.Electric_data[_P_L2]; json += ",\"unit\":\"W\"},"; json += "\"powerL3\":{\"value\":"; json+= dMETER.Electric_data[_P_L3]; json += ",\"unit\":\"W\"},"; json += "\"freq\":{\"value\":"; json+= dMETER.Electric_data[_FREQ]; json += ",\"unit\":\"dHz\"}}"; json += ",\"protocols\":{\"total\":"; json += dMETER.ProtocolCounter; json +=",\"failed\":"; json += dMETER.ErrorCounter; json += "}}"; return json; } //*********** send consumption only **************************************/ String sendConsumptionValue(){ String json = "{\"consumption\":{\"value\":"; json += dMETER.Electric_data[_CONSUMPTION]; json += ",\"unit\":\"W\"}}"; return json; } //*********** prepare values for sending as JSON *************************/ String prepareSendValuesAsJSON(){ String Data = "{\"userid\":"; Data += cDTZ.getUserID(); Data += ",\"meter\":{"; Data += "\"localip\":\""+ WiFi.localIP().toString()+"\","; Data += "\"metername\":\""+cDTZ.getNameDTZ()+"\","; Data += "\"manufacturer\":\""+dMETER.MeterType+"\","; Data += "\"meterid\":\""; Data += dMETER.getMeterID(); Data += "\"},\"currentData\":"; Data += getValuesAsJSON(); Data += "}"; return Data; } String ioBrokerData(){ String Data = HTTP_ANSWERJSON; Data +="{\"billingData:\":{\"assignment\":["; Data += "{\"obis\":\"0100000000FF\",\"value\":\""; Data+=dMETER.getMeter_ID(); Data += "\"},"; Data += "{\"obis\":\"010000090B00\",\"value\":\""; Data+=getDate2String(_act_date_time[_YEAR],_act_date_time[_MONTH],_act_date_time[_DAY]);Data+=","; Data += getTime2String(_act_date_time[_HOUR],_act_date_time[_MINUTE],_act_date_time[_SECOND]); Data += "\"}],\"values\":["; Data += "{\"obis\":\"0101010800FF\",\"value\":"; Data+=dMETER.MeterKWH[_FROMGRID_0]; Data += ",\"unit\":\"dWh\"},"; Data += "{\"obis\":\"0101010801FF\",\"value\":"; Data+=dMETER.MeterKWH[_FROMGRID_1]; Data += ",\"unit\":\"dWh\"},"; Data += "{\"obis\":\"0101010802FF\",\"value\":"; Data+=dMETER.MeterKWH[_FROMGRID_2]; Data += ",\"unit\":\"dWh\"},"; Data += "{\"obis\":\"0101020800FF\",\"value\":"; Data+=dMETER.MeterKWH[_FEEDIN]; Data += ",\"unit\":\"dWh\"},"; Data += "{\"obis\":\"0100010700FF\",\"value\":"; Data+=dMETER.Electric_data[_CONSUMPTION]; Data += ",\"unit\":\"W\"},"; Data += "{\"obis\":\"010020070000\",\"value\":"; Data+=dMETER.Electric_data[_U_L1]; Data += ",\"unit\":\"dV\"},"; Data += "{\"obis\":\"010034070000\",\"value\":"; Data+=dMETER.Electric_data[_U_L2]; Data += ",\"unit\":\"dV\"},"; Data += "{\"obis\":\"010048070000\",\"value\":"; Data+=dMETER.Electric_data[_U_L3]; Data += ",\"unit\":\"dV\"},"; Data += "{\"obis\":\"01001F070000\",\"value\":"; Data+=dMETER.Electric_data[_I_L1]; Data += ",\"unit\":\"cA\"},"; Data += "{\"obis\":\"010033070000\",\"value\":"; Data+=dMETER.Electric_data[_I_L2]; Data += ",\"unit\":\"cA\"},"; Data += "{\"obis\":\"010047070000\",\"value\":"; Data+=dMETER.Electric_data[_I_L3]; Data += ",\"unit\":\"cA\"},"; Data += "{\"obis\":\"01000E070000\",\"value\":"; Data+=dMETER.Electric_data[_FREQ]; Data += ",\"unit\":\"dHz\"}"; Data += "]}}"; return Data; } //*********** hande set crc check on off *********************************/ String setCheckCRC(bool setVar){ cDTZ.setCRC_Check(setVar); return webShowSetup(); } //*********** set push intervall *****************************************/ String setIntervall(int pushValue){ String ret="Actual-Push-Time-Intervall: "; ret+=cDTZ.PushIntervall; ret+=" minutes\n"; if(pushValue >0 && pushValue < 31 || pushValue==60){ ret+="New-Push-Time-Intervall: "; ret+=pushValue; ret+=" minutes\n"; cDTZ.PushIntervall=pushValue; //set new intervall cDTZ.saveConfigDTZ(); //and saved into config file } else { ret+="The value entered was incorrect. Range is 1-30 or just 60\nNothing is saved.\n"; } return ret; } //*********** show intern setup data for support *************************/ String getSerialSpeed(int serialSpeed){ String ret=""; switch(serialSpeed){ case 0: ret = "SerialType: -9600b 8N1-"; break; case 1: ret = "SerialType: -9600b 7E1-"; break; case 2: ret = "SerialType: -1200b 7E1-"; break; case 3: ret = "SerialType: -2400b 7E1-"; break; case 4: ret = "SerialType: -4800b 7E1-"; break; case 5: ret = "SerialType: -9600b 7E1-"; break; case 6: ret = "SerialType: -19400b 7E1-"; break; case 10: ret = "SerialType: -2400b 8N1-"; break; default: ret = "Not detect"; break; } return ret; } //*********** show rest-end-points **************************************/ const char HELP_REST_POINTS[] PROGMEM = "Available Rest-Endpoints after StromLogIP:
/vJSON - get Data as JSON for diagram
/diagram - Show diagram
/consumption - get act. power as JSON
/json.txt - get Data as JSON for ioBroker
/currentData - get electric Data as JSON
/allData - get all Data as JSON
/refresh - get Data for refresh display
/setup - start setup-window
/showsetup - show intern setups
/searchLogger - return exist of StromLog
/memory - show files of intern memory
/sendProtocols - send raw protocols of meter to server
/setTime - set new of act. time
/firmware - get files from server for updates
/CRC_ON - switch on of SML check-sum
/CRC_OFF - switch off of SML check-sum
/help - this info
/setIntervall?15 - set time of send data to server
/upDate?file.bin - update of file
"; String webShowHelp(){ String ret = HTTP_ANSWER; ret += FPSTR(HELP_REST_POINTS); ret += "

"; ret += HTTP_TEXT_END; return ret; } //*********** show intern setup and variables ****************************/ String showSetup(){ String ret = "

StromLog Status


"; ret += "Processor: ESP-Wroom2 (ESP8266 2Mb)
"; ret += "

User: -"; ret += cDTZ.getUser(); ret +="-
"; ret += "PW (Key): -"; ret += cDTZ.getPasswEncrypt(); ret +="-
"; ret += "UserID: -"; ret += cDTZ.getUserID(); ret +="-
"; ret += "URL: -"; ret += cDTZ.getTargetURL(); ret +="-
"; ret += "Send-Intervall: -"; ret += cDTZ.PushIntervall; ret +="- minutes
"; ret += "Encryption: -"; ret+=_crypt; ret+="-
"; // ret += "URLclean: -"; ret += cDTZ.getTargetURLclean(); ret +="-
"; ret += "Update-Server: -"; ret += cDTZ.getTargetServer(); ret+="-
"; ret += "HTTPCode: -"; ret +=_httpMarker; ret +="-
"; ret += "Timestamp: -"; ret +=_timestamp; ret +="-
"; ret += "TimestampServer: -"; ret +=_timestampFromServer; ret +="-
"; ret += "AdjustSec: -"; ret +=_secAdjust; ret +="-
"; ret += "File-system free-space: -"; ret +=cDTZ.getFreeSpace(); ret +="- kB
"; #ifdef SML_DIN ret += getSerialSpeed(_serialType); ret += "
CRC-Check: -"; if(_CRC_CHECK==0){ret+="On";}else{ret+="Off";} ret+="-
"; #else ret += getSerialSpeed(dMETER.SerialSpeed); #endif #ifdef MBUS_DLMS ret += "
Encryption: DLMS/COSEM (AES128)"; #endif ret +="

"; return ret; } //*** end *** #endif //*** WEB_CLIENT_H_