mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Introduce Event Services (#1653)
* Allow to enable/disable suspend & lock event handling * Fix Windows * Refactor event handling incl.CEC * Revert "Auxiliary commit to revert individual files from 0d9a8b8a3a4a09609a339f54c7d8a9384c561282" This reverts commit 80737d926ad151a07b2493dd1685ed502975cb2e. * Support Events for Grabbers generically * Have CECEvent to actions configurable, further clean-ups * Remove handleEvent from V4L2grabber, as grabber will be stopped on suspend * Validate that one CEC Event can only trigger one action * MacOS lock/unlock added * fast windows fix * Corrections * Fix CodeQL findings * add macos lock/unlock handler * Migration of CEC-config and have default actions * Correct target_link_libraries * Include Foundation * macOS include AppKit * Support Scheduled Events, cleanups. * Fix destructing * Fix coredump during free * Consider additional error sceanrio * Fix missing code * install desktop icons * correct bash logic --------- Co-authored-by: Paulchen-Panther <16664240+Paulchen-Panther@users.noreply.github.com>
This commit is contained in:
153
libsrc/events/EventScheduler.cpp
Normal file
153
libsrc/events/EventScheduler.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include "events/EventScheduler.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <events/EventHandler.h>
|
||||
#include <utils/Logger.h>
|
||||
|
||||
EventScheduler::EventScheduler()
|
||||
: _isEnabled(false)
|
||||
{
|
||||
qRegisterMetaType<Event>("Event");
|
||||
_log = Logger::getInstance("EVENTS-SCHED");
|
||||
|
||||
QObject::connect(this, &EventScheduler::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
|
||||
}
|
||||
|
||||
EventScheduler::~EventScheduler()
|
||||
{
|
||||
QObject::disconnect(this, &EventScheduler::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
|
||||
clearTimers();
|
||||
Info(_log, "Event scheduler stopped");
|
||||
}
|
||||
|
||||
void EventScheduler::handleSettingsUpdate(settings::type type, const QJsonDocument& config)
|
||||
{
|
||||
if(type == settings::SCHEDEVENTS)
|
||||
{
|
||||
const QJsonObject& obj = config.object();
|
||||
|
||||
_isEnabled = obj["enable"].toBool(false);
|
||||
Debug(_log, "Event scheduler is %s", _isEnabled? "enabled" : "disabled");
|
||||
|
||||
if (_isEnabled)
|
||||
{
|
||||
_scheduledEvents.clear();
|
||||
|
||||
const QJsonArray actionItems = obj["actions"].toArray();
|
||||
if (!actionItems.isEmpty())
|
||||
{
|
||||
timeEvent timeEvent;
|
||||
for (const QJsonValue &item : actionItems)
|
||||
{
|
||||
QString action = item.toObject().value("action").toString();
|
||||
timeEvent.action = stringToEvent(action);
|
||||
|
||||
QString event = item.toObject().value("event").toString();
|
||||
timeEvent.time = QTime::fromString(event,"hh:mm");
|
||||
if (timeEvent.time.isValid())
|
||||
{
|
||||
_scheduledEvents.append(timeEvent);
|
||||
Debug(_log, "Time-Event : \"%s\" linked to action \"%s\"", QSTRING_CSTR(event), QSTRING_CSTR(action));
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Error in configured time : \"%s\" linked to action \"%s\"", QSTRING_CSTR(event), QSTRING_CSTR(action));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_scheduledEvents.isEmpty())
|
||||
{
|
||||
enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(_log, "No scheduled events to listen to are configured currently.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
disable();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool EventScheduler::enable()
|
||||
{
|
||||
bool enabled {false};
|
||||
|
||||
clearTimers();
|
||||
for (int i = 0; i < _scheduledEvents.size(); ++i)
|
||||
{
|
||||
QTimer* timer = new QTimer(this);
|
||||
timer->setTimerType(Qt::PreciseTimer);
|
||||
_timers.append(timer);
|
||||
|
||||
// Calculate the milliseconds until the next occurrence of the scheduled time
|
||||
int milliseconds = getMillisecondsToNextScheduledTime(_scheduledEvents.at(i).time);
|
||||
timer->start(milliseconds);
|
||||
|
||||
QObject::connect(timer, &QTimer::timeout, this, [this, i]() { handleEvent(i); });
|
||||
}
|
||||
|
||||
enabled = true;
|
||||
Info(_log, "Event scheduler started");
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void EventScheduler::disable()
|
||||
{
|
||||
Info(_log, "Disabling event scheduler");
|
||||
clearTimers();
|
||||
}
|
||||
|
||||
void EventScheduler::clearTimers()
|
||||
{
|
||||
for (QTimer *timer : std::as_const(_timers)) {
|
||||
timer->disconnect();
|
||||
timer->stop();
|
||||
delete timer;
|
||||
}
|
||||
_timers.clear();
|
||||
}
|
||||
|
||||
void EventScheduler::handleEvent(int timerIndex)
|
||||
{
|
||||
QTime time = _scheduledEvents.at(timerIndex).time;
|
||||
Event action = _scheduledEvents.at(timerIndex).action;
|
||||
Debug(_log, "Event : \"%s\" triggers action \"%s\"", QSTRING_CSTR(time.toString()), eventToString(action) );
|
||||
if ( action != Event::Unknown )
|
||||
{
|
||||
emit signalEvent(action);
|
||||
}
|
||||
|
||||
// Retrigger the timer for the next occurrence
|
||||
QTimer* timer = _timers.at(timerIndex);
|
||||
int milliseconds = getMillisecondsToNextScheduledTime(time);
|
||||
timer->start(milliseconds);
|
||||
}
|
||||
|
||||
int EventScheduler::getMillisecondsToNextScheduledTime(const QTime& scheduledTime)
|
||||
{
|
||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
QTime currentTime = currentDateTime.time();
|
||||
|
||||
QDateTime nextOccurrence = currentDateTime;
|
||||
nextOccurrence.setTime(scheduledTime);
|
||||
|
||||
// If the scheduled time has already passed for today, schedule it for tomorrow
|
||||
if (currentTime > scheduledTime)
|
||||
{
|
||||
nextOccurrence = nextOccurrence.addDays(1);
|
||||
}
|
||||
|
||||
int milliseconds = currentDateTime.msecsTo(nextOccurrence);
|
||||
return (milliseconds > 0) ? milliseconds : 0;
|
||||
}
|
Reference in New Issue
Block a user