#pragma once
#include <cstdio>
#include <format>
#include <fstream>
#include <string>
#include <thread>
#include <unistd.h>
#include <wait.h>
#include "Functional.h"
#include "Fork.h"
class ChargeCheckVars {
public:
int critical_level;
int low_level;
int full_level;
unsigned short charge;
bool is_charging;
bool is_full;
bool cnotified, lnotified, inotified, snotified;
bool stop;
ChargeCheckVars(int critical, int low, int full, bool charge_status) {
low_level = low;
critical_level = critical;
full_level = full;
snotified = charge_status;
}
};
// updated code to run on c++ standards.
class ChargeCheck {
public:
static inline ChargeCheckVars *variables;
static int get_charge() {
std::ifstream ifs("/sys/class/power_supply/BATT/capacity");
char data[3];
ifs >> data;
auto ret = std::stoi(std::string(data));
variables->charge = ret;
return ret;
}
static std::string is_charging() {
std::ifstream ifs("/sys/class/power_supply/BATT/status");
char data[14];
ifs >> data;
auto res = std::string(data);
res = res.substr(0, res.find("ing") + 3);
variables->is_charging = res == "Charging";
return {data};
}
static bool is_charging_bool() {
std::ifstream ifs("/sys/class/power_supply/BATT/status");
char data[14];
ifs >> data;
auto res = std::string(data);
res = res.substr(0, res.find("ing") + 3);
return res == "Charging";
}
static void if_critical(bool is_critical) {
if(is_critical && !variables->cnotified) {
send_notify("Critical Battery Level", "You have to plug your charger.");
variables->cnotified = true;
}
}
static void if_low(bool is_low) {
if(is_low && !variables->lnotified) {
send_notify("Low Battery Level", "Please plug your computer to the charger.");
variables->lnotified = true;
}
}
static void if_full() {
if(variables->is_full && !variables->inotified) {
std::string text = "Charge is " + std::to_string(variables->charge) + ", you can unplug your computer.";
send_notify("Battery reached the full threshold", text.c_str());
variables->inotified = true;
}
}
static void send_notify_wrap(const std::string& title, const std::string& message) {
execlp("notify-send", "notify-send", title.c_str(), message.c_str(), NULL);
}
static void send_notify(const std::string& title, const std::string& message) {
Fork{}.Invoke(FunctionWrapper<void, const std::string&, const std::string&>(send_notify_wrap, title, message));
}
static void update() {
while(!variables->stop) {
using namespace std::chrono_literals;
variables->is_full = variables->charge >= variables->full_level;
if_critical(get_charge() <= variables->critical_level);
variables->cnotified = !(variables->charge > variables->critical_level);
if_low(get_charge() <= variables->low_level);
variables->lnotified = !(variables->charge > variables->low_level);
if_full();
variables->is_full = !(variables->charge < variables->full_level);
is_charging();
if(variables->snotified != variables->is_charging) {
send_notify("Charging status changed", std::format("Your battery is {} now.", (variables->is_charging ? "charging" : "discharging")));
variables->snotified = variables->is_charging;
}
std::this_thread::sleep_for(1000ms);
}
}
};