test: no longer daemon + added 0% alert every 5 sec, bat status is back

This commit is contained in:
devaine 2025-08-04 13:00:42 -05:00
commit a7967a86d7
Signed by untrusted user who does not match committer: devaine
GPG key ID: 954B1DCAC6FF84EE
3 changed files with 64 additions and 48 deletions

Binary file not shown.

View file

@ -1,13 +1,21 @@
#include <atomic>
#include <chrono>
#include <csignal>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sched.h> // pid_t data type #include <sched.h> // pid_t data type
#include <sys/select.h> #include <sys/select.h>
#include <thread>
#include <unistd.h> // For fork(); #include <unistd.h> // For fork();
using namespace std; using namespace std;
// atomic type => ensure that variable can be safely accessed and modified.
// // 1 = Suddenly at 0%, 0 = Not at 0%
atomic<int> BAT_EMPTY(0);
// If another instance of this program is running... // If another instance of this program is running...
const char *lockFilePath = "/tmp/bat-daemon-run"; const char *lockFilePath = "/tmp/bat-daemon-run";
@ -26,6 +34,17 @@ void createLockFile() {
// Removes file. // Removes file.
void removeLockFile() { remove(lockFilePath); } void removeLockFile() { remove(lockFilePath); }
void send_notifs_empty() {
string command = "notify-send 'Low Battery' 'ALERT! 0% Battery Remaining.' "
"-u critical -i 'battery-caution' -t 5000";
// If battery is empty...
while (BAT_EMPTY.load() == 1) {
system(command.c_str());
this_thread::sleep_for(chrono::seconds(5));
}
}
void send_notifs_warn(const int &percent) { void send_notifs_warn(const int &percent) {
// Formulate command // Formulate command
string command = string command =
@ -62,41 +81,14 @@ void send_notifs_full() {
system(command.c_str()); system(command.c_str());
} }
// Turn program into a daemon.
void daemonize() {
pid_t pid = fork();
// if forking fails, exit.
if (pid < 0) {
exit(EXIT_FAILURE);
}
if (pid > 0) {
exit(EXIT_SUCCESS);
}
// New session: if fails, exit.
// - New process becomes the leader
if (setsid() < 0) {
exit(EXIT_FAILURE);
}
// Change directory to root
chdir("/");
// Redirects all streams to /dev/null
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
}
// Checks battery info. (Charging, Discharging, etc.) // Checks battery info. (Charging, Discharging, etc.)
void battery() { void battery() {
int OLD_BAT_PERCENT = 100; // Maxing out to prevent bugs int OLD_BAT_PERCENT = 100; // Maxing out to prevent bugs
int CHARGE = 0; // 1 = Charging, 0 = Discharging int CHARGE = 0; // 1 = Charging, 0 = Discharging
int BAT_FULL = 0; // 1 = Full, 0 = Not Full int BAT_FULL = 0; // 1 = Full, 0 = Not Full
while (true) { while (true) {
int BAT_WARN = 36; int BAT_WARN = 35;
// Read and Grab File Info: // Read and Grab File Info:
// ifstream (input file stream) class: operates on files (I/O) // ifstream (input file stream) class: operates on files (I/O)
@ -120,35 +112,45 @@ void battery() {
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 100000; tv.tv_usec = 100000;
if (BAT_PERCENT <= BAT_WARN) { // If the actual battery is charging, update all values
if ((BAT_PERCENT < OLD_BAT_PERCENT) && (BAT_STATUS == "Discharging")) {
CHARGE = 0;
OLD_BAT_PERCENT = BAT_PERCENT;
send_notifs_warn(BAT_PERCENT);
}
}
if (BAT_STATUS == "Charging") { if (BAT_STATUS == "Charging") {
if ((BAT_PERCENT < 99) && (CHARGE == 0)) { if (BAT_PERCENT < 99 && CHARGE == 0) {
CHARGE = 1; CHARGE = 1;
OLD_BAT_PERCENT = BAT_PERCENT; OLD_BAT_PERCENT = BAT_PERCENT;
BAT_FULL = 0; BAT_FULL = 0;
send_notifs_charge(BAT_PERCENT, CHARGE); send_notifs_charge(BAT_PERCENT, CHARGE);
}
if (BAT_PERCENT >= 99 && BAT_FULL == 0) { } else if (BAT_PERCENT >= 99 && BAT_FULL == 0) {
BAT_FULL = 1; BAT_FULL = 1;
CHARGE = 1; CHARGE = 1;
send_notifs_full(); send_notifs_full();
} else if (BAT_PERCENT > OLD_BAT_PERCENT) {
OLD_BAT_PERCENT = BAT_PERCENT;
}
if (BAT_EMPTY == 1) {
BAT_EMPTY.store(0);
} }
} }
if (BAT_STATUS == "Discharging" && CHARGE == 1) { // If the actual battery is discharging, update all values
CHARGE = 0; if (BAT_STATUS == "Discharging") {
send_notifs_charge(BAT_PERCENT, CHARGE); if (CHARGE == 1) {
CHARGE = 0;
send_notifs_charge(BAT_PERCENT, CHARGE);
if (BAT_PERCENT < 99) { } else if (BAT_PERCENT < 99 && BAT_FULL == 1) {
BAT_FULL = 0; BAT_FULL = 0;
} else if (BAT_PERCENT <= BAT_WARN && BAT_PERCENT < OLD_BAT_PERCENT) {
OLD_BAT_PERCENT = BAT_PERCENT;
send_notifs_warn(BAT_PERCENT);
}
// Change value of BAT_EMPTY (alert notification)
if (BAT_PERCENT == 0 && BAT_EMPTY == 0) {
BAT_EMPTY.store(1);
} }
} }
@ -158,16 +160,30 @@ void battery() {
// Initializer // Initializer
int main() { int main() {
// Change directory to root
chdir("/");
// Redirects all streams to /dev/null
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
if (isRunning()) { if (isRunning()) {
cout << "Another process already exists!" << endl; ifstream lockFile(lockFilePath);
return 1; int pid;
lockFile >> pid;
removeLockFile();
kill(pid, 1);
} }
createLockFile(); createLockFile();
daemonize();
battery(); battery();
removeLockFile(); thread background(send_notifs_empty);
return 0; return 0;
} }