Skip to content

Commit

Permalink
Add Suspend/Resume support (#1535)
Browse files Browse the repository at this point in the history
* Add Suspend/Resume support

* Support Suspend/Resume/Restart via API, UI and Systray

* Support screen lock/unlock scenario

* Handle idle scenario

* Align with fix for #1368

* Update Windows build

* Refactor SuspendHandler to maintain state

* Do not start BG-Effect, if system goes into suspend mode

* Correct Idle and Resume interaction
  • Loading branch information
Lord-Grey authored Dec 22, 2022
1 parent 2217135 commit 1189f86
Show file tree
Hide file tree
Showing 32 changed files with 993 additions and 66 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,16 @@ jobs:
with:
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
key: ${{ runner.os }}-chocolatey

# - name: Install Python
# shell: powershell
# run: |
# choco install --no-progress python -y

- name: Install Python, OpenSSL, DirectX SDK
- name: Install OpenSSL, DirectX SDK
shell: powershell
run: |
choco install --no-progress python openssl directx-sdk -y
choco install --no-progress openssl directx-sdk -y
- name: Install libjpeg-turbo
run: |
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/push-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,15 @@ jobs:
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
key: ${{ runner.os }}-chocolatey

- name: Install Python, OpenSSL, DirectX SDK
# - name: Install Python
# shell: powershell
# run: |
# choco install --no-progress python -y

- name: Install OpenSSL, DirectX SDK
shell: powershell
run: |
choco install --no-progress python openssl directx-sdk -y
choco install --no-progress openssl directx-sdk -y
- name: Install libjpeg-turbo
run: |
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Allow to Disable / Enable all instances (#970) by
- Suspend/Resume support for Linux and Windows (#1493,#1282, #978).
Suspend/Resume/Restart is supported via API, UI, Systray and hyperion-remote
- Idle scenario via Screen Locking (Linux/Windows), Screensaver invokation (Linux), hyperion-remote or API
In Idle, all instances, components will be disabled besides the output processing (LED-Devices, smoothing).
The current priorities will be cleared and the background effect per instance will be executed, if enabled.
- Commands toogleSuspend and toggleIdle allow to flip between modes, e.g. might be used to trigger modes by a remote
- Add instance# in API response (#1504)

### Changed

### Fixed

- Restart correctly, if running as service (#1368)

## Removed

## [2.0.14](https://github.com/hyperion-project/hyperion.ng/releases/tag/2.0.14) - 2022-11
Expand Down
3 changes: 3 additions & 0 deletions assets/webconfig/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"infoDialog_password_current_text": "Current password",
"infoDialog_password_minimum_length": "Passwords must be minimum 8 characters.",
"infoDialog_password_new_text": "New password",
"InfoDialog_systemSuspend_title": "Suspend",
"InfoDialog_systemResume_title": "Resume",
"InfoDialog_systemRestart_title": "Restart",
"infoDialog_username_text": "Username",
"about_3rd_party_licenses": "3rd party licenses",
"about_3rd_party_licenses_error": "We had trouble collecting 3rd party licenses information from web. <br />Please follow this link to the GitHub Resource.",
Expand Down
33 changes: 33 additions & 0 deletions assets/webconfig/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,39 @@ <h3>Hyperion Web Configuration requires Javascript. Please enable Javascript in
</li>
</ul>
</li>
<!-- /.dropdown -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-power-off fa-fw"></i> <i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-alerts">
<li id="btn_systemSuspend">
<a>
<div>
<i class="fa fa-stop fa-fw"></i>
<span data-i18n="InfoDialog_systemSuspend_title"></span>
</div>
</a>
</li>
<li id="btn_systemResume">
<a>
<div>
<i class="fa fa-play fa-fw"></i>
<span data-i18n="InfoDialog_systemResume_title"></span>
</div>
</a>
</li>
<li class="divider"></li>
<li id="btn_systemRestart">
<a>
<div>
<i class="fa fa-refresh fa-fw"></i>
<span data-i18n="InfoDialog_systemRestart_title"></span>
</div>
</a>
</li>
</ul>
</li>

<!-- /.lock-ui -->
<li class="dropdown" id="btn_lock_ui" style="display:none">
Expand Down
15 changes: 15 additions & 0 deletions assets/webconfig/js/hyperion.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,21 @@ function requestSysInfo()
sendToHyperion("sysinfo");
}

function requestSystemSuspend()
{
sendToHyperion("system","suspend");
}

function requestSystemResume()
{
sendToHyperion("system","resume");
}

function requestSystemRestart()
{
sendToHyperion("system","restart");
}

function requestServerConfigSchema()
{
sendToHyperion("config","getschema");
Expand Down
15 changes: 15 additions & 0 deletions assets/webconfig/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ $(document).ready(function () {
changePassword();
});

//Suspend Hyperion
$('#btn_systemSuspend').off().on('click', function () {
requestSystemSuspend();
});

//Resume Hyperion
$('#btn_systemResume').off().on('click', function () {
requestSystemResume();
});

//Restart Hyperion
$('#btn_systemRestart').off().on('click', function () {
requestSystemRestart();
});

//Lock Ui
$('#btn_lock_ui').off().on('click', function () {
removeStorage('loginToken');
Expand Down
26 changes: 26 additions & 0 deletions include/api/JsonAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ private slots:
///
void forwardJsonMessage(QJsonObject);

///
/// Signal emits whenever a suspend/resume request for all instances should be forwarded
///
void suspendAll(bool isSuspend);

///
/// Signal emits whenever a toggle suspend/resume request for all instances should be forwarded
///
void toggleSuspendAll();

///
/// Signal emits whenever a idle mode request for all instances should be forwarded
///
void idleAll(bool isIdle);

///
/// Signal emits whenever a toggle idle/working mode request for all instances should be forwarded
///
void toggleIdleAll();

private:
// true if further callbacks are forbidden (http)
bool _noListener;
Expand Down Expand Up @@ -298,6 +318,12 @@ private slots:
///
void handleServiceCommand(const QJsonObject &message, const QString &command, int tan);

/// Handle an incoming JSON message for actions related to the overall Hyperion system
///
/// @param message the incoming message
///
void handleSystemCommand(const QJsonObject &message, const QString &command, int tan);

///
/// Handle an incoming JSON message of unknown type
///
Expand Down
10 changes: 9 additions & 1 deletion include/hyperion/BGEffectHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class BGEffectHandler : public QObject
, _hyperion(hyperion)
, _prioMuxer(_hyperion->getMuxerInstance())
, _isBgEffectEnabled(false)
, _isSuspended(false)
{
QString subComponent = parent()->property("instance").toString();
_log = Logger::getInstance("HYPERION", subComponent);
Expand All @@ -33,6 +34,11 @@ class BGEffectHandler : public QObject
this->handlePriorityUpdate();
});

// listen for suspend/resume requests, to not start a background effect when system goes into suspend mode
connect(_hyperion, &Hyperion::suspendRequest, this, [=] (bool isSuspended) {
_isSuspended = isSuspended;
});

// initialization
handleSettingsUpdate(settings::BGEFFECT, _hyperion->getSetting(settings::BGEFFECT));
}
Expand Down Expand Up @@ -109,7 +115,7 @@ private slots:
Debug(_log,"Stop background (color-) effect as it moved out of scope");
_hyperion->clear(PriorityMuxer::BG_PRIORITY);
}
else if (_prioMuxer->getCurrentPriority() == PriorityMuxer::LOWEST_PRIORITY && _isBgEffectEnabled)
else if (!_isSuspended && _prioMuxer->getCurrentPriority() == PriorityMuxer::LOWEST_PRIORITY && _isBgEffectEnabled)
{
Debug(_log,"Start background (color-) effect as it moved in scope");
emit handleSettingsUpdate (settings::BGEFFECT, _bgEffectConfig);
Expand All @@ -126,6 +132,8 @@ private slots:

QJsonDocument _bgEffectConfig;
bool _isBgEffectEnabled;

bool _isSuspended;
};

#endif // BGEFFECTHANDLER_H
24 changes: 18 additions & 6 deletions include/hyperion/ComponentRegister.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
#include <map>

#include <QObject>
#include <QVector>

class Hyperion;

typedef QVector<hyperion::Components> ComponentList;

///
/// @brief The component register reflects and manages the current state of all components and Hyperion as a whole
/// It emits also real component state changes (triggert from the specific component), which can be used for listening APIs (Network Clients/Plugins)
/// It emits also real component state changes (triggered from the specific component), which can be used for listening APIs (Network Clients/Plugins)
///
class ComponentRegister : public QObject
{
Expand All @@ -36,23 +39,32 @@ class ComponentRegister : public QObject
///
/// @brief Emits whenever a component changed (really) the state
/// @param comp The component
/// @param state The new state of the component
/// @param isActive The new state of the component
///
void updatedComponentState(hyperion::Components comp, bool state);
void updatedComponentState(hyperion::Components comp, bool isActive);

public slots:
///
/// @brief is called whenever a component change a state, DO NOT CALL FROM API, use signal hyperion->compStateChangeRequest
/// @param comp The component
/// @param state The new state of the component
/// @param isActive The new state of the component
///
void setNewComponentState(hyperion::Components comp, bool activated);
void setNewComponentState(hyperion::Components comp, bool isActive);

private slots:
///
/// @brief Handle COMP_ALL changes from Hyperion->compStateChangeRequest
/// @param comp COMP_ALL
/// @param isActive The new state for all components
///
void handleCompStateChangeRequest(hyperion::Components comps, bool isActive);

///
/// @brief Activate/Deactivate all components, except those provided by the list of excluded components
/// @param isActive The new state for all components
/// @param execludeList of excluded components
///
void handleCompStateChangeRequest(hyperion::Components comps, bool activated);
void handleCompStateChangeRequestAll(bool isActive, const ComponentList& excludeList = ComponentList{});

private:
/// Hyperion instance
Expand Down
26 changes: 26 additions & 0 deletions include/hyperion/Hyperion.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,20 @@ public slots:

int getLatchTime() const;

///
/// @brief Set hyperion in suspend mode or resume from suspend/idle.
/// All instances and components will be disabled/enabled.
/// @param isSupend True, components will be deactivated, else put into their previous state before suspend
///
void setSuspend(bool isSupend);

///
/// @brief Set hyperion in idle /working mode.
/// In idle, all instances and components will be disabled besides the output processing (LED-Devices, smoothing).
/// @param isIdle True, selected components will be deactivated, else put into their previous state before idle
///
void setIdle(bool isIdle);

signals:
/// Signal which is emitted when a priority channel is actively cleared
/// This signal will not be emitted when a priority channel time out
Expand All @@ -406,6 +420,18 @@ public slots:
///
void compStateChangeRequest(hyperion::Components component, bool enabled);

///
/// @brief Emits when all (besides excluded) components are subject to state changes
/// @param isActive The new state for all components
/// @param execlude List of excluded components
void compStateChangeRequestAll(bool isActive, const ComponentList& excludeList = {});

/// Signal which is emitted, when system is to be suspended/resumed
void suspendRequest(bool isSuspend);

/// Signal which is emitted, when system should go into idle/working mode
void idleRequest(bool isIdle);

///
/// @brief Emits whenever the imageToLedsMapping has changed
/// @param mappingType The new mapping type
Expand Down
25 changes: 23 additions & 2 deletions include/hyperion/HyperionIManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,27 @@ public slots:
///
bool stopInstance(quint8 inst);

///
/// @brief Suspend (disable) all Hyperion instances
///
void suspend();

///
/// @brief Resume (resume) all Hyperion instances
///
void resume();

///
/// @brief Toggle the state of all Hyperion instances for an idle sceanrio (user is not interacting with the system
/// @param isIdle, If true all instances toggle to idle, else to resume
///
void toggleIdle(bool isIdle);

///
/// @brief Toggle the state of all Hyperion instances
/// @param pause If true all instances toggle to pause, else to resume
/// @param enable, If false all instances toggle to pause, else to resume
///
void toggleStateAllInstances(bool pause = false);
void toggleStateAllInstances(bool enable = false);

///
/// @brief Create a new Hyperion instance entry in db
Expand Down Expand Up @@ -125,6 +141,11 @@ public slots:
///
void startInstanceResponse(QObject *caller, const int &tan);

void triggerSuspend(bool isSuspend);
void triggerToggleSuspend();
void triggerIdle(bool isIdle);
void triggerToggleIdle();

signals:
///////////////////////////////////////
/// FROM HYPERIONDAEMON TO HYPERION ///
Expand Down
20 changes: 20 additions & 0 deletions libsrc/api/JSONRPC_schema/schema-system.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type":"object",
"required":true,
"properties":{
"command": {
"type" : "string",
"required" : true,
"enum" : ["system"]
},
"tan" : {
"type" : "integer"
},
"subcommand": {
"type" : "string",
"required" : true,
"enum": [ "restart", "resume", "suspend", "toggleSuspend", "idle", "toggleIdle" ]
}
},
"additionalProperties": false
}
2 changes: 1 addition & 1 deletion libsrc/api/JSONRPC_schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"command": {
"type" : "string",
"required" : true,
"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "service", "transform", "correction", "temperature" ]
"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "service", "system", "transform", "correction", "temperature" ]
}
}
}
Loading

0 comments on commit 1189f86

Please sign in to comment.