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...
This commit is contained in:
Michael Carlberg 2016-05-31 02:52:18 +02:00
parent a3229c30a5
commit 4a6a36f08f
5 changed files with 39 additions and 30 deletions

View File

@ -57,8 +57,6 @@ set(SETTING_PATH_BACKLIGHT_VAL "/sys/class/backlight/%card%/brightness"
CACHE STRING "Path to file containing the current backlight value") CACHE STRING "Path to file containing the current backlight value")
set(SETTING_PATH_BACKLIGHT_MAX "/sys/class/backlight/%card%/max_brightness" set(SETTING_PATH_BACKLIGHT_MAX "/sys/class/backlight/%card%/max_brightness"
CACHE STRING "Path to file containing the maximum backlight value") 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" set(SETTING_PATH_BATTERY_CAPACITY "/sys/class/power_supply/%battery%/capacity"
CACHE STRING "Path to file containing the current battery capacity") CACHE STRING "Path to file containing the current battery capacity")
set(SETTING_PATH_ADAPTER_STATUS "/sys/class/power_supply/%adapter%/online" set(SETTING_PATH_ADAPTER_STATUS "/sys/class/power_supply/%adapter%/online"

View File

@ -204,6 +204,9 @@ the resulting output might not be award-winning.
; $ ls -1 /sys/class/power_supply/ ; $ ls -1 /sys/class/power_supply/
;battery = BAT0 ;battery = BAT0
;adapter = ADP1 ;adapter = ADP1
; Seconds between reading battery capacity
;poll_interval = 3
~~~ ~~~
##### Extra formatting (example) ##### Extra formatting (example)

View File

@ -16,7 +16,6 @@
#define CONNECTION_TEST_IP "@SETTING_CONNECTION_TEST_IP@" #define CONNECTION_TEST_IP "@SETTING_CONNECTION_TEST_IP@"
#define PATH_BACKLIGHT_VAL "@SETTING_PATH_BACKLIGHT_VAL@" #define PATH_BACKLIGHT_VAL "@SETTING_PATH_BACKLIGHT_VAL@"
#define PATH_BACKLIGHT_MAX "@SETTING_PATH_BACKLIGHT_MAX@" #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_BATTERY_CAPACITY "@SETTING_PATH_BATTERY_CAPACITY@"
#define PATH_ADAPTER_STATUS "@SETTING_PATH_ADAPTER_STATUS@" #define PATH_ADAPTER_STATUS "@SETTING_PATH_ADAPTER_STATUS@"
#define BSPWM_SOCKET_PATH "@SETTING_BSPWM_SOCKET_PATH@" #define BSPWM_SOCKET_PATH "@SETTING_BSPWM_SOCKET_PATH@"

View File

@ -47,11 +47,13 @@ namespace modules
concurrency::Atomic<int> percentage; concurrency::Atomic<int> percentage;
int full_at; int full_at;
void animation_thread_runner(); void subthread_runner();
public: public:
BatteryModule(const std::string& name); BatteryModule(const std::string& name);
void start();
bool on_event(InotifyEvent *event); bool on_event(InotifyEvent *event);
std::string get_format(); std::string get_format();
bool build(Builder *builder, const std::string& tag); bool build(Builder *builder, const std::string& tag);

View File

@ -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_BATTERY_CAPACITY, "%battery%", this->battery), InotifyEvent::ACCESSED);
this->watch(string::replace(PATH_ADAPTER_STATUS, "%adapter%", this->adapter), 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(); std::this_thread::yield();
const auto dur = std::chrono::duration<double>( const auto dur = std::chrono::duration<double>(
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<float>(name(), "poll_interval", 3.0f) / dur.count();
while (retries-- > 0)
{
while (this->enabled()) { while (this->enabled()) {
std::unique_lock<concurrency::SpinLock> lck(this->broadcast_lock); std::unique_lock<concurrency::SpinLock> lck(this->broadcast_lock);
if (retries > 0) // TODO(jaagr): Keep track of when the values were last read to determine
retries = 0; // 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;
}
if (this->state == STATE_CHARGING) { if (this->state == STATE_CHARGING) {
lck.unlock(); lck.unlock();
this->broadcast(); this->broadcast();
} else {
log_trace("state != charging");
} }
std::this_thread::sleep_for(dur); std::this_thread::sleep_for(dur);
} }
std::this_thread::sleep_for(500ms); log_debug("Reached end of battery subthread");
}
} }
bool BatteryModule::on_event(InotifyEvent *event) bool BatteryModule::on_event(InotifyEvent *event)
@ -121,11 +126,13 @@ bool BatteryModule::on_event(InotifyEvent *event)
case '1': state = STATE_CHARGING; break; case '1': state = STATE_CHARGING; break;
} }
if ((state == STATE_CHARGING) && percentage >= this->full_at) if (state == STATE_CHARGING) {
if (percentage >= this->full_at)
percentage = 100; percentage = 100;
if (percentage == 100) if (percentage == 100)
state = STATE_FULL; state = STATE_FULL;
}
if (!this->label_charging_tokenized) if (!this->label_charging_tokenized)
this->label_charging_tokenized = this->label_charging->clone(); this->label_charging_tokenized = this->label_charging->clone();