diff --git a/src/CHANGES.md b/src/CHANGES.md index c6daf2ac..83e4124d 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.7.39 - 2023-08-21 +* fix background color of invalid inputs +* add hardware info (click in `live` on inverter name) + ## 0.7.38 - 2023-08-21 * reset alarms at midnight (if inverter is not available) #1105, #1096 * add option to reset 'max' values on midnight #1102 diff --git a/src/defines.h b/src/defines.h index 021b4010..ffdcab75 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 7 -#define VERSION_PATCH 38 +#define VERSION_PATCH 39 //------------------------------------- typedef struct { diff --git a/src/web/RestApi.h b/src/web/RestApi.h index ce06ae6b..a0a457d1 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -98,17 +98,13 @@ class RestApi { else if(path == "setup/networks") getNetworks(root); #endif /* !defined(ETHERNET) */ else if(path == "live") getLive(request,root); - /*else if(path == "record/info") getRecord(root, InverterDevInform_All); - else if(path == "record/alarm") getRecord(root, AlarmData); - else if(path == "record/config") getRecord(root, SystemConfigPara); - else if(path == "record/live") getRecord(root, RealTimeRunData_Debug);*/ else { if(path.substring(0, 12) == "inverter/id/") getInverter(root, request->url().substring(17).toInt()); else if(path.substring(0, 15) == "inverter/alarm/") getIvAlarms(root, request->url().substring(20).toInt()); else if(path.substring(0, 17) == "inverter/version/") - getIvVersion(root, request->url().substring(20).toInt()); + getIvVersion(root, request->url().substring(22).toInt()); else getNotFound(root, F("http://") + request->host() + F("/api/")); } @@ -434,21 +430,28 @@ class RestApi { record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); obj[F("name")] = String(iv->config->name); + obj[F("serial")] = String(iv->config->serial.u64, HEX); obj[F("generation")] = iv->ivGen; obj[F("max_pwr")] = iv->getMaxPower(); obj[F("part_num")] = iv->getChannelFieldValueInt(CH0, FLD_PART_NUM, rec); obj[F("hw_ver")] = iv->getChannelFieldValueInt(CH0, FLD_HW_VERSION, rec); - obj[F("prod_cw")] = ((iv->config->serial.b[3] & 0x0f) * 10 + ((iv->config->serial.b[2] & 0x0f))); + obj[F("prod_cw")] = ((iv->config->serial.b[3] & 0x0f) * 10 + (((iv->config->serial.b[2] >> 4) & 0x0f))); obj[F("prod_year")] = ((iv->config->serial.b[3] >> 4) & 0x0f) + 2014; rec = iv->getRecordStruct(InverterDevInform_All); - obj[F("fw_ver")] = iv->getChannelFieldValueInt(CH0, FLD_FW_VERSION, rec); - obj[F("fw_date")] = String(iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_YEAR, rec)) - + "-" + String(iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_MONTH_DAY, rec) / 100) - + "-" + String(iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_MONTH_DAY, rec) % 100); - obj[F("fw_time")] = String(iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_HOUR_MINUTE, rec) / 100) - + ":" + String(iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_HOUR_MINUTE, rec) % 100); + char buf[10]; + uint16_t val; + + val = iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_MONTH_DAY, rec); + snprintf(buf, 10, "-%02d-%02d", (val / 100), (val % 100)); + obj[F("fw_date")] = String(iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_YEAR, rec)) + String(buf); + val = iv->getChannelFieldValueInt(CH0, FLD_FW_BUILD_HOUR_MINUTE, rec); + snprintf(buf, 10, "%02d:%02d", (val / 100), (val % 100)); + obj[F("fw_time")] = String(buf); + val = iv->getChannelFieldValueInt(CH0, FLD_FW_VERSION, rec); + snprintf(buf, 10, "%d.%02d.%02d", (val / 10000), ((val % 10000) / 100), (val % 100)); + obj[F("fw_ver")] = String(buf); obj[F("boot_ver")] = iv->getChannelFieldValueInt(CH0, FLD_BOOTLOADER_VER, rec); } diff --git a/src/web/html/colorBright.css b/src/web/html/colorBright.css index 81d57326..255b5130 100644 --- a/src/web/html/colorBright.css +++ b/src/web/html/colorBright.css @@ -17,6 +17,8 @@ --footer-bg: #282828; --modal-bg: #fff; + --invalid-bg: #f99; + --total-head-title: #8e5903; --total-bg: #b06e04; --iv-head-title: #1c6800; diff --git a/src/web/html/colorDark.css b/src/web/html/colorDark.css index 549158b9..d143f8be 100644 --- a/src/web/html/colorDark.css +++ b/src/web/html/colorDark.css @@ -17,6 +17,8 @@ --footer-bg: #282828; --modal-bg: #666; + --invalid-bg: #400; + --total-head-title: #555511; --total-bg: #666622; --iv-head-title: #115511; diff --git a/src/web/html/style.css b/src/web/html/style.css index f61b1a18..4d4dc6f8 100644 --- a/src/web/html/style.css +++ b/src/web/html/style.css @@ -501,7 +501,7 @@ input[type=text], input[type=password], select, input[type=number] { input:invalid { border: 2px solid #f00 !important; - background-color: #400 !important; + background-color: var(--invalid-bg) !important; } input.sh { diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index a8048eb3..c7de12ff 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -261,7 +261,7 @@ case 3: model = "HMT-"; break; default: model = "???-"; break; } - model += String(obj.max_pwr); + model += String(obj.max_pwr) + " (Serial: " + obj.serial + ")"; var html = ml("table", {class: "table"}, [ @@ -276,15 +276,15 @@ ]), ml("tr", {}, [ ml("th", {}, "Hardware Version / Build"), - ml("td", {}, String(obj.hw_ver) + " (build: " + String(obj.prod_cw) + "/" + String(obj.prod_year) + ")") + ml("td", {}, (obj.hw_ver.toString(16) / 100).toFixed(2) + " (build: " + String(obj.prod_cw) + "/" + String(obj.prod_year) + ")") ]), ml("tr", {}, [ ml("th", {}, "Hardware Number"), - ml("td", {}, String(obj.part_num)) + ml("td", {}, obj.part_num.toString(16)) ]), ml("tr", {}, [ ml("th", {}, "Bootloader Version"), - ml("td", {}, String(obj.boot_ver)) + ml("td", {}, (obj.boot_ver / 100).toFixed(2)) ]) ]) ]);