X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fprint_battery_info.c;h=7a462f7fcf29dd0148d19f3a3189e09f24b5bc48;hb=95c068358acb303ab01ab8dc372f893aec5fe1b0;hp=52d503149d4e2b6081d83517e62cd88daf190741;hpb=dc072f9f5353dc8adab14b2de99f0c1abb25e8d8;p=i3%2Fi3status diff --git a/src/print_battery_info.c b/src/print_battery_info.c index 52d5031..7a462f7 100644 --- a/src/print_battery_info.c +++ b/src/print_battery_info.c @@ -11,7 +11,7 @@ #if defined(LINUX) #include -#include +#include #include #endif @@ -138,9 +138,13 @@ static bool slurp_battery_info(struct battery_info *batt_info, yajl_gen json_gen if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW=")) { watt_as_unit = true; batt_info->remaining = atoi(walk + 1); + batt_info->percentage_remaining = -1; } else if (BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW=")) { watt_as_unit = false; batt_info->remaining = atoi(walk + 1); + batt_info->percentage_remaining = -1; + } else if (BEGINS_WITH(last, "POWER_SUPPLY_CAPACITY=") && batt_info->remaining == -1) { + batt_info->percentage_remaining = atoi(walk + 1); } else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW=")) batt_info->present_rate = abs(atoi(walk + 1)); else if (BEGINS_WITH(last, "POWER_SUPPLY_VOLTAGE_NOW=")) @@ -171,11 +175,19 @@ static bool slurp_battery_info(struct battery_info *batt_info, yajl_gen json_gen * POWER_SUPPLY_CHARGE_NOW is the unit of measurement. The energy is * given in mWh, the charge in mAh. So calculate every value given in * ampere to watt */ - if (!watt_as_unit && voltage != -1) { - batt_info->present_rate = (((float)voltage / 1000.0) * ((float)batt_info->present_rate / 1000.0)); - batt_info->remaining = (((float)voltage / 1000.0) * ((float)batt_info->remaining / 1000.0)); - batt_info->full_design = (((float)voltage / 1000.0) * ((float)batt_info->full_design / 1000.0)); - batt_info->full_last = (((float)voltage / 1000.0) * ((float)batt_info->full_last / 1000.0)); + if (!watt_as_unit && voltage >= 0) { + if (batt_info->present_rate > 0) { + batt_info->present_rate = (((float)voltage / 1000.0) * ((float)batt_info->present_rate / 1000.0)); + } + if (batt_info->remaining > 0) { + batt_info->remaining = (((float)voltage / 1000.0) * ((float)batt_info->remaining / 1000.0)); + } + if (batt_info->full_design > 0) { + batt_info->full_design = (((float)voltage / 1000.0) * ((float)batt_info->full_design / 1000.0)); + } + if (batt_info->full_last > 0) { + batt_info->full_last = (((float)voltage / 1000.0) * ((float)batt_info->full_last / 1000.0)); + } } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) int state; @@ -414,40 +426,39 @@ static bool slurp_all_batteries(struct battery_info *batt_info, yajl_gen json_ge char *outwalk = buffer; bool is_found = false; - /* 1,000 batteries should be enough for anyone */ - for (int i = 0; i < 1000; i++) { - char batpath[1024]; - (void)snprintf(batpath, sizeof(batpath), path, i); - - if (!strcmp(batpath, path)) { - OUTPUT_FULL_TEXT("no '%d' in battery path"); - return false; - } + char *placeholder; + char *globpath = sstrdup(path); + if ((placeholder = strstr(path, "%d")) != NULL) { + char *globplaceholder = globpath + (placeholder - path); + *globplaceholder = '*'; + strcpy(globplaceholder + 1, placeholder + 2); + } - /* Probe to see if there is such a battery. */ - struct stat sb; - if (stat(batpath, &sb) != 0) { - /* No such file, then we are done, assuming sysfs files have sequential numbers. */ - if (errno == ENOENT) - break; + if (!strcmp(globpath, path)) { + OUTPUT_FULL_TEXT("no '%d' in battery path"); + return false; + } - OUTPUT_FULL_TEXT(format_down); - return false; + glob_t globbuf; + if (glob(globpath, 0, NULL, &globbuf) == 0) { + for (size_t i = 0; i < globbuf.gl_pathc; i++) { + /* Probe to see if there is such a battery. */ + struct battery_info batt_buf = { + .full_design = 0, + .full_last = 0, + .remaining = 0, + .present_rate = 0, + .status = CS_UNKNOWN, + }; + if (!slurp_battery_info(&batt_buf, json_gen, buffer, i, globbuf.gl_pathv[i], format_down)) + return false; + + is_found = true; + add_battery_info(batt_info, &batt_buf); } - - struct battery_info batt_buf = { - .full_design = 0, - .full_last = 0, - .remaining = 0, - .present_rate = 0, - .status = CS_UNKNOWN, - }; - if (!slurp_battery_info(&batt_buf, json_gen, buffer, i, path, format_down)) - return false; - - is_found = true; - add_battery_info(batt_info, &batt_buf); } + globfree(&globbuf); + free(globpath); if (!is_found) { OUTPUT_FULL_TEXT(format_down); @@ -483,7 +494,7 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char /* These OSes report battery stats in whole percent. */ integer_battery_capacity = true; #endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__OpenBSD__) /* These OSes report battery time in minutes. */ hide_seconds = true; #endif @@ -496,8 +507,19 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char return; } - int full = (last_full_capacity ? batt_info.full_last : batt_info.full_design); - if (full < 0 && batt_info.percentage_remaining < 0) { + // *Choose* a measure of the 'full' battery. It is whichever is better of + // the battery's (hardware-given) design capacity (batt_info.full_design) + // and the battery's last known good charge (batt_info.full_last). + // We prefer the design capacity, but use the last capacity if we don't have it, + // or if we are asked to (last_full_capacity == true); but similarly we use + // the design capacity if we don't have the last capacity. + // If we don't have either then both full_design and full_last <= 0, + // which implies full <= 0, which bails out on the following line. + int full = batt_info.full_design; + if (full <= 0 || (last_full_capacity && batt_info.full_last > 0)) { + full = batt_info.full_last; + } + if (full <= 0 && batt_info.remaining < 0 && batt_info.percentage_remaining < 0) { /* We have no physical measurements and no estimates. Nothing * much we can report, then. */ OUTPUT_FULL_TEXT(format_down); @@ -599,6 +621,7 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char } else if (BEGINS_WITH(walk + 1, "emptytime")) { if (batt_info.seconds_remaining >= 0) { time_t empty_time = time(NULL) + batt_info.seconds_remaining; + set_timezone(NULL); /* Use local time. */ struct tm *empty_tm = localtime(&empty_time); if (hide_seconds)