Skip to content

Commit a1f0821

Browse files
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 0d9a8b8" 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>
1 parent 2e0cc9c commit a1f0821

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2298
-821
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212

1313
- New language: Hebrew
1414

15+
**Event Services**
16+
Newly introduced Event Service configuration and consistent handling across all components
17+
- Suspend/Resume & Screen Locking support for MaxOS
18+
- Allow to enable/disable suspend & lock on operating system events (#1633, #1632)
19+
- Scheduled events allowing to suspend,resume, etc. (#1088)
20+
- Configurable CEC event handling
21+
1522
##### LED-Devices
1623

1724
**Philips Hue**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="container-fluid">
2+
<div class="row">
3+
<div class="col-lg-12">
4+
<h3 class="page-header"><i class="fa fa-server fa-fw"></i><span data-i18n="main_menu_events">Event Services</span></h3>
5+
<div id="conf_cont">
6+
</div>
7+
</div>
8+
</div>
9+
</div>
10+
11+
<script src="/js/content_events.js"></script>

assets/webconfig/i18n/en.json

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@
192192
"conf_network_tok_intro": "Here you can create and delete tokens for API authentication. Created tokens will only be displayed once.",
193193
"conf_network_tok_lastuse": "Last use",
194194
"conf_network_tok_title": "Token Management",
195+
"conf_cec_events_heading_title": "CEC Events",
196+
"conf_cec_events_intro": "Settings related to diffent CEC (Consumer Electronics Control) protocol events Hyperion can handle",
197+
"conf_os_events_heading_title": "Operating System Events",
198+
"conf_os_events_intro": "Settings related to diffent Operating System events Hyperion can handle",
199+
"conf_sched_events_heading_title": "Scheduled Events",
200+
"conf_sched_events_intro": "Settings related to scheduled, i.e. time based events, which Hyperion will handle",
195201
"conf_webconfig_label_intro": "Webconfiguration settings. Edit wisely.",
196202
"dashboard_active_instance": "Selected instance",
197203
"dashboard_alert_message_confedit": "Your Hyperion configuration has been modified. To apply it, restart Hyperion.",
@@ -243,6 +249,30 @@
243249
"edt_append_pixel": "Pixel",
244250
"edt_append_s": "s",
245251
"edt_append_sdegree": "s/degree",
252+
"edt_conf_action_title": "Action",
253+
"edt_conf_action_expl": "Action to be applied",
254+
"edt_conf_action_record_validation_error": "The same event can trigger only one action. Clean up Actions $1",
255+
"edt_conf_audio_device_expl": "Selected audio input device",
256+
"edt_conf_audio_device_title": "Audio Device",
257+
"edt_conf_audio_effects_expl": "Select an effect on how the audio signal is transformed to",
258+
"edt_conf_audio_effects_title": "Audio Effects",
259+
"edt_conf_audio_effect_enum_vumeter": "VU-Meter",
260+
"edt_conf_audio_effect_hotcolor_expl": "Hot Color",
261+
"edt_conf_audio_effect_hotcolor_title": "Hot Color",
262+
"edt_conf_audio_effect_multiplier_expl": "Audio Signal Value multiplier",
263+
"edt_conf_audio_effect_multiplier_title": "Multiplier",
264+
"edt_conf_audio_effect_safecolor_expl": "Safe Color",
265+
"edt_conf_audio_effect_safecolor_title": "Safe Color",
266+
"edt_conf_audio_effect_safevalue_expl": "Safe Threshold",
267+
"edt_conf_audio_effect_safevalue_title": "Safe Threshold",
268+
"edt_conf_audio_effect_set_defaults": "Reset to default values",
269+
"edt_conf_audio_effect_tolerance_expl": "Tolerance used when auto calculating a signal multipler from 0-100",
270+
"edt_conf_audio_effect_tolerance_title": "Tolerance",
271+
"edt_conf_audio_effect_warncolor_expl": "Warning Color",
272+
"edt_conf_audio_effect_warncolor_title": "Warning Color",
273+
"edt_conf_audio_effect_warnvalue_expl": "Warning Threshold",
274+
"edt_conf_audio_effect_warnvalue_title": "Warning Threshold",
275+
"edt_conf_audio_heading_title": "Audio Capture",
246276
"edt_conf_bb_blurRemoveCnt_expl": "Number of pixels that get removed from the detected border to cut away blur.",
247277
"edt_conf_bb_blurRemoveCnt_title": "Blur pixel",
248278
"edt_conf_bb_borderFrameCnt_expl": "Number of frames before a consistent detected border is set.",
@@ -258,6 +288,17 @@
258288
"edt_conf_bb_unknownFrameCnt_title": "Unknown frames",
259289
"edt_conf_bge_heading_title": "Background Effect/Color",
260290
"edt_conf_bobls_heading_title": "Boblight Server",
291+
"edt_conf_cec_actions_header_title": "Actions",
292+
"edt_conf_cec_actions_header_expl": "Define which action should take place on a recognised CEC event",
293+
"edt_conf_cec_actions_header_item_title": "Action",
294+
"edt_conf_cec_button_release_delay_ms_title": "Button release time",
295+
"edt_conf_cec_button_release_delay_ms_expl": "Remote button press release time",
296+
"edt_conf_cec_button_repeat_rate_ms_title": "Button repeat rate",
297+
"edt_conf_cec_button_repeat_rate_ms_expl": "Remote button press repeat rate",
298+
"edt_conf_cec_double_tap_timeout_ms_title": "Button delay before repeating",
299+
"edt_conf_cec_double_tap_timeout_ms_expl": "Remote button press delay before repeating",
300+
"edt_conf_cec_event_title": "CEC Event",
301+
"edt_conf_cec_event_expl": "CEC event that will trigger an action",
261302
"edt_conf_color_accuracyLevel_expl": "Level how accurate dominat colors are evaluated. A higher level creates more accurate results, but also requries more processing power. Should to be combined with reduced pixel processing.",
262303
"edt_conf_color_accuracyLevel_title": "Accuracy level",
263304
"edt_conf_color_backlightColored_expl": "Add some color to your backlight.",
@@ -320,6 +361,13 @@
320361
"edt_conf_enum_HORIZONTAL": "Horizontal",
321362
"edt_conf_enum_VERTICAL": "Vertical",
322363
"edt_conf_enum_BOTH": "Horizontal & Vertical",
364+
"edt_conf_enum_action_idle": "Idle",
365+
"edt_conf_enum_action_restart": "Restart",
366+
"edt_conf_enum_action_resume": "Resume",
367+
"edt_conf_enum_action_resumeIdle": "ResumeIdle",
368+
"edt_conf_enum_action_suspend": "Suspend",
369+
"edt_conf_enum_action_toggleIdle": "ToggleIdle",
370+
"edt_conf_enum_action_toggleSuspend": "ToggleSuspend",
323371
"edt_conf_enum_automatic": "Automatic",
324372
"edt_conf_enum_bbclassic": "Classic",
325373
"edt_conf_enum_bbdefault": "Default",
@@ -328,6 +376,12 @@
328376
"edt_conf_enum_bgr": "BGR",
329377
"edt_conf_enum_bottom_up": "Bottom up",
330378
"edt_conf_enum_brg": "BRG",
379+
"edt_conf_enum_cec_key_f1_blue": "Blue button pressed",
380+
"edt_conf_enum_cec_key_f2_red": "Red button pressed",
381+
"edt_conf_enum_cec_key_f3_green": "Green button pressed",
382+
"edt_conf_enum_cec_key_f4_yellow": "Yellow button pressed",
383+
"edt_conf_enum_cec_opcode_set stream path": "TV on",
384+
"edt_conf_enum_cec_opcode_standby": "TV off",
331385
"edt_conf_enum_color": "Color",
332386
"edt_conf_enum_custom": "Custom",
333387
"edt_conf_enum_decay": "Decay",
@@ -455,9 +509,18 @@
455509
"edt_conf_net_localApiAuth_title": "Local API Authentication",
456510
"edt_conf_net_restirctedInternetAccessAPI_expl": "You can restrict the access to the API through the internet to certain IP's.",
457511
"edt_conf_net_restirctedInternetAccessAPI_title": "Restrict to IP's",
512+
"edt_conf_os_events_lockEnable_title": "Listen to lock events",
513+
"edt_conf_os_events_lockEnable_expl": "Listen to screen lock/unlock events",
514+
"edt_conf_os_events_suspendEnable_title": "Listen to suspend events",
515+
"edt_conf_os_events_suspendEnable_expl": "Listen to operating system suspend/resume events",
516+
"edt_conf_os_events_suspendOnLockEnable_title": "Suspend when locked",
517+
"edt_conf_os_events_suspendOnLockEnable_expl": "Suspend when the screen is locked, otherwise go into idle mode",
458518
"edt_conf_pbs_heading_title": "Protocol Buffers Server",
459519
"edt_conf_pbs_timeout_expl": "If no data are received for the given period, the component will be (soft) disabled.",
460520
"edt_conf_pbs_timeout_title": "Timeout",
521+
"edt_conf_sched_actions_header_title": "Actions",
522+
"edt_conf_sched_actions_header_expl": "Define which action should take place on a point in time. The action will be scheduled daily.",
523+
"edt_conf_sched_actions_header_item_title": "Action",
461524
"edt_conf_smooth_continuousOutput_expl": "Update the LEDs even there is no changed picture.",
462525
"edt_conf_smooth_continuousOutput_title": "Continuous output",
463526
"edt_conf_smooth_decay_expl": "The speed of decay. 1 is linear, greater values are have stronger effect.",
@@ -475,6 +538,8 @@
475538
"edt_conf_smooth_updateDelay_title": "Output delay",
476539
"edt_conf_smooth_updateFrequency_expl": "The output speed to your LED controller.",
477540
"edt_conf_smooth_updateFrequency_title": "Update frequency",
541+
"edt_conf_time_event_title": "Time",
542+
"edt_conf_time_event_expl": "Point in time that will trigger an action",
478543
"edt_conf_v4l2_blueSignalThreshold_expl": "Darkens low blue values (recognized as black)",
479544
"edt_conf_v4l2_blueSignalThreshold_title": "Blue signal threshold",
480545
"edt_conf_v4l2_cecDetection_expl": "If enabled, USB capture will be temporarily disabled when CEC standby event received from HDMI bus.",
@@ -534,27 +599,6 @@
534599
"edt_conf_v4l2_hardware_set_defaults_tip": "Set device's default values for brightness, contrast, hue and saturation",
535600
"edt_conf_v4l2_noSignalCounterThreshold_title": "Signal Counter Threshold",
536601
"edt_conf_v4l2_noSignalCounterThreshold_expl": "Count of frames (check that with grabber's current FPS mode) after which the no signal is triggered",
537-
"edt_conf_audio_device_expl": "Selected audio input device",
538-
"edt_conf_audio_device_title": "Audio Device",
539-
"edt_conf_audio_effects_expl": "Select an effect on how the audio signal is transformed to",
540-
"edt_conf_audio_effects_title": "Audio Effects",
541-
"edt_conf_audio_effect_enum_vumeter": "VU-Meter",
542-
"edt_conf_audio_effect_hotcolor_expl": "Hot Color",
543-
"edt_conf_audio_effect_hotcolor_title": "Hot Color",
544-
"edt_conf_audio_effect_multiplier_expl": "Audio Signal Value multiplier",
545-
"edt_conf_audio_effect_multiplier_title": "Multiplier",
546-
"edt_conf_audio_effect_safecolor_expl": "Safe Color",
547-
"edt_conf_audio_effect_safecolor_title": "Safe Color",
548-
"edt_conf_audio_effect_safevalue_expl": "Safe Threshold",
549-
"edt_conf_audio_effect_safevalue_title": "Safe Threshold",
550-
"edt_conf_audio_effect_set_defaults": "Reset to default values",
551-
"edt_conf_audio_effect_tolerance_expl": "Tolerance used when auto calculating a signal multipler from 0-100",
552-
"edt_conf_audio_effect_tolerance_title": "Tolerance",
553-
"edt_conf_audio_effect_warncolor_expl": "Warning Color",
554-
"edt_conf_audio_effect_warncolor_title": "Warning Color",
555-
"edt_conf_audio_effect_warnvalue_expl": "Warning Threshold",
556-
"edt_conf_audio_effect_warnvalue_title": "Warning Threshold",
557-
"edt_conf_audio_heading_title": "Audio Capture",
558602
"edt_conf_webc_crtPath_expl": "Path to the certification file (format should be PEM)",
559603
"edt_conf_webc_crtPath_title": "Certificate path",
560604
"edt_conf_webc_docroot_expl": "Local webinterface root path (just for webui developer)",
@@ -983,6 +1027,8 @@
9831027
"main_menu_dashboard_token": "Dashboard",
9841028
"main_menu_effect_conf_token": "Effects",
9851029
"main_menu_effectsconfigurator_token": "Effects Configurator",
1030+
"main_menu_events": "Event Services",
1031+
"main_menu_event_services_token": "Event Services",
9861032
"main_menu_general_conf_token": "General",
9871033
"main_menu_grabber_conf_token": "Capturing Hardware",
9881034
"main_menu_input_selection_token": "Input Selection",

assets/webconfig/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ <h3>Hyperion Web Configuration requires Javascript. Please enable Javascript in
280280
<li>
281281
<a class="inactive"><i class="fa fa-industry fa-fw"></i><span data-i18n="main_menu_system_token">System</span><span class="fa arrow"></span></a>
282282
<ul class="nav nav-second-level">
283+
<li> <a class="inactive mnava" id="MenuItemEventServices" href="#conf_events"><i class="fa fa-server fa-fw"></i><span data-i18n="main_menu_event_services_token">Event Services</span></a> </li>
283284
<li> <a class="inactive mnava" id="MenuItemWeb" href="#conf_webconfig" id="load_webconfig"><i class="fa fa-wrench fa-fw"></i><span data-i18n="main_menu_webconfig_token">Webconfiguration</span></a> </li>
284285
<li> <a class="inactive mnava" id="MenuItemLogging" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li>
285286
<li> <a class="inactive mnava" href="#update"><i class="fa fa-download fa-fw"></i><span data-i18n="main_menu_update_token">Update</span></a> </li>
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
$(document).ready(function () {
2+
performTranslation();
3+
4+
const CEC_ENABLED = (jQuery.inArray("cec", window.serverInfo.services) !== -1);
5+
6+
let conf_editor_osEvents = null;
7+
let conf_editor_cecEvents = null;
8+
let conf_editor_schedEvents = null;
9+
10+
if (window.showOptHelp) {
11+
//Operating System Events
12+
$('#conf_cont').append(createRow('conf_cont_os_events'));
13+
$('#conf_cont_os_events').append(createOptPanel('fa-laptop', $.i18n("conf_os_events_heading_title"), 'editor_container_os_events', 'btn_submit_os_events', 'panel-system'));
14+
$('#conf_cont_os_events').append(createHelpTable(window.schema.osEvents.properties, $.i18n("conf_os_events_heading_title")));
15+
16+
//Scheduled Events
17+
$('#conf_cont').append(createRow('conf_cont_sched_events'));
18+
$('#conf_cont_sched_events').append(createOptPanel('fa-laptop', $.i18n("conf_sched_events_heading_title"), 'editor_container_sched_events', 'btn_submit_sched_events', 'panel-system'));
19+
$('#conf_cont_sched_events').append(createHelpTable(window.schema.schedEvents.properties, $.i18n("conf_sched_events_heading_title")));
20+
21+
22+
//CEC Events
23+
if (CEC_ENABLED) {
24+
$('#conf_cont').append(createRow('conf_cont_event_cec'));
25+
$('#conf_cont_event_cec').append(createOptPanel('fa-tv', $.i18n("conf_cec_events_heading_title"), 'editor_container_cec_events', 'btn_submit_cec_events', 'panel-system'));
26+
$('#conf_cont_event_cec').append(createHelpTable(window.schema.cecEvents.properties, $.i18n("conf_cec_events_heading_title"), "cecEventsHelpPanelId"));
27+
}
28+
}
29+
else {
30+
$('#conf_cont').addClass('row');
31+
$('#conf_cont').append(createOptPanel('fa-laptop', $.i18n("conf_os_events_heading_title"), 'editor_container_os_events', 'btn_submit_os_events'));
32+
$('#conf_cont').append(createOptPanel('fa-laptop', $.i18n("conf_sched_events_heading_title"), 'editor_container_sched_events', 'btn_submit_sched_events'));
33+
if (CEC_ENABLED) {
34+
$('#conf_cont').append(createOptPanel('fa-tv', $.i18n("conf_cec_events_heading_title"), 'editor_container_cec_events', 'btn_submit_cec_events'));
35+
}
36+
}
37+
38+
function findDuplicateEventsIndices(data) {
39+
const eventIndices = {};
40+
data.forEach((item, index) => {
41+
const event = item.event;
42+
if (!eventIndices[event]) {
43+
eventIndices[event] = [index];
44+
} else {
45+
eventIndices[event].push(index);
46+
}
47+
});
48+
49+
return Object.values(eventIndices).filter(indices => indices.length > 1);
50+
}
51+
52+
JSONEditor.defaults.custom_validators.push(function (schema, value, path) {
53+
let errors = [];
54+
if (schema.type === 'array' && Array.isArray(value)) {
55+
const duplicateEventIndices = findDuplicateEventsIndices(value);
56+
57+
if (duplicateEventIndices.length > 0) {
58+
59+
let recs;
60+
duplicateEventIndices.forEach(indices => {
61+
const displayIndices = indices.map(index => index + 1);
62+
recs = displayIndices.join(', ');
63+
});
64+
65+
errors.push({
66+
path: path,
67+
message: $.i18n('edt_conf_action_record_validation_error', recs)
68+
});
69+
}
70+
}
71+
return errors;
72+
});
73+
74+
//Operating System Events
75+
conf_editor_osEvents = createJsonEditor('editor_container_os_events', {
76+
osEvents: window.schema.osEvents
77+
}, true, true);
78+
79+
conf_editor_osEvents.on('change', function () {
80+
conf_editor_osEvents.validate().length || window.readOnlyMode ? $('#btn_submit_os_events').prop('disabled', true) : $('#btn_submit_os_events').prop('disabled', false);
81+
});
82+
83+
$('#btn_submit_os_events').off().on('click', function () {
84+
requestWriteConfig(conf_editor_osEvents.getValue());
85+
});
86+
87+
//Scheduled Events
88+
conf_editor_schedEvents = createJsonEditor('editor_container_sched_events', {
89+
schedEvents: window.schema.schedEvents
90+
}, true, true);
91+
92+
conf_editor_schedEvents.on('change', function () {
93+
94+
const schedEventsEnable = conf_editor_schedEvents.getEditor("root.schedEvents.enable").getValue();
95+
96+
if (schedEventsEnable) {
97+
showInputOptionsForKey(conf_editor_schedEvents, "schedEvents", "enable", true);
98+
$('#schedEventsHelpPanelId').show();
99+
} else {
100+
showInputOptionsForKey(conf_editor_schedEvents, "schedEvents", "enable", false);
101+
$('#schedEventsHelpPanelId').hide();
102+
}
103+
104+
conf_editor_schedEvents.validate().length || window.readOnlyMode ? $('#btn_submit_sched_events').prop('disabled', true) : $('#btn_submit_sched_events').prop('disabled', false);
105+
});
106+
107+
$('#btn_submit_sched_events').off().on('click', function () {
108+
109+
const saveOptions = conf_editor_schedEvents.getValue();
110+
// Workaround, as otherwise values are not reflected correctly
111+
saveOptions.schedEvents.enable = conf_editor_schedEvents.getEditor("root.schedEvents.enable").getValue();
112+
saveOptions.schedEvents.actions = conf_editor_schedEvents.getEditor("root.schedEvents.actions").getValue();
113+
requestWriteConfig(saveOptions);
114+
});
115+
116+
//CEC Events
117+
if (CEC_ENABLED) {
118+
conf_editor_cecEvents = createJsonEditor('editor_container_cec_events', {
119+
cecEvents: window.schema.cecEvents
120+
}, true, true);
121+
122+
conf_editor_cecEvents.on('change', function () {
123+
124+
const cecEventsEnable = conf_editor_cecEvents.getEditor("root.cecEvents.enable").getValue();
125+
126+
if (cecEventsEnable) {
127+
showInputOptionsForKey(conf_editor_cecEvents, "cecEvents", "enable", true);
128+
$('#cecEventsHelpPanelId').show();
129+
} else {
130+
showInputOptionsForKey(conf_editor_cecEvents, "cecEvents", "enable", false);
131+
$('#cecEventsHelpPanelId').hide();
132+
}
133+
134+
conf_editor_cecEvents.validate().length || window.readOnlyMode ? $('#btn_submit_cec_events').prop('disabled', true) : $('#btn_submit_cec_events').prop('disabled', false);
135+
});
136+
137+
$('#btn_submit_cec_events').off().on('click', function () {
138+
139+
const saveOptions = conf_editor_cecEvents.getValue();
140+
// Workaround, as otherwise values are not reflected correctly
141+
saveOptions.cecEvents.enable = conf_editor_cecEvents.getEditor("root.cecEvents.enable").getValue();
142+
saveOptions.cecEvents.actions = conf_editor_cecEvents.getEditor("root.cecEvents.actions").getValue();
143+
requestWriteConfig(saveOptions);
144+
});
145+
}
146+
147+
//create introduction
148+
if (window.showOptHelp) {
149+
createHint("intro", $.i18n('conf_os_events_intro'), "editor_container_os_events");
150+
if (CEC_ENABLED) {
151+
createHint("intro", $.i18n('conf_cec_events_intro'), "editor_container_cec_events");
152+
}
153+
}
154+
155+
removeOverlay();
156+
});
157+

assets/webconfig/js/content_grabber.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ $(document).ready(function () {
55
var screenGrabberAvailable = (window.serverInfo.grabbers.screen.available.length !== 0);
66
var videoGrabberAvailable = (window.serverInfo.grabbers.video.available.length !== 0);
77
const audioGrabberAvailable = (window.serverInfo.grabbers.audio.available.length !== 0);
8-
var CEC_ENABLED = (jQuery.inArray("cec", window.serverInfo.services) !== -1);
98

109
var conf_editor_video = null;
1110
var conf_editor_audio = null;
@@ -369,11 +368,6 @@ $(document).ready(function () {
369368

370369
conf_editor_video.on('change', function () {
371370

372-
// Hide elements not supported by the backend
373-
if (window.serverInfo.cec.enabled === false || !CEC_ENABLED) {
374-
showInputOptionForItem(conf_editor_video, "grabberV4L2", "cecDetection", false);
375-
}
376-
377371
// Validate the current editor's content
378372
if (!conf_editor_video.validate().length) {
379373
var deviceSelected = conf_editor_video.getEditor("root.grabberV4L2.available_devices").getValue();

0 commit comments

Comments
 (0)