diff --git a/i3status.c b/i3status.c index 3922bf2c..f3ff0e8c 100644 --- a/i3status.c +++ b/i3status.c @@ -320,11 +320,18 @@ int main(int argc, char *argv[]) { CFG_STR("format_percentage", "%.02f%s", CFGF_NONE), CFG_STR("status_chr", "CHR", CFGF_NONE), CFG_STR("status_bat", "BAT", CFGF_NONE), + CFG_STR("status_bat_low", "BAT", CFGF_NONE), + CFG_STR("status_bat_quarter", "BAT", CFGF_NONE), + CFG_STR("status_bat_half", "BAT", CFGF_NONE), + CFG_STR("status_bat_three_quarters", "BAT", CFGF_NONE), CFG_STR("status_unk", "UNK", CFGF_NONE), CFG_STR("status_full", "FULL", CFGF_NONE), CFG_STR("status_idle", "IDLE", CFGF_NONE), CFG_STR("path", "/sys/class/power_supply/BAT%d/uevent", CFGF_NONE), CFG_INT("low_threshold", 30, CFGF_NONE), + CFG_INT("quarter_threshold", 45, CFGF_NONE), + CFG_INT("half_threshold", 60, CFGF_NONE), + CFG_INT("three_quarters_threshold", 75, CFGF_NONE), CFG_STR("threshold_type", "time", CFGF_NONE), CFG_BOOL("last_full_capacity", false, CFGF_NONE), CFG_BOOL("integer_battery_capacity", false, CFGF_NONE), @@ -741,10 +748,17 @@ int main(int argc, char *argv[]) { .format_down = cfg_getstr(sec, "format_down"), .status_chr = cfg_getstr(sec, "status_chr"), .status_bat = cfg_getstr(sec, "status_bat"), + .status_bat_low = cfg_getstr(sec, "status_bat_low"), + .status_bat_quarter = cfg_getstr(sec, "status_bat_quarter"), + .status_bat_half = cfg_getstr(sec, "status_bat_half"), + .status_bat_three_quarters = cfg_getstr(sec, "status_bat_three_quarters"), .status_unk = cfg_getstr(sec, "status_unk"), .status_full = cfg_getstr(sec, "status_full"), .status_idle = cfg_getstr(sec, "status_idle"), .low_threshold = cfg_getint(sec, "low_threshold"), + .quarter_threshold = cfg_getint(sec, "quarter_threshold"), + .half_threshold = cfg_getint(sec, "half_threshold"), + .three_quarters_threshold = cfg_getint(sec, "three_quarters_threshold"), .threshold_type = cfg_getstr(sec, "threshold_type"), .last_full_capacity = cfg_getbool(sec, "last_full_capacity"), .format_percentage = cfg_getstr(sec, "format_percentage"), diff --git a/include/i3status.h b/include/i3status.h index ad05055d..000fcb29 100644 --- a/include/i3status.h +++ b/include/i3status.h @@ -269,10 +269,17 @@ typedef struct { const char *format_down; const char *status_chr; const char *status_bat; + const char *status_bat_low; + const char *status_bat_quarter; + const char *status_bat_half; + const char *status_bat_three_quarters; const char *status_unk; const char *status_full; const char *status_idle; int low_threshold; + int quarter_threshold; + int half_threshold; + int three_quarters_threshold; char *threshold_type; bool last_full_capacity; const char *format_percentage; diff --git a/man/i3status.man b/man/i3status.man index 06a120c0..5b28c4c6 100644 --- a/man/i3status.man +++ b/man/i3status.man @@ -92,6 +92,25 @@ battery 0 { low_threshold = 10 } +battery 1 { + format = "%status %percentage %remaining %emptytime" + format_down = "No battery" + status_chr = "⚡ CHR" + status_bat = "🔋 BAT" + status_unk = "? UNK" + status_full = "☻ FULL" + status_idle = "☻ IDLE" + status_bat_low = "LOW" + status_bat_half = "½" + status_bat_quarter = "¼" + status_bat_three_quarters = "¾" + path = "/sys/class/power_supply/BAT%d/uevent" + low_threshold = 15 + quarter_threshold = 35 + half_threshold = 65 + threshold_type = "percentage" +} + run_watch DHCP { pidfile = "/var/run/dhclient*.pid" } @@ -389,7 +408,8 @@ battery states. This makes it possible to display individual symbols for each state (charging, discharging, unknown, full). Of course it will also work with special iconic fonts, such as FontAwesome. If any of these special status strings are omitted, the default (CHR, BAT, UNK, -FULL) is used. +FULL) is used. Battery capacity can also be shown with different custom strings +per quartile, with definable thresholds. *Example order (for the first battery)*: +battery 0+ @@ -405,18 +425,34 @@ FULL) is used. *Example status_bat*: +🔋 BAT+ +*Example status_bat_half*: +½+ + +*Example status_bat_low*: +LOW+ + +*Example status_bat_quarter*: +¼+ + +*Example status_bat_three_quarters*: +¾+ + *Example status_unk*: +? UNK+ *Example status_full*: +☻ FULL+ *Example low_threshold*: +30+ -*Example threshold_type*: +time+ +*Example threshold_type*: +time+ or +percentage+ *Example path (%d replaced by title number)*: +/sys/class/power_supply/CMB%d/uevent+ *Example path (ignoring the number)*: +/sys/class/power_supply/CMB1/uevent+ +*Example half_threshold (e.g., percentage)*: +65+ + +*Example low_threshold*: +15+ + +*Example quarter_threshold*: +35+ + +*Example three_quarters_threshold*: +85+ + === CPU-Temperature Gets the temperature of the given thermal zone. It is possible to @@ -497,7 +533,7 @@ decimals can be configured via the +decimals+ option. If no such option is given the converted format placeholder will have one decimal. As Linux' meminfo doesn't expose the overall memory in use, there are multiple -methods to distinguish the actually used memory. +methods to distinguish the actually used memory. *Example memory_used_method*: +memavailable+ ("total memory" - "MemAvailable", matches +free+ command) @@ -524,7 +560,7 @@ methods to distinguish the actually used memory. Gets the system load (number of processes waiting for CPU time in the last 1, 5 and 15 minutes). It is possible to define a max_threshold that will color the load value +color_bad+ in case the load average of the last minute is -getting higher than the configured threshold. Defaults to 5. The output +getting higher than the configured threshold. Defaults to 5. The output format when above +max_threshold+ can be customized with +format_above_threshold+. @@ -657,7 +693,7 @@ volume master { Outputs the contents of the specified file. You can use this to check contents of files on your system, for example /proc/uptime. By default the function only -reads the first 254 characters of the file, if you want to override this set +reads the first 254 characters of the file, if you want to override this set the +Max_characters+ option. It will never read beyond the first 4095 characters. If the file is not found "no file" will be printed, if the file can't be read "error read" will be printed. diff --git a/src/print_battery_info.c b/src/print_battery_info.c index 1f567231..ef57c379 100644 --- a/src/print_battery_info.c +++ b/src/print_battery_info.c @@ -290,10 +290,10 @@ static bool slurp_battery_info(battery_info_ctx_t *ctx, struct battery_info *bat batt_info->status = CS_DISCHARGING; #elif defined(__OpenBSD__) /* - * We're using apm(4) here, which is the interface to acpi(4) on amd64/i386 and - * the generic interface on macppc/sparc64/zaurus. Machines that have ACPI - * battery sensors gain some extra information. - */ + * We're using apm(4) here, which is the interface to acpi(4) on amd64/i386 and + * the generic interface on macppc/sparc64/zaurus. Machines that have ACPI + * battery sensors gain some extra information. + */ struct apm_power_info apm_info; struct sensordev sensordev; struct sensor sensor; @@ -601,6 +601,10 @@ void print_battery_info(battery_info_ctx_t *ctx) { .status = CS_UNKNOWN, }; bool colorful_output = false; + bool discharging_low = false; + bool discharging_quarter = false; + bool discharging_half = false; + bool discharging_three_quarters = false; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__OpenBSD__) /* These OSes report battery stats in whole percent. */ @@ -661,16 +665,38 @@ void print_battery_info(battery_info_ctx_t *ctx) { batt_info.seconds_remaining = 0; } - if (batt_info.status == CS_DISCHARGING && ctx->low_threshold > 0) { - if (batt_info.percentage_remaining >= 0 && strcasecmp(ctx->threshold_type, "percentage") == 0 && batt_info.percentage_remaining < ctx->low_threshold) { - START_COLOR("color_bad"); - colorful_output = true; - } else if (batt_info.seconds_remaining >= 0 && strcasecmp(ctx->threshold_type, "time") == 0 && batt_info.seconds_remaining < 60 * ctx->low_threshold) { - START_COLOR("color_bad"); - colorful_output = true; + if (batt_info.status == CS_DISCHARGING) { + if (!strcasecmp(ctx->threshold_type, "percentage")) { + if (batt_info.percentage_remaining <= ctx->low_threshold) + discharging_low = true; + else if (batt_info.percentage_remaining <= ctx->quarter_threshold) + discharging_quarter = true; + else if (batt_info.percentage_remaining <= ctx->half_threshold) + discharging_half = true; + else if (batt_info.percentage_remaining <= ctx->three_quarters_threshold) + discharging_three_quarters = true; + } else if (!strcasecmp(ctx->threshold_type, "time")) { + if (batt_info.seconds_remaining <= 60 * ctx->low_threshold) + discharging_low = true; + else if (batt_info.seconds_remaining <= 60 * ctx->quarter_threshold) + discharging_quarter = true; + else if (batt_info.seconds_remaining <= 60 * ctx->half_threshold) + discharging_half = true; + else if (batt_info.seconds_remaining <= 60 * ctx->three_quarters_threshold) + discharging_three_quarters = true; } } + if (discharging_low) { + START_COLOR("color_bad"); + colorful_output = true; + } + + if (discharging_quarter) { + START_COLOR("color_degraded"); + colorful_output = true; + } + char string_status[STRING_SIZE]; char string_percentage[STRING_SIZE]; // following variables are not alwasy set. If they are not set they should be empty. @@ -685,6 +711,18 @@ void print_battery_info(battery_info_ctx_t *ctx) { break; case CS_DISCHARGING: statusstr = ctx->status_bat; + + if (discharging_low && strcmp(ctx->status_bat_low, "BAT")) + statusstr = ctx->status_bat_low; + + if (discharging_quarter && strcmp(ctx->status_bat_quarter, "BAT")) + statusstr = ctx->status_bat_quarter; + + if (discharging_half && strcmp(ctx->status_bat_half, "BAT")) + statusstr = ctx->status_bat_half; + + if (discharging_three_quarters && strcmp(ctx->status_bat_three_quarters, "BAT")) + statusstr = ctx->status_bat_three_quarters; break; case CS_FULL: statusstr = ctx->status_full; diff --git a/src/print_eth_info.c b/src/print_eth_info.c index 9e2e22fe..ad738364 100644 --- a/src/print_eth_info.c +++ b/src/print_eth_info.c @@ -106,9 +106,9 @@ static int print_eth_speed(char *outwalk, const char *interface) { for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL; desc++) { /* - * Skip these non-informative values and go right ahead to the - * actual speeds. - */ + * Skip these non-informative values and go right ahead to the + * actual speeds. + */ if (BEGINS_WITH(desc->ifmt_string, "autoselect") || BEGINS_WITH(desc->ifmt_string, "auto")) continue; @@ -157,7 +157,7 @@ void print_eth_info(eth_info_ctx_t *ctx) { /* * Removing '%' and following characters from IPv6 since the interface identifier is redundant, * as the output already includes the interface name. - */ + */ if (ipv6_address != NULL) { char *prct_ptr = strstr(ipv6_address, "%"); if (prct_ptr != NULL) { diff --git a/testcases/027-battery-quartiles/BAT0_uevent b/testcases/027-battery-quartiles/BAT0_uevent new file mode 100644 index 00000000..51d866c1 --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=655 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=7600000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_half_pct b/testcases/027-battery-quartiles/BAT0_uevent_half_pct new file mode 100644 index 00000000..99640a71 --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_half_pct @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=655 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=3900000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_half_time b/testcases/027-battery-quartiles/BAT0_uevent_half_time new file mode 100644 index 00000000..bf858716 --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_half_time @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=60 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=7600000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_low_pct b/testcases/027-battery-quartiles/BAT0_uevent_low_pct new file mode 100644 index 00000000..75a2c72c --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_low_pct @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=655 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=1014000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_low_time b/testcases/027-battery-quartiles/BAT0_uevent_low_time new file mode 100644 index 00000000..76273a2e --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_low_time @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=30 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=7600000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_quarter_pct b/testcases/027-battery-quartiles/BAT0_uevent_quarter_pct new file mode 100644 index 00000000..7fe6632f --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_quarter_pct @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=655 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=1950000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_quarter_time b/testcases/027-battery-quartiles/BAT0_uevent_quarter_time new file mode 100644 index 00000000..91534b9a --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_quarter_time @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=45 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=7600000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_three_quarters_pct b/testcases/027-battery-quartiles/BAT0_uevent_three_quarters_pct new file mode 100644 index 00000000..f17851d8 --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_three_quarters_pct @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=655 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=5850000 diff --git a/testcases/027-battery-quartiles/BAT0_uevent_three_quarters_time b/testcases/027-battery-quartiles/BAT0_uevent_three_quarters_time new file mode 100644 index 00000000..60bd12ce --- /dev/null +++ b/testcases/027-battery-quartiles/BAT0_uevent_three_quarters_time @@ -0,0 +1,4 @@ +POWER_SUPPLY_STATUS=Discharging +POWER_SUPPLY_TIME_TO_EMPTY_NOW=75 +POWER_SUPPLY_CHARGE_FULL_DESIGN=7800000 +POWER_SUPPLY_CHARGE_NOW=7600000 diff --git a/testcases/027-battery-quartiles/expected_output.txt b/testcases/027-battery-quartiles/expected_output.txt new file mode 100644 index 00000000..e77010e9 --- /dev/null +++ b/testcases/027-battery-quartiles/expected_output.txt @@ -0,0 +1 @@ +L 13.00% 10:55 | Q 25.00% 10:55 | H 50.00% 10:55 | T 75.00% 10:55 | L 97.44% 00:30 | Q 97.44% 00:45 | H 97.44% 01:00 | T 97.44% 01:15 | BAT 97.44% 10:55 diff --git a/testcases/027-battery-quartiles/i3status.conf b/testcases/027-battery-quartiles/i3status.conf new file mode 100644 index 00000000..63e71e77 --- /dev/null +++ b/testcases/027-battery-quartiles/i3status.conf @@ -0,0 +1,94 @@ +general { + output_format = "none" +} + +order += "battery 0" +order += "battery 1" +order += "battery 2" +order += "battery 3" +order += "battery 4" +order += "battery 5" +order += "battery 6" +order += "battery 7" +order += "battery 8" + +battery 0 { + format = "%status %percentage %remaining" + status_bat_low = "L" + low_threshold = 15 + threshold_type = "percentage" + path = "testcases/027-battery-quartiles/BAT0_uevent_low_pct" +} + +battery 1 { + format = "%status %percentage %remaining" + status_bat_quarter = "Q" + low_threshold = 0 + quarter_threshold = 35 + threshold_type = "percentage" + path = "testcases/027-battery-quartiles/BAT0_uevent_quarter_pct" +} + +battery 2 { + format = "%status %percentage %remaining" + status_bat_half = "H" + low_threshold = 0 + quarter_threshold = 0 + half_threshold = 65 + threshold_type = "percentage" + path = "testcases/027-battery-quartiles/BAT0_uevent_half_pct" +} + +battery 3 { + format = "%status %percentage %remaining" + status_bat_three_quarters = "T" + low_threshold = 0 + quarter_threshold = 0 + half_threshold = 0 + three_quarters_threshold = 85 + threshold_type = "percentage" + path = "testcases/027-battery-quartiles/BAT0_uevent_three_quarters_pct" +} + +battery 4 { + format = "%status %percentage %remaining" + status_bat_low = "L" + low_threshold = 30 + threshold_type = "time" + path = "testcases/027-battery-quartiles/BAT0_uevent_low_time" +} + +battery 5 { + format = "%status %percentage %remaining" + status_bat_quarter = "Q" + low_threshold = 0 + quarter_threshold = 45 + threshold_type = "time" + path = "testcases/027-battery-quartiles/BAT0_uevent_quarter_time" +} + +battery 6 { + format = "%status %percentage %remaining" + status_bat_half = "H" + low_threshold = 0 + quarter_threshold = 0 + half_threshold = 60 + threshold_type = "time" + path = "testcases/027-battery-quartiles/BAT0_uevent_half_time" +} + +battery 7 { + format = "%status %percentage %remaining" + status_bat_three_quarters = "T" + low_threshold = 0 + quarter_threshold = 0 + half_threshold = 0 + three_quarters_threshold = 75 + threshold_type = "time" + path = "testcases/027-battery-quartiles/BAT0_uevent_three_quarters_time" +} + +battery 8 { + format = "%status %percentage %remaining" + path = "testcases/027-battery-quartiles/BAT0_uevent" +}