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")
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"

View File

@ -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)

View File

@ -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@"

View File

@ -47,11 +47,13 @@ namespace modules
concurrency::Atomic<int> 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);

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_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<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()) {
std::unique_lock<concurrency::SpinLock> lck(this->broadcast_lock);
while (this->enabled()) {
std::unique_lock<concurrency::SpinLock> 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();