/* * configPWR.h * File-class for Power PWM (PID) Regler for StromLog * for configuration of data * Version 0.06 * 31.03.2024 * author Creator P.Rebesky * Copyright (©): 2024-2028 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 use can exchange some parts of code or modify some code-lines. This code can change for private use only. * This software is basicly owned by Peter Rebesky and any comercial using is forbidden without approval of us (me). * * */ // class for manage config-data into and from file "confpwm.ini" #ifndef CONFIG_PWR_H_ #define CONFIG_PWR_H_ #include // LittleFS is declared #include "global.h" #define ReglerName "rname" #define ActionPump "pwON" #define ActionOff "voff" #define MaxConsumption "maxW" #define RegelValue "vrgl" #define RegelKp "vpkp" #define PumpOff "poff" #define MaxTemperatur "maxTemp" #define TempHisterese "tHist" #define WaitOn "wait" #define WaitOff "woff" #define BorderTemp "btemp" #define ScanMeter "scan" #define MeterIP "turl" #define Automatic "auto" #define Master_Slave "masla" #define UpdateUrl "upser" #define ErrorWait "error" #define mqttUser "XZuser" #define mqttPass "XZpass" #define mqttInterval "XZintv" #define mqttTarget "XZmqtt" #define MaxOnWatt "XZonw" #define ExchangeTemp "tChange" #define Send2Server "XZs2s" /***** class for save data intern into ESP8266 *****/ class configPWR { private: String TARGET_METER; String UPDATE_SERVER; String NAME_PWR; String BROKER_TARGET = "192.168.10.47"; String BROKER_USER = "User"; String BROKER_PW = "user"; int VALUE_UWPUMP_ON = -200; int VALUE_MINUTE_PUMP_OFF = 60; int VALUE_REGLER = -50; int VALUE_KP = 100; int VALUE_ACTION_OFF = 100; int WAIT_TIME_ACTION = 20; int WAIT_TIME_OFF = 15; int MAX_TEMPERATUR = 80; int TEMP_HISTERESE = 0; int ERROR_WAIT = 2; int SCAN_METER = 5; int AUTOMATIC_ON = 0; // negative or zero value turned automatic off, positive value turned on int MAXIMAL_CONSUMPTION = 2200; bool SEND2SERVER = false; bool MOUNTED = false; void loadConfig(String s); int calculateFreeSpaceFS(); String decodeOnValue(String s); unsigned char h2int(char c); public: int FREESPACE=0; uint32_t FactorKWH=0; bool AUTOMATIC = true; int SendSSL=0; int SendMQTT=0; int MQTT_INTERVAL = 60; bool begin(); // start to get data from file void end(); int getValuePumpOn(); int getMaxConsumption(); int getValueOFF(); int getValueREG(); int getValueKP(); bool setFactorKWH(); int getTurnBack(); int getPumpOFF(); int getWaitAction(); int getScanTime(); bool getSend2Server(); void setSend2Server(bool value); int maxTemperatur(); int minTemperatur(); int tempHisterese(); String getPName(); int getErrorWait(); int getOffWait(); String getTargetMeter(); String getTargetServer(); String getTargetURLclean(); bool readConfig(); bool saveConfig(); int getFreeSpace(); String readDir(); bool savePostValues(String saveValues); bool savePostValuesAdvance(String saveValues); String urldecode(String str); String urlencode(String str); String getOnePostValue(String post,String value); String getOneFileValue(String file,String ident); bool getAutomatic(); void setAutomatic(bool value); void saveHistory(String history); String readSavedHistory(); void delSavedHistory(); String getIoBroker(); String getBrokerUser(); String getBrokerPW(); }; /**** mount the file-object ****/ bool configPWR::begin(){ if(LittleFS.begin()){ this->MOUNTED = true; this->readConfig(); this->calculateFreeSpaceFS(); } return this->MOUNTED; } /**** read values from file ****/ bool configPWR::readConfig(){ String s; bool r=false; File Fconfig = LittleFS.open("/confpwm.ini","r"); // Fconfig = LittleFS.open("/confpwm.ini","r"); if (Fconfig){ s=Fconfig.readString(); this->loadConfig(s); Fconfig.close(); r = true; } return r; } /****** for compatibility ******/ void configPWR::end(){ // do nothing, it's for compatibility only } /******** send data 2 server ****************/ bool configPWR::getSend2Server(){ return this->SEND2SERVER; } void configPWR::setSend2Server(bool value){ this->SEND2SERVER=value; } /******** handle value for switch on ********/ int configPWR::getValuePumpOn(){ return this->VALUE_UWPUMP_ON; } //******* get the maximal switch on consumption *******/ int configPWR::getMaxConsumption(){ return this->MAXIMAL_CONSUMPTION; } //******** handle value for switch off and turn back ******/ int configPWR::getValueOFF(){ return this->VALUE_ACTION_OFF; } //******** handle value for regel PWM value ******/ int configPWR::getValueREG(){ return this->VALUE_REGLER; } //******** handle value for regel Kp value ******/ int configPWR::getValueKP(){ return this->VALUE_KP; } //******** set factor for calculation of **********/ bool configPWR::setFactorKWH(){ bool success=false; if(SCAN_METER!=0){ // check of division by zerogetTargetMeter() success=true; this->FactorKWH=3600000/SCAN_METER; // 3600000 = convert Wh into kWh and add additionally division by 60 for hour, and minute division by SCAN_METER } else { this->FactorKWH=720000; // set default because that this value is not zero! Default is set by scan-time of 5 seconds } return success; } //******** set or get some values of controling for switching relais *****/ int configPWR::getOffWait(){ return this->WAIT_TIME_OFF; } /******** handle value for wait time ******/ int configPWR::getWaitAction(){ return this->WAIT_TIME_ACTION; } int configPWR::getPumpOFF(){ return this->VALUE_MINUTE_PUMP_OFF*60; // minute multiple by 60 second } /******** maximum of temperatur of saving *******/ int configPWR::maxTemperatur(){ return this->MAX_TEMPERATUR; } /******** minimum of temperatur of activate again *******/ int configPWR::minTemperatur(){ return this->MAX_TEMPERATUR + this->TEMP_HISTERESE; } int configPWR::tempHisterese(){ return this->TEMP_HISTERESE; } /******** handle value for scan meter time ******/ int configPWR::getScanTime(){ return this->SCAN_METER; } /******** handle value for error wait ******/ int configPWR::getErrorWait(){ return this->ERROR_WAIT; } /******** handle PWR-name *******/ String configPWR::getPName(){ return this->NAME_PWR; } /******** mqtt get and set ****************/ String configPWR::getIoBroker(){ return this->BROKER_TARGET; } String configPWR::getBrokerUser(){ return this->BROKER_USER; } String configPWR::getBrokerPW(){ return this->BROKER_PW; } /******** get automatic on / off **************/ bool configPWR::getAutomatic(){ if(this->AUTOMATIC_ON>0)return true; else return false; } /******** set automatic on / off **************/ void configPWR::setAutomatic(bool value){ this->AUTOMATIC_ON=value; } /******** handle target meter ******/ String configPWR::getTargetMeter(){ return this->TARGET_METER; } /****** handle update server ******/ String configPWR::getTargetServer(){ return this->UPDATE_SERVER; } /**** handle push-server ***********/ String configPWR::getTargetURLclean(){ String ret=this->UPDATE_SERVER; ret+="/temperature.php"; return ret; } /**** save history *****************/ void configPWR::saveHistory(String history){ if(this->MOUNTED && this->calculateFreeSpaceFS() > 4096){ String fileName = "/history.his"; File Fvalues = LittleFS.open(fileName,"w"); if (Fvalues){ int w=Fvalues.print(history); Fvalues.close(); } } } /**** read saved history ***********/ String configPWR::readSavedHistory(){ String s; if(this->MOUNTED){ String fileName = "/history.his"; File Fvalues = LittleFS.open(fileName,"r"); if (Fvalues){ s=Fvalues.readString(); Fvalues.close(); } else s="No saved history"; } else s="File read error. No mounted"; return s; } /**** delete saved history *********/ void configPWR::delSavedHistory(){ String fileName="/history.his"; if(this->MOUNTED){ LittleFS.remove(fileName); } } /**** save actuelle config-data ****/ bool configPWR::saveConfig(){ bool r = false; String s = "Config: actpump_on:"; s += this->VALUE_UWPUMP_ON; s += ",\n"; s += "max_on_watt:"; s += this->MAXIMAL_CONSUMPTION; s += ",\n"; s += "action_off:";s += this->VALUE_ACTION_OFF; s += ",\n"; s += "reglung:";s += this->VALUE_REGLER; s += ",\n"; s += "reglkp:";s += this->VALUE_KP; s += ",\n"; s += "pump_off:";s += this->VALUE_MINUTE_PUMP_OFF; s += ",\n"; s += "max_temp:";s += this->MAX_TEMPERATUR; s += ",\n"; s += "temp_hist:";s += this->TEMP_HISTERESE; s += ",\n"; s += "waittime:"; s += this->WAIT_TIME_ACTION; s += ",\n"; s += "scantime:"; s += this->SCAN_METER; s += ",\n"; s += "errorwait:"; s += this->ERROR_WAIT; s += ",\n"; s += "offwait:"; s += this->WAIT_TIME_OFF; s += ",\n"; s += "automatic:"; s += this->AUTOMATIC_ON; s += ",\n"; s += "url:\""; s += this->TARGET_METER; s += "\",\n"; s += "namepwr:\""; s += this->NAME_PWR; s += "\",\n"; s += "upserv:\""; s += this->UPDATE_SERVER; s += "\",\n"; s += "mqttSVR:\""; s += this->BROKER_TARGET; s += "\",\n"; s += "mqttUser:\""; s += this->BROKER_USER; s += "\",\n"; s += "mqttPass:\""; s += this->BROKER_PW; s += "\",\n"; s += "mqttIntv:\""; s += this->MQTT_INTERVAL; s += "\",\n"; s += "mqttONoff:\""; s += this->SendMQTT; s += "\",\n"; s += "send2server:\""; s += this->SEND2SERVER; s += "\",\n"; s += "exchangeT:\""; s += _exchangeTemp; s += "\",\n"; // comma is neccessary! // Serial.println(s); this->setFactorKWH(); // set new, if value was changed if(this->MOUNTED){ File Fconfig = LittleFS.open("/confpwm.ini","w"); if (Fconfig){ int w=Fconfig.print(s); Fconfig.close(); if (w > 1) r = true; // write file was successful } } return r; } //******************* load one value from saved config ***************** String configPWR::getOneFileValue(String file,String ident){ String ret; int argBegin = file.indexOf(ident); if(argBegin>0){ int argEnd = file.indexOf(",",argBegin+2); ret = this->decodeOnValue(file.substring(argBegin, argEnd)); } return ret; } /**** decode file-data and save into class ****/ void configPWR::loadConfig(String s){ this->VALUE_UWPUMP_ON=getOneFileValue(s,"actpump_on").toInt(); this->MAXIMAL_CONSUMPTION=getOneFileValue(s,"max_on_watt").toInt(); this->VALUE_MINUTE_PUMP_OFF=getOneFileValue(s,"pump_off").toInt(); this->VALUE_ACTION_OFF=getOneFileValue(s,"action_off").toInt(); this->VALUE_REGLER=getOneFileValue(s,"reglung").toInt(); this->VALUE_KP=getOneFileValue(s,"reglkp").toInt(); this->MAX_TEMPERATUR=getOneFileValue(s,"max_temp").toInt(); this->TEMP_HISTERESE=getOneFileValue(s,"temp_hist").toInt(); this->WAIT_TIME_ACTION=getOneFileValue(s,"waittime").toInt(); this->SCAN_METER=getOneFileValue(s,"scantime").toInt(); this->ERROR_WAIT=getOneFileValue(s,"errorwait").toInt(); this->WAIT_TIME_OFF=getOneFileValue(s,"offwait").toInt(); this->AUTOMATIC_ON=getOneFileValue(s,"automatic").toInt(); this->TARGET_METER=getOneFileValue(s,"url"); this->UPDATE_SERVER=getOneFileValue(s,"upserv"); this->NAME_PWR=getOneFileValue(s,"namepwr"); this->BROKER_TARGET=getOneFileValue(s,"mqttSVR"); this->BROKER_USER=getOneFileValue(s,"mqttUser"); this->BROKER_PW=getOneFileValue(s,"mqttPass"); this->MQTT_INTERVAL=getOneFileValue(s,"mqttIntv").toInt(); this->SendMQTT=getOneFileValue(s,"mqttONoff").toInt(); this->SEND2SERVER=getOneFileValue(s,"send2server").toInt(); _exchangeTemp=getOneFileValue(s,"exchangeT").toInt(); this->setFactorKWH(); // calculate Factor for calculation of kWh } /**** extract one value from string ****/ String configPWR::decodeOnValue(String s){ int valueBegin = s.indexOf("\""); int valueLength = s.length(); if(valueLength >0){ if(valueBegin > 0){ s = s.substring(valueBegin+1,valueLength-1); } else { valueBegin = s.indexOf(":"); s = s.substring(valueBegin+1,valueLength); } } else s = ""; return s; } /****** get free space from file-system ******/ int configPWR::calculateFreeSpaceFS(){ if(MOUNTED){ FSInfo fsinfo; LittleFS.info(fsinfo); FREESPACE = fsinfo.totalBytes - fsinfo.usedBytes; } else FREESPACE = 0; return FREESPACE; } int configPWR::getFreeSpace(){ return this->FREESPACE; } //******************* read dir from file-system ************************ String configPWR::readDir(){ String ret="Files:
"; Dir dir =LittleFS.openDir("/"); while (dir.next()){ ret += dir.fileName(); if(dir.fileSize()) { File f=dir.openFile("r"); ret+=" -> Size: "; ret+=f.size(); ret+=" Bytes
"; } else ret += "
"; } return ret; } //******************* decode post-values ******************************* String configPWR::getOnePostValue(String post,String value){ String returnValue=""; if(post.length()>0){ int mmenBegin = post.indexOf(value); if(mmenBegin >= 0){ int argEnd = post.indexOf("&",mmenBegin); if (argEnd == -1) argEnd = post.length(); returnValue = post.substring(post.indexOf("=",mmenBegin)+1, argEnd); } } return this->urldecode(returnValue); } /***** decode values from html-post-arguments *****/ bool configPWR::savePostValues(String saveValues){ bool r=false; //Serial.println(saveValues); this->VALUE_UWPUMP_ON=getOnePostValue(saveValues,ActionPump).toInt(); this->MAXIMAL_CONSUMPTION=getOnePostValue(saveValues,MaxConsumption).toInt(); this->MAX_TEMPERATUR=getOnePostValue(saveValues,MaxTemperatur).toInt(); this->VALUE_ACTION_OFF=getOnePostValue(saveValues,ActionOff).toInt(); this->VALUE_REGLER=getOnePostValue(saveValues,RegelValue).toInt(); this->VALUE_KP=getOnePostValue(saveValues,RegelKp).toInt(); this->AUTOMATIC_ON=getOnePostValue(saveValues,Automatic).toInt(); this->saveConfig(); return true; } /***** decode values from html-post-arguments *****/ bool configPWR::savePostValuesAdvance(String saveValues){ bool r=false; this->NAME_PWR=getOnePostValue(saveValues,ReglerName); this->TARGET_METER=getOnePostValue(saveValues,MeterIP); this->UPDATE_SERVER=getOnePostValue(saveValues,UpdateUrl); this->BROKER_TARGET=getOnePostValue(saveValues,mqttTarget); this->BROKER_USER=getOnePostValue(saveValues,mqttUser); this->BROKER_PW=getOnePostValue(saveValues,mqttPass); this->VALUE_MINUTE_PUMP_OFF=getOnePostValue(saveValues,PumpOff).toInt(); // this->VALUE_ACTION_OFF=getOnePostValue(saveValues,ActionOff).toInt(); this->WAIT_TIME_ACTION=getOnePostValue(saveValues,WaitOn).toInt(); this->WAIT_TIME_OFF=getOnePostValue(saveValues,WaitOff).toInt(); this->TEMP_HISTERESE=getOnePostValue(saveValues,TempHisterese).toInt(); this->ERROR_WAIT=getOnePostValue(saveValues,ErrorWait).toInt(); this->SCAN_METER=getOnePostValue(saveValues,ScanMeter).toInt(); this->MQTT_INTERVAL=getOnePostValue(saveValues,mqttInterval).toInt(); if(saveValues.indexOf("tChange") >=0) _exchangeTemp=true; else _exchangeTemp=false; if(saveValues.indexOf("XZmqON") >=0) SendMQTT=1; else SendMQTT=0; if(saveValues.indexOf("XZs2s") >=0) SEND2SERVER=true; else SEND2SERVER=false; this->saveConfig(); return true; } /***** url decoding part *****/ unsigned char configPWR::h2int(char c) { if (c >= '0' && c <='9') return((unsigned char)c - '0'); if (c >= 'a' && c <='f') return((unsigned char)c - 'a' + 10); if (c >= 'A' && c <='F') return((unsigned char)c - 'A' + 10); return(0); } /***** url decoding function ******/ String configPWR::urldecode(String str) { String encodedString=""; char c; char code0; char code1; for (int i =0; i < str.length(); i++){ c=str.charAt(i); if (c == '+') encodedString+=' '; else if (c == '%') { i++; code0=str.charAt(i); i++; code1=str.charAt(i); c = (h2int(code0) << 4) | h2int(code1); encodedString+=c; } else encodedString+=c; yield(); } return encodedString; } /***** url encoding function ******/ String configPWR::urlencode(String str) { String encodedString=""; char c; char code0; char code1; char code2; for (int i =0; i < str.length(); i++){ c=str.charAt(i); if (c == ' ') encodedString+= '+'; else if (isalnum(c)) encodedString+=c; else{ code1=(c & 0xf)+'0'; if ((c & 0xf) >9) code1=(c & 0xf) - 10 + 'A'; c=(c>>4)&0xf; code0=c+'0'; if (c > 9) code0=c - 10 + 'A'; code2='\0'; encodedString+='%'; encodedString+=code0; encodedString+=code1; //encodedString+=code2; } yield(); } return encodedString; } //*** class end #endif //*** CONFIG_PWR_H_