From 4a6a36f08f5133587826f6ed212826b7b1eb89a8 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Tue, 31 May 2016 02:52:18 +0200 Subject: [PATCH] fix(battery): Poll capacity level Some distros doesn't report any inotify event's for the filesystem where the battery capacity file is located. Resort to polling for now... --- CMakeLists.txt | 2 -- README.md | 3 ++ include/config.hpp.cmake | 1 - include/modules/battery.hpp | 4 ++- src/modules/battery.cpp | 59 +++++++++++++++++++++---------------- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0df7d459..1b50abd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,8 +57,6 @@ set(SETTING_PATH_BACKLIGHT_VAL "/sys/class/backlight/%card%/brightness" CACHE STRING "Path to file containing the current backlight value") set(SETTING_PATH_BACKLIGHT_MAX "/sys/class/backlight/%card%/max_brightness" CACHE STRING "Path to file containing the maximum backlight value") -set(SETTING_PATH_BATTERY_WATCH "/sys/class/power_supply/%battery%/charge_now" - CACHE STRING "Path to attach inotify watch to") set(SETTING_PATH_BATTERY_CAPACITY "/sys/class/power_supply/%battery%/capacity" CACHE STRING "Path to file containing the current battery capacity") set(SETTING_PATH_ADAPTER_STATUS "/sys/class/power_supply/%adapter%/online" diff --git a/README.md b/README.md index 15d9f8e0..5178783a 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,9 @@ the resulting output might not be award-winning. ; $ ls -1 /sys/class/power_supply/ ;battery = BAT0 ;adapter = ADP1 + + ; Seconds between reading battery capacity + ;poll_interval = 3 ~~~ ##### Extra formatting (example) diff --git a/include/config.hpp.cmake b/include/config.hpp.cmake index ac491de6..ffdc9caa 100644 --- a/include/config.hpp.cmake +++ b/include/config.hpp.cmake @@ -16,7 +16,6 @@ #define CONNECTION_TEST_IP "@SETTING_CONNECTION_TEST_IP@" #define PATH_BACKLIGHT_VAL "@SETTING_PATH_BACKLIGHT_VAL@" #define PATH_BACKLIGHT_MAX "@SETTING_PATH_BACKLIGHT_MAX@" -#define PATH_BATTERY_WATCH "@SETTING_PATH_BATTERY_WATCH@" #define PATH_BATTERY_CAPACITY "@SETTING_PATH_BATTERY_CAPACITY@" #define PATH_ADAPTER_STATUS "@SETTING_PATH_ADAPTER_STATUS@" #define BSPWM_SOCKET_PATH "@SETTING_BSPWM_SOCKET_PATH@" diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp index 04c45187..5d3fedd7 100644 --- a/include/modules/battery.hpp +++ b/include/modules/battery.hpp @@ -47,11 +47,13 @@ namespace modules concurrency::Atomic percentage; int full_at; - void animation_thread_runner(); + void subthread_runner(); public: BatteryModule(const std::string& name); + void start(); + bool on_event(InotifyEvent *event); std::string get_format(); bool build(Builder *builder, const std::string& tag); diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index ce27e3e8..cf6a3821 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -55,40 +55,45 @@ BatteryModule::BatteryModule(const std::string& name_) : InotifyModule(name_) this->watch(string::replace(PATH_BATTERY_CAPACITY, "%battery%", this->battery), InotifyEvent::ACCESSED); this->watch(string::replace(PATH_ADAPTER_STATUS, "%adapter%", this->adapter), InotifyEvent::ACCESSED); - - if (this->animation_charging) - this->threads.emplace_back(std::thread(&BatteryModule::animation_thread_runner, this)); } -void BatteryModule::animation_thread_runner() +void BatteryModule::start() +{ + this->InotifyModule::start(); + this->threads.emplace_back(std::thread(&BatteryModule::subthread_runner, this)); +} + +void BatteryModule::subthread_runner() { std::this_thread::yield(); const auto dur = std::chrono::duration( - float(this->animation_charging->get_framerate()) / 1000.0f); + float(this->animation_charging->get_framerate()) / 1000.0f); - int retries = 5; + int i = 0; + const int poll_seconds = config::get(name(), "poll_interval", 3.0f) / dur.count(); - while (retries-- > 0) - { - while (this->enabled()) { - std::unique_lock lck(this->broadcast_lock); + while (this->enabled()) { + std::unique_lock lck(this->broadcast_lock); - if (retries > 0) - retries = 0; - - if (this->state == STATE_CHARGING) { - lck.unlock(); - this->broadcast(); - } else { - log_trace("state != charging"); - } - - std::this_thread::sleep_for(dur); + // TODO(jaagr): Keep track of when the values were last read to determine + // if we need to trigger the event manually or not. + if ((++i % poll_seconds) == 0) { + // Trigger an inotify event in case the underlying filesystem doesn't + log_debug("Poll battery capacity"); + io::file::get_contents("/sys/class/power_supply/BAT0/capacity"); + i = 0; } - std::this_thread::sleep_for(500ms); + if (this->state == STATE_CHARGING) { + lck.unlock(); + this->broadcast(); + } + + std::this_thread::sleep_for(dur); } + + log_debug("Reached end of battery subthread"); } bool BatteryModule::on_event(InotifyEvent *event) @@ -121,11 +126,13 @@ bool BatteryModule::on_event(InotifyEvent *event) case '1': state = STATE_CHARGING; break; } - if ((state == STATE_CHARGING) && percentage >= this->full_at) - percentage = 100; + if (state == STATE_CHARGING) { + if (percentage >= this->full_at) + percentage = 100; - if (percentage == 100) - state = STATE_FULL; + if (percentage == 100) + state = STATE_FULL; + } if (!this->label_charging_tokenized) this->label_charging_tokenized = this->label_charging->clone();