*** BatteryMeter.c.orig 2026-01-14 20:50:00 --- BatteryMeter.c 2026-01-14 20:50:00 *************** *** 25,37 **** --- 25,57 ---- + #include + #include + #include + #include + + #define APC_CMD "/usr/sbin/apcaccess" + + typedef struct UPSData { + int percent; // 0-100 + int charging; // 1=ONLINE/FULL, 0=ONBATTERY + int time_left; // minutes + } UPSData; + + static UPSData ups_cache = {0}; + static time_t last_ups_update = 0; + + static int read_ups(UPSData *ups) + { + FILE *fp = popen(APC_CMD " status", "r"); + if (!fp) + return -1; + + char line[256]; + while (fgets(line, sizeof(line), fp)) { + if (strncmp(line, "BCHARGE", 7) == 0) + ups->percent = atoi(strchr(line, ':') + 1); + else if (strncmp(line, "STATUS", 6) == 0) { + if (strstr(line, "ONLINE") || strstr(line, "FULL")) + ups->charging = 1; + else if (strstr(line, "ONBATT")) + ups->charging = 0; + } + else if (strncmp(line, "TIMELEFT", 8) == 0) + ups->time_left = atoi(strchr(line, ':') + 1); + } + + pclose(fp); + return 0; + } *** 42,59 **** - static void BatteryMeter_updateValues(Meter* this) { - ACPresence isOnAC; - double percent; - - Platform_getBattery(&percent, &isOnAC); - - if (!isNonnegative(percent)) { - this->values[0] = NAN; - xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "N/A"); - return; - } - - this->values[0] = percent; - - const char* text; - switch (isOnAC) { - case AC_PRESENT: - text = this->mode == TEXT_METERMODE ? " (Running on A/C)" : "(A/C)"; - break; - case AC_ABSENT: - text = this->mode == TEXT_METERMODE ? " (Running on battery)" : "(bat)"; - break; - case AC_ERROR: - default: - text = ""; - break; - } - - xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.1f%%%s", percent, text); - } --- 62,84 ---- + static void BatteryMeter_updateValues(Meter* this) { + ACPresence isOnAC; + double percent; + + // Get system battery info (optional fallback) + Platform_getBattery(&percent, &isOnAC); + + // Poll UPS every 2 seconds + if (time(NULL) - last_ups_update > 2) { + if (read_ups(&ups_cache) == 0) + last_ups_update = time(NULL); + } + + // Always override with UPS info if available + percent = (double)ups_cache.percent; + isOnAC = ups_cache.charging ? AC_PRESENT : AC_ABSENT; + + this->values[0] = percent; + + const char* text; + switch (isOnAC) { + case AC_PRESENT: + text = this->mode == TEXT_METERMODE ? " (Running on A/C)" : "(A/C)"; + break; + case AC_ABSENT: + text = this->mode == TEXT_METERMODE ? " (Running on battery)" : "(bat)"; + break; + case AC_ERROR: + default: + text = ""; + break; + } + + xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.1f%%%s", percent, text); + }