From 50b4bf378313e3cc2e82a05afbe5588368d17d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 5 Jun 2020 13:36:10 +0200 Subject: [PATCH 1/3] module/battery: use time_to_empty_now if available --- modules/battery.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/modules/battery.c b/modules/battery.c index 9e2a27b..2a70fa4 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -35,6 +35,7 @@ struct private { long capacity; long energy; long power; + long time_to_empty; }; static void @@ -65,16 +66,24 @@ content(struct module *mod) unsigned long energy = m->state == STATE_CHARGING ? m->energy_full - m->energy : m->energy; - double hours_as_float; - if (m->state == STATE_FULL) - hours_as_float = 0.0; - else if (m->power > 0) - hours_as_float = (double)energy / m->power; - else - hours_as_float = 99.0; + unsigned long hours; + unsigned long minutes; - unsigned long hours = hours_as_float; - unsigned long minutes = (hours_as_float - (double)hours) * 60; + if (m->time_to_empty < 0) { + double hours_as_float; + if (m->state == STATE_FULL) + hours_as_float = 0.0; + else if (m->power > 0) + hours_as_float = (double)energy / m->power; + else + hours_as_float = 99.0; + + hours = hours_as_float; + minutes = (hours_as_float - (double)hours) * 60; + } else { + hours = m->time_to_empty / 60; + minutes = m->time_to_empty % 60; + } char estimate[64]; snprintf(estimate, sizeof(estimate), "%02lu:%02lu", hours, minutes); @@ -212,13 +221,14 @@ err: static void update_status(struct module *mod, int capacity_fd, int energy_fd, int power_fd, - int status_fd) + int status_fd, int time_to_empty_fd) { struct private *m = mod->private; long capacity = readint_from_fd(capacity_fd); - long energy = readint_from_fd(energy_fd); - long power = readint_from_fd(power_fd); + long energy = energy_fd >= 0 ? readint_from_fd(energy_fd) : -1; + long power = power_fd >= 0 ? readint_from_fd(power_fd) : -1; + long time_to_empty = time_to_empty_fd >= 0 ? readint_from_fd(time_to_empty_fd) : -1; const char *status = readline_from_fd(status_fd); enum state state; @@ -243,6 +253,7 @@ update_status(struct module *mod, int capacity_fd, int energy_fd, int power_fd, m->capacity = capacity; m->energy = energy; m->power = power; + m->time_to_empty = time_to_empty; mtx_unlock(&mod->lock); } @@ -265,20 +276,25 @@ run(struct module *mod) int capacity_fd = openat(base_dir_fd, "capacity", O_RDONLY); int energy_fd = openat(base_dir_fd, "energy_now", O_RDONLY); int power_fd = openat(base_dir_fd, "power_now", O_RDONLY); + int time_to_empty_fd = openat(base_dir_fd, "time_to_empty_now", O_RDONLY); struct udev *udev = udev_new(); struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev"); +#if 0 if (status_fd == -1 || capacity_fd == -1 || energy_fd == -1 || power_fd == -1 || udev == NULL || mon == NULL) { goto out; } +#endif + if (status_fd < 0 || capacity_fd < 0 || udev == NULL || mon == NULL) + goto out; udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL); udev_monitor_enable_receiving(mon); - update_status(mod, capacity_fd, energy_fd, power_fd, status_fd); + update_status(mod, capacity_fd, energy_fd, power_fd, status_fd, time_to_empty_fd); bar->refresh(bar); while (true) { @@ -304,7 +320,7 @@ run(struct module *mod) continue; } - update_status(mod, capacity_fd, energy_fd, power_fd, status_fd); + update_status(mod, capacity_fd, energy_fd, power_fd, status_fd, time_to_empty_fd); bar->refresh(bar); } From 1864d68961b65bc807287cb771642162f4918b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 5 Jun 2020 13:44:38 +0200 Subject: [PATCH 2/3] module/battery: don't need 'energy' unless we're estimating time left --- modules/battery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/battery.c b/modules/battery.c index 2a70fa4..9bde2f6 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -63,13 +63,13 @@ content(struct module *mod) m->state == STATE_CHARGING || m->state == STATE_DISCHARGING); - unsigned long energy = m->state == STATE_CHARGING - ? m->energy_full - m->energy : m->energy; - unsigned long hours; unsigned long minutes; if (m->time_to_empty < 0) { + unsigned long energy = m->state == STATE_CHARGING + ? m->energy_full - m->energy : m->energy; + double hours_as_float; if (m->state == STATE_FULL) hours_as_float = 0.0; From 0b1333aa031eb40507e75fc68b5fde281da11e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 5 Jun 2020 13:44:59 +0200 Subject: [PATCH 3/3] module/battery: add support for 'charge_full' and 'charge_full_design' --- modules/battery.c | 84 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/modules/battery.c b/modules/battery.c index 9bde2f6..564d917 100644 --- a/modules/battery.c +++ b/modules/battery.c @@ -30,6 +30,8 @@ struct private { char *model; long energy_full_design; long energy_full; + long charge_full_design; + long charge_full; enum state state; long capacity; @@ -190,26 +192,60 @@ initialize(struct private *m) } } + if (faccessat(base_dir_fd, "energy_full_design", O_RDONLY, 0) == 0 && + faccessat(base_dir_fd, "energy_full", O_RDONLY, 0) == 0) { - int fd = openat(base_dir_fd, "energy_full_design", O_RDONLY); - if (fd == -1) { - LOG_ERRNO("/sys/class/power_supply/%s/energy_full_design", m->battery); - goto err; + { + int fd = openat(base_dir_fd, "energy_full_design", O_RDONLY); + if (fd == -1) { + LOG_ERRNO("/sys/class/power_supply/%s/energy_full_design", m->battery); + goto err; + } + + m->energy_full_design = readint_from_fd(fd); + close(fd); } - m->energy_full_design = readint_from_fd(fd); - close(fd); + { + int fd = openat(base_dir_fd, "energy_full", O_RDONLY); + if (fd == -1) { + LOG_ERRNO("/sys/class/power_supply/%s/energy_full", m->battery); + goto err; + } + + m->energy_full = readint_from_fd(fd); + close(fd); + } + } else { + m->energy_full = m->energy_full_design = -1; } + if (faccessat(base_dir_fd, "charge_full_design", O_RDONLY, 0) == 0 && + faccessat(base_dir_fd, "charge_full", O_RDONLY, 0) == 0) { - int fd = openat(base_dir_fd, "energy_full", O_RDONLY); - if (fd == -1) { - LOG_ERRNO("/sys/class/power_supply/%s/energy_full", m->battery); - goto err; + { + int fd = openat(base_dir_fd, "charge_full_design", O_RDONLY); + if (fd == -1) { + LOG_ERRNO("/sys/class/power_supply/%s/charge_full_design", m->battery); + goto err; + } + + m->charge_full_design = readint_from_fd(fd); + close(fd); } - m->energy_full = readint_from_fd(fd); - close(fd); + { + int fd = openat(base_dir_fd, "charge_full", O_RDONLY); + if (fd == -1) { + LOG_ERRNO("/sys/class/power_supply/%s/charge_full", m->battery); + goto err; + } + + m->charge_full = readint_from_fd(fd); + close(fd); + } + } else { + m->charge_full = m->charge_full_design = -1; } return base_dir_fd; @@ -246,7 +282,8 @@ update_status(struct module *mod, int capacity_fd, int energy_fd, int power_fd, state = STATE_DISCHARGING; } - LOG_DBG("capacity: %ld, energy: %ld, power: %ld", capacity, energy, power); + LOG_DBG("capacity: %ld, energy: %ld, power: %ld, time-to-empty: %ld", + capacity, energy, power, time_to_empty); mtx_lock(&mod->lock); m->state = state; @@ -269,7 +306,11 @@ run(struct module *mod) LOG_INFO("%s: %s %s (at %.1f%% of original capacity)", m->battery, m->manufacturer, m->model, - 100.0 * m->energy_full / m->energy_full_design); + (m->energy_full > 0 + ? 100.0 * m->energy_full / m->energy_full_design + : m->charge_full > 0 + ? 100.0 * m->charge_full / m->charge_full_design + : 0.0)); int ret = 1; int status_fd = openat(base_dir_fd, "status", O_RDONLY); @@ -281,20 +322,14 @@ run(struct module *mod) struct udev *udev = udev_new(); struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev"); -#if 0 - if (status_fd == -1 || capacity_fd == -1 || energy_fd == -1 || - power_fd == -1 || udev == NULL || mon == NULL) - { - goto out; - } -#endif if (status_fd < 0 || capacity_fd < 0 || udev == NULL || mon == NULL) goto out; udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL); udev_monitor_enable_receiving(mon); - update_status(mod, capacity_fd, energy_fd, power_fd, status_fd, time_to_empty_fd); + update_status(mod, capacity_fd, energy_fd, power_fd, status_fd, + time_to_empty_fd); bar->refresh(bar); while (true) { @@ -320,7 +355,8 @@ run(struct module *mod) continue; } - update_status(mod, capacity_fd, energy_fd, power_fd, status_fd, time_to_empty_fd); + update_status(mod, capacity_fd, energy_fd, power_fd, status_fd, + time_to_empty_fd); bar->refresh(bar); } @@ -338,6 +374,8 @@ out: close(capacity_fd); if (status_fd != -1) close(status_fd); + if (time_to_empty_fd != -1) + close(time_to_empty_fd); close(base_dir_fd); return ret;