mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
UI and Web updates (#1421)
* Stop Web-Capture when priority changes * Remote control UI: Treat duration=0 as endless * Stop Web-Capture on non-Image events changes * LED Matrix Layout - Support vertical cabling direction * Additional Yeelight models * Treat http headers case insensitive * Update change log * Treat http headers case insensitive (consider Qt version) * API - Consider provided format when setImage * UI - Support Boblight configuration per LED instance * Support multiple Boblight clients with different priorities * Update changelog * Simplify isGUI rules allowing for QT only builds * Sysinfo: Fix indents * LED-Devices: Show warning, if get properties failed * Qt-Grabber: Fixed position handling of multiple monitors * LED layout: Remove indention limitations * Yeelight: Test YLTD003 * hyperion-remote: Provide image filename to muxer/UI * Refactor PriorityMuxer and related * Temp: Build under Windows 2019 * Yeelight: Remove YLTD003 as it is not working without additional changes * Test Windows-latest with out removing redistributables/new MSVC * correct workflows * correct CI script * Build Windows with Qt 5.15.2 * Priority Muxer: Updates after testing * Fix Typo * Update BGHandler * QTGrabber - Reactivate windows code to avoid cursor issues * Emit prioritiesChanged when autoselect was changed by user Co-authored-by: Paulchen Panther <Paulchen-Panter@protonmail.com>
This commit is contained in:
@@ -193,7 +193,10 @@ void Hyperion::stop()
|
||||
|
||||
void Hyperion::freeObjects()
|
||||
{
|
||||
// switch off all leds
|
||||
//delete Background effect first that it does not kick in when other priorities are stopped
|
||||
delete _BGEffectHandler;
|
||||
|
||||
//Remove all priorities to switch off all leds
|
||||
clear(-1,true);
|
||||
|
||||
// delete components on exit of hyperion core
|
||||
@@ -462,11 +465,6 @@ void Hyperion::setColor(int priority, const std::vector<ColorRgb> &ledColors, in
|
||||
}
|
||||
end:
|
||||
|
||||
if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
|
||||
{
|
||||
clear(priority);
|
||||
}
|
||||
|
||||
// register color
|
||||
registerInput(priority, hyperion::COMP_COLOR, origin);
|
||||
|
||||
@@ -618,10 +616,9 @@ void Hyperion::handleVisibleComponentChanged(hyperion::Components comp)
|
||||
_raw2ledAdjustment->setBacklightEnabled((comp != hyperion::COMP_COLOR && comp != hyperion::COMP_EFFECT));
|
||||
}
|
||||
|
||||
void Hyperion::handleSourceAvailability(const quint8& priority)
|
||||
void Hyperion::handleSourceAvailability(int priority)
|
||||
{ int previousPriority = _muxer->getPreviousPriority();
|
||||
|
||||
Debug(_log,"priority[%d], previousPriority[%d]", priority, previousPriority);
|
||||
if ( priority == PriorityMuxer::LOWEST_PRIORITY)
|
||||
{
|
||||
Debug(_log,"No source left -> Pause output processing and switch LED-Device off");
|
||||
|
@@ -17,6 +17,7 @@ const int PriorityMuxer::BG_PRIORITY = 254;
|
||||
const int PriorityMuxer::MANUAL_SELECTED_PRIORITY = 256;
|
||||
const int PriorityMuxer::LOWEST_PRIORITY = std::numeric_limits<uint8_t>::max();
|
||||
const int PriorityMuxer::TIMEOUT_NOT_ACTIVE_PRIO = -100;
|
||||
const int PriorityMuxer::REMOVE_CLEARED_PRIO = -101;
|
||||
const int PriorityMuxer::ENDLESS = -1;
|
||||
|
||||
PriorityMuxer::PriorityMuxer(int ledCount, QObject * parent)
|
||||
@@ -26,8 +27,6 @@ PriorityMuxer::PriorityMuxer(int ledCount, QObject * parent)
|
||||
, _previousPriority(_currentPriority)
|
||||
, _manualSelectedPriority(MANUAL_SELECTED_PRIORITY)
|
||||
, _prevVisComp (hyperion::Components::COMP_COLOR)
|
||||
, _activeInputs()
|
||||
, _lowestPriorityInfo()
|
||||
, _sourceAutoSelectEnabled(true)
|
||||
, _updateTimer(new QTimer(this))
|
||||
, _timer(new QTimer(this))
|
||||
@@ -38,8 +37,10 @@ PriorityMuxer::PriorityMuxer(int ledCount, QObject * parent)
|
||||
|
||||
// init lowest priority info
|
||||
_lowestPriorityInfo.priority = PriorityMuxer::LOWEST_PRIORITY;
|
||||
_lowestPriorityInfo.timeoutTime_ms = PriorityMuxer::ENDLESS;
|
||||
_lowestPriorityInfo.ledColors = std::vector<ColorRgb>(ledCount, {0, 0, 0});
|
||||
|
||||
_lowestPriorityInfo.timeoutTime_ms = -1;
|
||||
_lowestPriorityInfo.ledColors = std::vector<ColorRgb>(ledCount, ColorRgb::BLACK);
|
||||
|
||||
_lowestPriorityInfo.componentId = hyperion::COMP_COLOR;
|
||||
_lowestPriorityInfo.origin = "System";
|
||||
_lowestPriorityInfo.owner = "";
|
||||
@@ -50,12 +51,10 @@ PriorityMuxer::PriorityMuxer(int ledCount, QObject * parent)
|
||||
connect(_timer, &QTimer::timeout, this, &PriorityMuxer::timeTrigger);
|
||||
_timer->setSingleShot(true);
|
||||
_blockTimer->setSingleShot(true);
|
||||
// forward timeRunner signal to prioritiesChanged signal & threading workaround
|
||||
connect(this, &PriorityMuxer::timeRunner, this, &PriorityMuxer::prioritiesChanged);
|
||||
connect(this, &PriorityMuxer::signalTimeTrigger, this, &PriorityMuxer::timeTrigger);
|
||||
|
||||
// start muxer timer
|
||||
connect(_updateTimer, &QTimer::timeout, this, &PriorityMuxer::setCurrentTime);
|
||||
connect(_updateTimer, &QTimer::timeout, this, &PriorityMuxer::updatePriorities);
|
||||
_updateTimer->setInterval(250);
|
||||
_updateTimer->start();
|
||||
}
|
||||
@@ -85,7 +84,9 @@ bool PriorityMuxer::setSourceAutoSelectEnabled(bool enable, bool update)
|
||||
|
||||
// update _currentPriority if called from external
|
||||
if(update)
|
||||
setCurrentTime();
|
||||
{
|
||||
emit prioritiesChanged(_currentPriority,_activeInputs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -128,10 +129,10 @@ bool PriorityMuxer::hasPriority(int priority) const
|
||||
|
||||
PriorityMuxer::InputInfo PriorityMuxer::getInputInfo(int priority) const
|
||||
{
|
||||
auto elemIt = _activeInputs.find(priority);
|
||||
auto elemIt = _activeInputs.constFind(priority);
|
||||
if (elemIt == _activeInputs.end())
|
||||
{
|
||||
elemIt = _activeInputs.find(PriorityMuxer::LOWEST_PRIORITY);
|
||||
elemIt = _activeInputs.constFind(PriorityMuxer::LOWEST_PRIORITY);
|
||||
if (elemIt == _activeInputs.end())
|
||||
{
|
||||
// fallback
|
||||
@@ -150,11 +151,18 @@ void PriorityMuxer::registerInput(int priority, hyperion::Components component,
|
||||
{
|
||||
// detect new registers
|
||||
bool newInput = false;
|
||||
bool reusedInput = false;
|
||||
|
||||
if (!_activeInputs.contains(priority))
|
||||
{
|
||||
newInput = true;
|
||||
}
|
||||
else if(_prevVisComp == component || _activeInputs[priority].componentId == component)
|
||||
reusedInput = true;
|
||||
{
|
||||
if (_activeInputs[priority].owner != owner)
|
||||
{
|
||||
newInput = true;
|
||||
}
|
||||
}
|
||||
|
||||
InputInfo& input = _activeInputs[priority];
|
||||
input.priority = priority;
|
||||
@@ -166,18 +174,11 @@ void PriorityMuxer::registerInput(int priority, hyperion::Components component,
|
||||
|
||||
if (newInput)
|
||||
{
|
||||
Debug(_log,"Register new input '%s/%s' with priority %d as inactive", QSTRING_CSTR(origin), hyperion::componentToIdString(component), priority);
|
||||
// emit 'prioritiesChanged' only if _sourceAutoSelectEnabled is false
|
||||
if (!_sourceAutoSelectEnabled)
|
||||
{
|
||||
emit prioritiesChanged();
|
||||
}
|
||||
return;
|
||||
Debug(_log,"Register new input '%s/%s' (%s) with priority %d as inactive", QSTRING_CSTR(origin), hyperion::componentToIdString(component), QSTRING_CSTR(owner), priority);
|
||||
}
|
||||
|
||||
if (reusedInput)
|
||||
else
|
||||
{
|
||||
emit timeRunner();
|
||||
Debug(_log,"Reuse input '%s/%s' (%s) with priority %d", QSTRING_CSTR(origin), hyperion::componentToIdString(component), QSTRING_CSTR(owner), priority);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,12 +222,12 @@ bool PriorityMuxer::setInput(int priority, const std::vector<ColorRgb>& ledColor
|
||||
// emit active change
|
||||
if(activeChange)
|
||||
{
|
||||
Debug(_log, "Priority %d is now %s", priority, active ? "active" : "inactive");
|
||||
if (_currentPriority < priority)
|
||||
if (_currentPriority <= priority || !_sourceAutoSelectEnabled)
|
||||
{
|
||||
emit prioritiesChanged();
|
||||
Debug(_log, "Priority %d is now %s", priority, active ? "active" : "inactive");
|
||||
emit prioritiesChanged(_currentPriority,_activeInputs);
|
||||
}
|
||||
setCurrentTime();
|
||||
updatePriorities();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -272,12 +273,12 @@ bool PriorityMuxer::setInputImage(int priority, const Image<ColorRgb>& image, in
|
||||
// emit active change
|
||||
if(activeChange)
|
||||
{
|
||||
Debug(_log, "Priority %d is now %s", priority, active ? "active" : "inactive");
|
||||
if (_currentPriority < priority)
|
||||
if (_currentPriority <= priority || !_sourceAutoSelectEnabled)
|
||||
{
|
||||
emit prioritiesChanged();
|
||||
Debug(_log, "Priority %d is now %s", priority, active ? "active" : "inactive");
|
||||
emit prioritiesChanged(_currentPriority,_activeInputs);
|
||||
}
|
||||
setCurrentTime();
|
||||
updatePriorities();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -291,14 +292,9 @@ bool PriorityMuxer::setInputInactive(int priority)
|
||||
|
||||
bool PriorityMuxer::clearInput(int priority)
|
||||
{
|
||||
if (priority < PriorityMuxer::LOWEST_PRIORITY && (_activeInputs.remove(priority) > 0))
|
||||
if (priority < PriorityMuxer::LOWEST_PRIORITY)
|
||||
{
|
||||
Debug(_log,"Removed source priority %d",priority);
|
||||
// on clear success update _currentPriority
|
||||
setCurrentTime();
|
||||
// emit 'prioritiesChanged' only if _sourceAutoSelectEnabled is false
|
||||
if ((!_sourceAutoSelectEnabled && (_currentPriority < priority)) || _currentPriority == BG_PRIORITY)
|
||||
emit prioritiesChanged();
|
||||
_activeInputs[priority].timeoutTime_ms = REMOVE_CLEARED_PRIO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -312,6 +308,7 @@ void PriorityMuxer::clearAll(bool forceClearAll)
|
||||
_activeInputs.clear();
|
||||
_currentPriority = PriorityMuxer::LOWEST_PRIORITY;
|
||||
_activeInputs[_currentPriority] = _lowestPriorityInfo;
|
||||
updatePriorities();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,35 +323,61 @@ void PriorityMuxer::clearAll(bool forceClearAll)
|
||||
}
|
||||
}
|
||||
|
||||
void PriorityMuxer::setCurrentTime()
|
||||
void PriorityMuxer::updatePriorities()
|
||||
{
|
||||
const int64_t now = QDateTime::currentMSecsSinceEpoch();
|
||||
int newPriority;
|
||||
bool priorityChanged {false};
|
||||
|
||||
_activeInputs.contains(0) ? newPriority = 0 : newPriority = PriorityMuxer::LOWEST_PRIORITY;
|
||||
|
||||
for (auto infoIt = _activeInputs.begin(); infoIt != _activeInputs.end();)
|
||||
{
|
||||
if (infoIt->timeoutTime_ms > 0 && infoIt->timeoutTime_ms <= now)
|
||||
QMutableMapIterator<int, PriorityMuxer::InputInfo> i(_activeInputs);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
|
||||
if ( i.value().timeoutTime_ms == REMOVE_CLEARED_PRIO )
|
||||
{
|
||||
int tPrio = infoIt->priority;
|
||||
infoIt = _activeInputs.erase(infoIt);
|
||||
Debug(_log,"Timeout clear for priority %d",tPrio);
|
||||
emit prioritiesChanged();
|
||||
int tPrio = i.value().priority;
|
||||
i.remove();
|
||||
|
||||
Debug(_log,"Removed source priority %d", tPrio);
|
||||
priorityChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// timeoutTime of TIMEOUT_NOT_ACTIVE_PRIO is awaiting data (inactive); skip
|
||||
if(infoIt->timeoutTime_ms > TIMEOUT_NOT_ACTIVE_PRIO)
|
||||
newPriority = qMin(newPriority, infoIt->priority);
|
||||
|
||||
// call timeTrigger when effect or color is running with timeout > 0, blacklist prio 255
|
||||
if (infoIt->priority < BG_PRIORITY && infoIt->timeoutTime_ms > 0 && (infoIt->componentId == hyperion::COMP_EFFECT || infoIt->componentId == hyperion::COMP_COLOR || infoIt->componentId == hyperion::COMP_IMAGE))
|
||||
if (i.value().timeoutTime_ms > 0 && i.value().timeoutTime_ms <= now)
|
||||
{
|
||||
emit signalTimeTrigger(); // as signal to prevent Threading issues
|
||||
//Stop timer for deleted items to avoid additional priority update
|
||||
_timer->stop();
|
||||
int tPrio = i.value().priority;
|
||||
i.remove();
|
||||
|
||||
Debug(_log,"Timeout clear for priority %d",tPrio);
|
||||
priorityChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// timeoutTime of TIMEOUT_NOT_ACTIVE_PRIO is awaiting data (inactive); skip
|
||||
if(i.value().timeoutTime_ms > TIMEOUT_NOT_ACTIVE_PRIO)
|
||||
{
|
||||
newPriority = qMin(newPriority, i.value().priority);
|
||||
}
|
||||
|
||||
// call timeTrigger when effect or color is running with timeout > 0, blacklist prio 255
|
||||
if (i.value().priority < BG_PRIORITY &&
|
||||
i.value().timeoutTime_ms > 0 &&
|
||||
( i.value().componentId == hyperion::COMP_EFFECT ||
|
||||
i.value().componentId == hyperion::COMP_COLOR ||
|
||||
(i.value().componentId == hyperion::COMP_IMAGE && i.value().owner != "Streaming")
|
||||
)
|
||||
)
|
||||
{
|
||||
emit signalTimeTrigger(); // as signal to prevent Threading issues
|
||||
}
|
||||
}
|
||||
++infoIt;
|
||||
}
|
||||
}
|
||||
|
||||
// evaluate, if manual selected priority is still available
|
||||
if(!_sourceAutoSelectEnabled)
|
||||
{
|
||||
@@ -371,7 +394,7 @@ void PriorityMuxer::setCurrentTime()
|
||||
}
|
||||
// apply & emit on change (after apply!)
|
||||
hyperion::Components comp = getComponentOfPriority(newPriority);
|
||||
if (_currentPriority != newPriority || comp != _prevVisComp)
|
||||
if (_currentPriority != newPriority || comp != _prevVisComp )
|
||||
{
|
||||
_previousPriority = _currentPriority;
|
||||
_currentPriority = newPriority;
|
||||
@@ -383,7 +406,12 @@ void PriorityMuxer::setCurrentTime()
|
||||
_prevVisComp = comp;
|
||||
emit visibleComponentChanged(comp);
|
||||
}
|
||||
emit prioritiesChanged();
|
||||
priorityChanged = true;
|
||||
}
|
||||
|
||||
if (priorityChanged)
|
||||
{
|
||||
emit prioritiesChanged(_currentPriority,_activeInputs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +423,7 @@ void PriorityMuxer::timeTrigger()
|
||||
}
|
||||
else
|
||||
{
|
||||
emit timeRunner();
|
||||
_blockTimer->start(1000);
|
||||
emit prioritiesChanged(_currentPriority,_activeInputs);
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@
|
||||
"type" : "integer",
|
||||
"required" : true,
|
||||
"title" : "edt_conf_general_port_title",
|
||||
"default" : 19333,
|
||||
"minimum" : 1024,
|
||||
"maximum" : 65535,
|
||||
"propertyOrder" : 2
|
||||
|
@@ -137,6 +137,10 @@
|
||||
"type": "string",
|
||||
"enum": [ "snake", "parallel" ]
|
||||
},
|
||||
"direction": {
|
||||
"type": "string",
|
||||
"enum": [ "horizontal", "vertical" ]
|
||||
},
|
||||
"start": {
|
||||
"type": "string",
|
||||
"enum": [ "top-left", "top-right", "bottom-left", "bottom-right" ]
|
||||
|
Reference in New Issue
Block a user