make it a class
This commit is contained in:
61
src/app.cpp
61
src/app.cpp
@@ -15,13 +15,12 @@
|
||||
#include <utils.hpp>
|
||||
#include <vector>
|
||||
|
||||
// std::binary_semaphore Application::Semaphores::main{0};
|
||||
// std::binary_semaphore Application::Semaphores::display{0};
|
||||
Application* Application::s_instance = nullptr;
|
||||
|
||||
void Application::signalHandler(int) {
|
||||
applog(LOG::WRN, "got SIGINT/SIGTERM, exiting...");
|
||||
this->Semaphores::main.release();
|
||||
this->Semaphores::display.release();
|
||||
if (s_instance)
|
||||
s_instance->m_control.quit.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void Application::hassThread(const std::stop_token& st, Sensors& s) {
|
||||
@@ -40,11 +39,11 @@ void Application::hassThread(const std::stop_token& st, Sensors& s) {
|
||||
}
|
||||
|
||||
void Application::sensorsThread(const std::stop_token& st, Sensors& s) {
|
||||
applog(LOG::START, "Thread started, poll interval {} ms", lcd_interval_ms);
|
||||
cpu::detectHwmon(&s.cpu, cpu_pciaddr);
|
||||
gpu::detectHwmon(&s.gpu, gpu_pciaddr);
|
||||
sys::detectHwmon(&s.sys, sys_sensor);
|
||||
s.home.mountpoint = home_dir;
|
||||
applog(LOG::START, "Thread started, poll interval {} ms", m_config.lcd_interval_ms);
|
||||
cpu::detectHwmon(&s.cpu, m_config.cpu_pciaddr);
|
||||
gpu::detectHwmon(&s.gpu, m_config.gpu_pciaddr);
|
||||
sys::detectHwmon(&s.sys, m_config.sys_sensor);
|
||||
s.home.mountpoint = m_config.home_dir;
|
||||
|
||||
while (!st.stop_requested()) {
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
@@ -55,25 +54,27 @@ void Application::sensorsThread(const std::stop_token& st, Sensors& s) {
|
||||
getloadavg(s.avg, 3);
|
||||
sys::getRam(&s.ram);
|
||||
sys::getDisk(&s.home);
|
||||
sys::getNetwork(&s.net, sys_ifname);
|
||||
sys::getNetwork(&s.net, m_config.sys_ifname);
|
||||
sys::updateSensors(&s.sys);
|
||||
cpu::update(&s.cpu);
|
||||
gpu::update(&s.gpu);
|
||||
}
|
||||
|
||||
// log(LOG::DBG, "took {} microseconds", std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count());
|
||||
this->Semaphores::display.release(); // unlocks display loop
|
||||
std::this_thread::sleep_until(start + std::chrono::milliseconds(lcd_interval_ms));
|
||||
m_control.display.release(); // unlocks display loop
|
||||
std::this_thread::sleep_until(start + std::chrono::milliseconds(m_config.lcd_interval_ms));
|
||||
}
|
||||
applog(LOG::INF, "Stopped thread");
|
||||
}
|
||||
|
||||
void Application::displayThread(const std::stop_token& st, Sensors& s) {
|
||||
std::stop_callback cb(st, [&] { m_control.display.release(); });
|
||||
applog(LOG::START, "Thread started");
|
||||
// init internal variables of LCDDisplay class
|
||||
LCDDisplay lcd(lcd_port);
|
||||
LCDDisplay lcd(m_config.lcd_port);
|
||||
|
||||
// basic lcd setup
|
||||
lcd.setContrast(lcd_contrast);
|
||||
lcd.setContrast(m_config.lcd_contrast);
|
||||
lcd.setBacklight(true);
|
||||
lcd.setCustomChar(0, {16, 6, 9, 8, 8, 9, 6, 0}); // celcius
|
||||
lcd.setCustomChar(1, {0, 0, 4, 10, 10, 17, 31, 0}); // delta
|
||||
@@ -88,7 +89,8 @@ void Application::displayThread(const std::stop_token& st, Sensors& s) {
|
||||
|
||||
// actual main display loop
|
||||
while (!st.stop_requested()) {
|
||||
this->Semaphores::display.acquire(); // holds the loop until sensor data is ready
|
||||
m_control.display.try_acquire_for(std::chrono::milliseconds(static_cast<int>(m_config.lcd_interval_ms * 1.25))); // holds the loop until sensor data is ready, max 1.25x of the loop time
|
||||
if (st.stop_requested()) break; // needed, otherwise it wont quit correctly
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s.mtx);
|
||||
|
||||
@@ -137,26 +139,37 @@ void Application::displayThread(const std::stop_token& st, Sensors& s) {
|
||||
lcd.flushBuf();
|
||||
}
|
||||
|
||||
Application::Application(const std::string& display_port) {
|
||||
this->lcd_port = display_port;
|
||||
Application::Application(const Config& config) : m_config(config) {
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
applog(LOG::START, "Application stopped");
|
||||
}
|
||||
|
||||
void Application::Run() {
|
||||
applog(LOG::START, "Application started");
|
||||
std::signal(SIGINT, signalHandler);
|
||||
std::signal(SIGTERM, signalHandler);
|
||||
s_instance = this;
|
||||
std::signal(SIGINT, &Application::signalHandler);
|
||||
std::signal(SIGTERM, &Application::signalHandler);
|
||||
|
||||
{
|
||||
Sensors sensors;
|
||||
std::vector<std::jthread> threads;
|
||||
|
||||
for (std::function<void(std::stop_token st, Sensors & s)> funcs[] = {displayThread, sensorsThread, hassThread};
|
||||
auto& f : funcs)
|
||||
{
|
||||
std::function<void(std::stop_token, Sensors&)> funcs[] = {
|
||||
[this](const std::stop_token& st, Sensors& s) { displayThread(st, s); },
|
||||
[this](const std::stop_token& st, Sensors& s) { sensorsThread(st, s); },
|
||||
[this](const std::stop_token& st, Sensors& s) { hassThread(st, s); },
|
||||
};
|
||||
|
||||
// start threads in order
|
||||
for (auto& f : funcs) {
|
||||
threads.emplace_back(f, std::ref(sensors)); // params: function, stop_token (implied), pointer to sensor struct
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // start threads with delay so displayThread can quit the app if theres no lcd
|
||||
}
|
||||
|
||||
this->Semaphores::main.acquire();
|
||||
// hold until signal recieved
|
||||
while (!m_control.quit.load(std::memory_order_relaxed))
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // ugly
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user