diff --git a/lib/obp60task/OBP60Formater.cpp b/lib/obp60task/OBP60Formater.cpp index 6e7e56e..9225886 100644 --- a/lib/obp60task/OBP60Formater.cpp +++ b/lib/obp60task/OBP60Formater.cpp @@ -9,6 +9,7 @@ // hold values by missing data FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){ + GwLog *logger = commondata.logger; FormatedData result; static int dayoffset = 0; @@ -33,28 +34,15 @@ FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){ buffer[0]=0; //######################################################## if (value->getFormat() == "formatDate"){ + + int dayoffset = 0; + if (commondata.time->value + int(timeZone*3600) > 86400) {dayoffset = 1;} + if (commondata.time->value + int(timeZone*3600) < 0) {dayoffset = -1;} - double utctime = commondata.time->value; // UTC time in secounds of the day (GPS or bus data) - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/* - time_t now; - char strftime_buf[64]; - struct tm timeinfo; - - time(&now); - // Set timezone to China Standard Time - setenv("TZ", "CST-8", 1); - tzset(); - localtime_r(&now, &timeinfo); - - strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); -*/ - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + LOG_DEBUG(GwLog::DEBUG,"... formatDate value->value: %f tz: %f dayoffset: %d", value->value, timeZone, dayoffset); tmElements_t parts; time_t tv=tNMEA0183Msg::daysToTime_t(value->value + dayoffset); - tNMEA0183Msg::breakTime(tv,parts); if(usesimudata == false) { if(String(dateFormat) == "DE"){ @@ -83,41 +71,16 @@ FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){ //######################################################## else if(value->getFormat() == "formatTime"){ double timeInSeconds = 0; - double utcTime = 0; double inthr = 0; double intmin = 0; double intsec = 0; double val = 0; - if(timeZone > 0){ - timeInSeconds = value->value + timeZone * 3600; - timeInSeconds = int(timeInSeconds) % 86400; // Reduce to one day (86400s) - } - else{ - timeInSeconds = value->value + timeZone * 3600 + 86400; // Add one day - timeInSeconds = int(timeInSeconds) % 86400; // Reduce to one day (86400s) - } -/* - // Changing day depends on time offset - utcTime = value->value; - if(timeZone + (utcTime/3600) > 24 && timeZone > 0){ - dayoffset = 1; - } - else{ - dayoffset = 0; - } - if(timeZone == 0){ - dayoffset = 0; - } - if(timeZone + (utcTime/3600) > 24 && timeZone < 0){ - dayoffset = 0; - } - else{ - dayoffset = -1; - } -*/ - - if(usesimudata == false) { + timeInSeconds = value->value + int(timeZone * 3600); + if (timeInSeconds > 86400) {timeInSeconds = timeInSeconds - 86400;} + if (timeInSeconds < 0) {timeInSeconds = timeInSeconds + 86400;} + LOG_DEBUG(GwLog::DEBUG,"... formatTime value: %f tz: %f corrected timeInSeconds: %f ", value->value, timeZone, timeInSeconds); + if(usesimudata == false) { val=modf(timeInSeconds/3600.0,&inthr); val=modf(val*3600.0/60.0,&intmin); modf(val*60.0,&intsec); diff --git a/lib/obp60task/PageBattery.cpp b/lib/obp60task/PageBattery.cpp new file mode 100644 index 0000000..4aa46e7 --- /dev/null +++ b/lib/obp60task/PageBattery.cpp @@ -0,0 +1,238 @@ +#ifdef BOARD_NODEMCU32S_OBP60 + +#include "Pagedata.h" +#include "OBP60ExtensionPort.h" + +class PageBattery : public Page +{ + bool keylock = false; // Keylock + + public: + PageBattery(CommonData &comon){ + comon.logger->logDebug(GwLog::LOG,"Show PageThreeValue"); + } + + virtual int handleKey(int key){ + if(key == 11){ // Code for keylock + keylock = !keylock; // Toggle keylock + return 0; // Commit the key + } + return key; + } + + virtual void displayPage(CommonData &commonData, PageData &pageData){ + GwConfigHandler *config = commonData.config; + GwLog *logger=commonData.logger; + + // Old values for hold function + double value1 = 0; + static String svalue1old = ""; + static String unit1old = ""; + double value2 = 0; + static String svalue2old = ""; + static String unit2old = ""; + double value3 = 0; + static String svalue3old = ""; + static String unit3old = ""; + + // Get config data + String lengthformat = config->getString(config->lengthFormat); + // bool simulation = config->getBool(config->useSimuData); + String displaycolor = config->getString(config->displaycolor); + String flashLED = config->getString(config->flashLED); + String backlightMode = config->getString(config->backlight); + String powsensor1 = config->getString(config->usePowSensor1); + bool simulation = config->getBool(config->useSimuData); + + // Get voltage value + String name1 = "BatVolt"; // Value name + if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){ + value1 = commonData.data.batteryVoltage; // Value as double in SI unit + } + else{ + if(simulation == false){ + value1 = 0; // No sensor data + } + else{ + value1 = 12 + float(random(0, 5)) / 10; // Simulation data + } + } + String svalue1 = String(value1); // Formatted value as string including unit conversion and switching decimal places + String unit1 = "V"; // Unit of value + + // Get current value + String name2 = "BatCurr"; // Value name + if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){ + value2 = commonData.data.batteryCurrent; // Value as double in SI unit + } + else{ + if(simulation == false){ + value2 = 0; // No sensor data + } + else{ + value2 = 8 + float(random(0, 10)) / 10; // Simulation data + } + } + String svalue2 = String(value2); // Formatted value as string including unit conversion and switching decimal places + String unit2 = "A"; // Unit of value + + // Get power value + String name3 = "BatPow"; // Value name + if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){ + value3 = commonData.data.batteryPower; // Value as double in SI unit + } + else{ + if(simulation == false){ + value3 = 0; // No sensor data + } + else{ + value3 = value1 * value2; // Simulation data + } + } + String svalue3 = String(value3); // Formatted value as string including unit conversion and switching decimal places + String unit3 = "W"; // Unit of value + + // Optical warning by limit violation (unused) + if(String(flashLED) == "Limit Violation"){ + setBlinkingLED(false); + setPortPin(OBP_FLASH_LED, false); + } + + // Logging boat values + LOG_DEBUG(GwLog::LOG,"Drawing at PageBattery, %s: %f, %s: %f, %s: %f", name1, value1, name2, value2, name3, value3); + + // Draw page + //*********************************************************** + + // Set background color and text color + int textcolor = GxEPD_BLACK; + int pixelcolor = GxEPD_BLACK; + int bgcolor = GxEPD_WHITE; + if(displaycolor == "Normal"){ + textcolor = GxEPD_BLACK; + pixelcolor = GxEPD_BLACK; + bgcolor = GxEPD_WHITE; + } + else{ + textcolor = GxEPD_WHITE; + pixelcolor = GxEPD_WHITE; + bgcolor = GxEPD_BLACK; + } + // Clear display by call in obp60task.cpp in main loop + + // ############### Value 1 ################ + + // Show name + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold20pt7b); + display.setCursor(20, 55); + display.print(name1); // Value name + + // Show unit + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold12pt7b); + display.setCursor(20, 90); + display.print(unit1); // Unit + + + // Show value + display.setFont(&DSEG7Classic_BoldItalic30pt7b); + display.setCursor(180, 90); + + // Show bus data + display.print(value1,2); // Real value as formated string + + // ############### Horizontal Line ################ + + // Horizontal line 3 pix + display.fillRect(0, 105, 400, 3, pixelcolor); + + // ############### Value 2 ################ + + // Show name + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold20pt7b); + display.setCursor(20, 145); + display.print(name2); // Value name + + // Show unit + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold12pt7b); + display.setCursor(20, 180); + display.print(unit2); // Unit + + // Show value + display.setFont(&DSEG7Classic_BoldItalic30pt7b); + display.setCursor(180, 180); + + // Show bus data + display.print(value2,1); // Real value as formated string + + // ############### Horizontal Line ################ + + // Horizontal line 3 pix + display.fillRect(0, 195, 400, 3, pixelcolor); + + // ############### Value 3 ################ + + // Show name + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold20pt7b); + display.setCursor(20, 235); + display.print(name3); // Value name + + // Show unit + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold12pt7b); + display.setCursor(20, 270); + display.print(unit3); // Unit + + // Show value + display.setFont(&DSEG7Classic_BoldItalic30pt7b); + display.setCursor(180, 270); + + // Show bus data + display.print(value3,1); // Real value as formated string + + + // ############### Key Layout ################ + + // Key Layout + display.setTextColor(textcolor); + display.setFont(&Ubuntu_Bold8pt7b); + display.setCursor(130, 290); + if(keylock == false){ + display.print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); + if(String(backlightMode) == "Control by Key"){ // Key for illumination + display.setCursor(343, 290); + display.print("[ILUM]"); + } + } + else{ + display.print(" [ Keylock active ]"); + } + + // Update display + display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, true); // Partial update (fast) + + }; +}; + +static Page *createPage(CommonData &common){ + return new PageBattery(common); +}/** + * with the code below we make this page known to the PageTask + * we give it a type (name) that can be selected in the config + * we define which function is to be called + * and we provide the number of user parameters we expect + * this will be number of BoatValue pointers in pageData.values + */ +PageDescription registerPageBattery( + "Battery", // Page name + createPage, // Action + 0, // Number of bus values depends on selection in Web configuration + {}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h) + true // Show display header on/off +); + +#endif \ No newline at end of file diff --git a/lib/obp60task/PageClock.cpp b/lib/obp60task/PageClock.cpp index 3e37953..84cdb8f 100644 --- a/lib/obp60task/PageClock.cpp +++ b/lib/obp60task/PageClock.cpp @@ -42,7 +42,8 @@ public: bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); - int timezone = config->getInt(config->timeZone); + String stimezone = config->getString(config->timeZone); + double timezone = stimezone.toDouble(); // Get boat values for GPS time GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) @@ -267,11 +268,13 @@ public: // Clock values double hour = 0; double minute = 0; + value1 = value1 + int(timezone*3600); + if (value1 > 86400) {value1 = value1 - 86400;} + if (value1 < 0) {value1 = value1 + 86400;} hour = (value1 / 3600.0); if(hour > 12) hour = hour - 12.0; - hour = hour + timezone; minute = (hour - int(hour)) * 3600.0 / 60.0; - + LOG_DEBUG(GwLog::DEBUG,"... PageClock, value1: %f hour: %f minute:%f", value1, hour, minute); // Draw hour pointer float startwidth = 8; // Start width of pointer if(valid1 == true || holdvalues == true || simulation == true){ diff --git a/lib/obp60task/PageKeelPosition.cpp b/lib/obp60task/PageKeelPosition.cpp index bac743c..f64fab9 100644 --- a/lib/obp60task/PageKeelPosition.cpp +++ b/lib/obp60task/PageKeelPosition.cpp @@ -46,6 +46,9 @@ public: value1 = commonData.data.rotationAngle; // Raw value without unit convertion } else{ + value1 = 0; + } + if(simulation == true){ value1 = (170 + float(random(0, 40)) / 10.0) * 2 * PI / 360; // Simulation data in radiant } diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index f0e559e..d47d5e6 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -656,7 +656,7 @@ "type": "list", "default": "Voltage", "description": "Type of page for page 1", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 1", "capabilities": { "obp60":"true" @@ -716,7 +716,7 @@ "type": "list", "default": "apparentWind", "description": "Type of page for page 2", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 2", "capabilities": { "obp60":"true" @@ -777,7 +777,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 3", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 3", "capabilities": { "obp60":"true" @@ -838,7 +838,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 4", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 4", "capabilities": { "obp60":"true" @@ -899,7 +899,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 5", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 5", "capabilities": { "obp60":"true" @@ -960,7 +960,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 6", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 6", "capabilities": { "obp60":"true" @@ -1021,7 +1021,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 7", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 7", "capabilities": { "obp60":"true" @@ -1082,7 +1082,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 8", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 8", "capabilities": { "obp60":"true" @@ -1143,7 +1143,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 9", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 9", "capabilities": { "obp60":"true" @@ -1204,7 +1204,7 @@ "type": "list", "default": "oneValue", "description": "Type of page for page 10", - "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition"], + "list":["oneValue","twoValues","threeValues","forValues","forValues2","apparentWind","WindRose","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KellPosition","Battery"], "category": "OBP60 Page 10", "capabilities": { "obp60":"true" diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 3632bd4..ebb9a46 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -205,6 +205,8 @@ void registerAllPages(PageList &list){ list.add(®isterPageRudderPosition); extern PageDescription registerPageKeelPosition; list.add(®isterPageKeelPosition); + extern PageDescription registerPageBattery; + list.add(®isterPageBattery); } // OBP60 Task diff --git a/lib/obp60task/obp60task.h b/lib/obp60task/obp60task.h index 7678b0c..b2b9443 100644 --- a/lib/obp60task/obp60task.h +++ b/lib/obp60task/obp60task.h @@ -20,7 +20,7 @@ DECLARE_INITFUNCTION(OBP60Init); // OBP60 Task void OBP60Task(GwApi *param); -DECLARE_USERTASK_PARAM(OBP60Task, 15000) // Need 15k RAM as stack size +DECLARE_USERTASK_PARAM(OBP60Task, 20000) // Need 20k RAM as stack size DECLARE_CAPABILITY(obp60,true); #endif \ No newline at end of file