hyperion.ng/libsrc/api/JsonCB.cpp

421 lines
12 KiB
C++
Raw Normal View History

// proj incl
#include <api/JsonCB.h>
// hyperion
#include <hyperion/Hyperion.h>
// HyperionIManager
#include <hyperion/HyperionIManager.h>
// components
#include <hyperion/ComponentRegister.h>
// priorityMuxer
#include <hyperion/PriorityMuxer.h>
// utils
#include <utils/ColorSys.h>
// qt
#include <QDateTime>
Windows compilation support (#738) * Disable AVAHI * Replace SysInfo backport with Qt SysInfo * Update vscode config * Update LedDevices * Update Logger * Update hyperiond * Update hyperion-remote * Exclude avahi * Empty definition for Process * PythonInit path broken * Exclude PiBlaster and link ws2_32 * more avahi * resolve ui bug * Update Compile howto * JsonAPI QtGrabber missing * fix error * ssize_t replacement * Nope, doesn't work * Adjust compile description and verify winSDK * Update ci script * Update ci script * Update ci * Update ci script * update Logger * Update PythonInit * added Azure & GitHub Actions, Logger, PythonInit * resolve merge conflicts * revert ssize_t in FadeCandy * look at registry for QT5 & use find_package(Python) if cmake >= 3.12 * second try * another try * and yet another test * qt5 registry search undone * Package creation test * finished package creation. only fine tuning is required :-) Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Dependencies for Windows finished Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * use 'add_definitions()' until CMake 3.12 Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Update .github/workflows/pull-request.yml Co-Authored-By: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com> * Update cmake/Dependencies.cmake Co-Authored-By: brindosch <edeltraud70@gmx.de> * fix typo/ add VCINSTALLDIR var * fix again * Undo change again (Not working) * fix QT grabber Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * first NSIS test Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Update NSIS package * surprise :-) Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com> * Update NSIS package * fix: NSIS .bmps * Add nsis templates * Force windows gui app * fix: QSysInfo required Qt5.6, now it's 5.4 again * Update: Remove platform component and adjust package name * Add macOS as system name * Update docs * fix: Allow gh actions ci also for forks with branches * Add ReadMe docs, mention windows, add vscode linux debug config * fix: readme visual * reduce/hide banner/copyright/log message Infos here: https://docs.microsoft.com/de-de/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019#switches * Fix PythonInit * vscode: Add runner task * fix(vscode): compiler path gcc ver independent * fix azure * vscode: add windows run tasks * move process detection * main: add windows process detection * Azure file shredder * Update docs Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com> Co-authored-by: Paulchen-Panther <Paulchen-Panter@protonmail.com>
2020-05-12 19:51:19 +02:00
#include <QVariant>
// Image to led map helper
#include <hyperion/ImageProcessor.h>
using namespace hyperion;
JsonCB::JsonCB(QObject* parent)
: QObject(parent)
, _hyperion(nullptr)
, _componentRegister(nullptr)
, _prioMuxer(nullptr)
{
mDNS Support (#1452) * Allow build, if no grabbers are enabled * Align available functions to right Qt version * Update to next development version * Align available functions to right Qt version * fix workflows (apt/nightly) * Disable QNetworkConfigurationManager deprecation warnings * Initial go on Smart Pointers * Add Deallocation * Correct QT_WARNING_DISABLE_DEPRECATED (available since 5.9) * Cluster Build Variables * Hyperion Light * Address build warnings * Hyperion Light - UI * Update Protobuf to latest master * Removed compiler warnings * Added restart ability to systray * Correct Protobuf * Ignore 'no-return' warning on protobuf build * hyperion-remote: Fix auto discovery of hyperion server * Fix Qt version override * Update changelog * Remove Grabber Components, if no Grabber exists * Standalone Grabber - Fix fps default * Remote Control - Have Source Selction accrosswhole screen * Enable Blackborder detection only, if relevant input sources available * Enable Blackborder detection only, if relevant input sources available * Remote UI - rearrange containers * Checkout * Fix compilation on windows * Re-added qmdnsengine template cmake * chrono added for linux * Removed existing AVAHI/Bonjour, allow to enable/disable mDNS * hyperiond macos typo fix * Fix macOS Bundle build * Fix macOS bundle info details * Correct CMake files * Removed existing AVAHI/Bonjour (2) * Share hyperion's services via mDNS * Add mDNS Browser and mDNS for LED-Devices * Support mDNS discovery for standalone grabbers * Remove ZLib Dependency & Cleanup * mDNS - hanle 2.local2 an ".local." domains equally * Hue - Link discovery to bridge class, workaround port 443 for mDNS discovery * Fix save button state when switching between devices * Removed sessions (of other hyperions) * mDNS Publisher - Simplify service naming * mDNS refactoring & Forwarder discovery * mDNS Updates to use device service name * Consistency of standalone grabbers with mDNS Service Registry * Merge branch 'hyperion-project:master' into mDNS * Start JSON and WebServers only after Instance 0 is available * Remove bespoke qDebug Output again * MDNS updates and refactor Forwarder * Minor updates * Upgrade to CMake 3.1 * typo * macOS fix * Correct merge * - Remove dynamic linker flag from standalone dispmanX Grabber - Added ability to use system qmdns libs * Cec handler library will load at runtime * typo fix * protobuf changes * mDNS changes for Windows/macOS * test window build qmdnsengine * absolute path to protobuf cmake dir * Rework Hue Wizard supporting mDNS * LED-Devices - Retry support + Refactoring (excl. Hue) * LED-Devices - Refactoring/Retry support Hue + additional alignments * Address LGTM findings * Fix CI-Build, revert test changes * Build Windows in Release mode to avoid python problem * Correct that WebServerObject is available earlier * Ensure that instance name in logs for one instance are presented * Update content LEDs * Rework mDNS Address lookup * Fix LED UI * Fix for non mDNS Services (ignore default port) * Disbale device when now input is available * Revert back some updates, ensure last color is updated when switched on * Handle reopening case and changed IP, port for API-calls * Add UPD-DDP Device * WLED support for DDP * Fix printout * LEDDevice - Allow more retries, udapte defaults * LED-Net Devices - Select Custom device, if configured Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com> Co-authored-by: Paulchen Panther <Paulchen-Panter@protonmail.com>
2022-05-01 19:42:47 +02:00
_availableCommands << "components-update" << "priorities-update" << "imageToLedMapping-update"
<< "adjustment-update" << "videomode-update" << "settings-update" << "leds-update" << "instance-update" << "token-update";
#if defined(ENABLE_EFFECTENGINE)
_availableCommands << "effects-update";
#endif
qRegisterMetaType<PriorityMuxer::InputsMap>("InputsMap");
}
2020-08-08 13:09:15 +02:00
bool JsonCB::subscribeFor(const QString& type, bool unsubscribe)
{
if(!_availableCommands.contains(type))
return false;
if(unsubscribe)
_subscribedCommands.removeAll(type);
else
_subscribedCommands << type;
if(type == "components-update")
{
if(unsubscribe)
disconnect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState);
else
connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState, Qt::UniqueConnection);
}
if(type == "priorities-update")
{
2020-11-01 19:15:22 +01:00
if (unsubscribe)
disconnect(_prioMuxer, &PriorityMuxer::prioritiesChanged, this, &JsonCB::handlePriorityUpdate);
2020-11-01 19:15:22 +01:00
else
connect(_prioMuxer, &PriorityMuxer::prioritiesChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection);
}
if(type == "imageToLedMapping-update")
{
if(unsubscribe)
disconnect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCB::handleImageToLedsMappingChange);
else
connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCB::handleImageToLedsMappingChange, Qt::UniqueConnection);
}
if(type == "adjustment-update")
{
if(unsubscribe)
disconnect(_hyperion, &Hyperion::adjustmentChanged, this, &JsonCB::handleAdjustmentChange);
else
connect(_hyperion, &Hyperion::adjustmentChanged, this, &JsonCB::handleAdjustmentChange, Qt::UniqueConnection);
}
if(type == "videomode-update")
{
if(unsubscribe)
disconnect(_hyperion, &Hyperion::newVideoMode, this, &JsonCB::handleVideoModeChange);
else
connect(_hyperion, &Hyperion::newVideoMode, this, &JsonCB::handleVideoModeChange, Qt::UniqueConnection);
}
#if defined(ENABLE_EFFECTENGINE)
if(type == "effects-update")
{
if(unsubscribe)
disconnect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCB::handleEffectListChange);
else
connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCB::handleEffectListChange, Qt::UniqueConnection);
}
#endif
if(type == "settings-update")
{
if(unsubscribe)
disconnect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleSettingsChange);
else
connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleSettingsChange, Qt::UniqueConnection);
}
if(type == "leds-update")
{
if(unsubscribe)
disconnect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleLedsConfigChange);
else
connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleLedsConfigChange, Qt::UniqueConnection);
}
if(type == "instance-update")
{
if(unsubscribe)
disconnect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange);
else
connect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange, Qt::UniqueConnection);
}
if (type == "token-update")
{
if (unsubscribe)
disconnect(AuthManager::getInstance(), &AuthManager::tokenChange, this, &JsonCB::handleTokenChange);
else
connect(AuthManager::getInstance(), &AuthManager::tokenChange, this, &JsonCB::handleTokenChange, Qt::UniqueConnection);
}
return true;
}
2020-08-02 10:44:42 +02:00
void JsonCB::resetSubscriptions()
{
for(const auto & entry : getSubscribedCommands())
{
subscribeFor(entry, true);
}
}
2020-08-02 10:44:42 +02:00
void JsonCB::setSubscriptionsTo(Hyperion* hyperion)
{
assert(hyperion);
//std::cout << "JsonCB::setSubscriptions for instance [" << static_cast<int>(hyperion->getInstanceIndex()) << "] " << std::endl;
// get current subs
QStringList currSubs(getSubscribedCommands());
// stop subs
resetSubscriptions();
// update pointer
_hyperion = hyperion;
_componentRegister = _hyperion->getComponentRegister();
_prioMuxer = _hyperion->getMuxerInstance();
// re-apply subs
for(const auto & entry : currSubs)
{
subscribeFor(entry);
}
}
void JsonCB::doCallback(const QString& cmd, const QVariant& data)
{
QJsonObject obj;
obj["instance"] = _hyperion->getInstanceIndex();
obj["command"] = cmd;
if (data.userType() == QMetaType::QJsonArray)
obj["data"] = data.toJsonArray();
else
obj["data"] = data.toJsonObject();
//std::cout << "JsonCB::doCallback | [" << static_cast<int>(_hyperion->getInstanceIndex()) << "] Send: [" << QJsonDocument(obj).toJson(QJsonDocument::Compact).toStdString() << "]" << std::endl;
emit newCallback(obj);
}
2020-08-08 13:09:15 +02:00
void JsonCB::handleComponentState(hyperion::Components comp, bool state)
{
QJsonObject data;
data["name"] = componentToIdString(comp);
data["enabled"] = state;
doCallback("components-update", QVariant(data));
}
void JsonCB::handlePriorityUpdate(int currentPriority, const PriorityMuxer::InputsMap& activeInputs)
{
QJsonObject data;
QJsonArray priorities;
uint64_t now = QDateTime::currentMSecsSinceEpoch();
QList<int> activePriorities = activeInputs.keys();
activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY);
for (int priority : qAsConst(activePriorities)) {
const Hyperion::InputInfo& priorityInfo = activeInputs[priority];
QJsonObject item;
item["priority"] = priority;
2018-12-31 15:48:29 +01:00
if (priorityInfo.timeoutTime_ms > 0 )
{
item["duration_ms"] = int(priorityInfo.timeoutTime_ms - now);
}
2018-12-31 15:48:29 +01:00
// owner has optional informations to the component
if(!priorityInfo.owner.isEmpty())
{
item["owner"] = priorityInfo.owner;
}
item["componentId"] = QString(hyperion::componentToIdString(priorityInfo.componentId));
item["origin"] = priorityInfo.origin;
item["active"] = (priorityInfo.timeoutTime_ms >= -1);
item["visible"] = (priority == currentPriority);
if(priorityInfo.componentId == hyperion::COMP_COLOR && !priorityInfo.ledColors.empty())
{
QJsonObject LEDcolor;
// add RGB Value to Array
QJsonArray RGBValue;
RGBValue.append(priorityInfo.ledColors.begin()->red);
RGBValue.append(priorityInfo.ledColors.begin()->green);
RGBValue.append(priorityInfo.ledColors.begin()->blue);
LEDcolor.insert("RGB", RGBValue);
uint16_t Hue;
float Saturation;
float Luminace;
// add HSL Value to Array
QJsonArray HSLValue;
ColorSys::rgb2hsl(priorityInfo.ledColors.begin()->red,
priorityInfo.ledColors.begin()->green,
priorityInfo.ledColors.begin()->blue,
Hue, Saturation, Luminace);
HSLValue.append(Hue);
HSLValue.append(Saturation);
HSLValue.append(Luminace);
LEDcolor.insert("HSL", HSLValue);
item["value"] = LEDcolor;
}
priorities.append(item);
}
data["priorities"] = priorities;
data["priorities_autoselect"] = _hyperion->sourceAutoSelectEnabled();
doCallback("priorities-update", QVariant(data));
}
2020-08-08 13:09:15 +02:00
void JsonCB::handleImageToLedsMappingChange(int mappingType)
{
QJsonObject data;
data["imageToLedMappingType"] = ImageProcessor::mappingTypeToStr(mappingType);
doCallback("imageToLedMapping-update", QVariant(data));
}
void JsonCB::handleAdjustmentChange()
{
QJsonArray adjustmentArray;
for (const QString& adjustmentId : _hyperion->getAdjustmentIds())
{
const ColorAdjustment * colorAdjustment = _hyperion->getAdjustment(adjustmentId);
if (colorAdjustment == nullptr)
{
continue;
}
QJsonObject adjustment;
adjustment["id"] = adjustmentId;
QJsonArray whiteAdjust;
whiteAdjust.append(colorAdjustment->_rgbWhiteAdjustment.getAdjustmentR());
whiteAdjust.append(colorAdjustment->_rgbWhiteAdjustment.getAdjustmentG());
whiteAdjust.append(colorAdjustment->_rgbWhiteAdjustment.getAdjustmentB());
adjustment.insert("white", whiteAdjust);
QJsonArray redAdjust;
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentR());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentG());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentB());
adjustment.insert("red", redAdjust);
QJsonArray greenAdjust;
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentR());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentG());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentB());
adjustment.insert("green", greenAdjust);
QJsonArray blueAdjust;
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentR());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentG());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentB());
adjustment.insert("blue", blueAdjust);
QJsonArray cyanAdjust;
cyanAdjust.append(colorAdjustment->_rgbCyanAdjustment.getAdjustmentR());
cyanAdjust.append(colorAdjustment->_rgbCyanAdjustment.getAdjustmentG());
cyanAdjust.append(colorAdjustment->_rgbCyanAdjustment.getAdjustmentB());
adjustment.insert("cyan", cyanAdjust);
QJsonArray magentaAdjust;
magentaAdjust.append(colorAdjustment->_rgbMagentaAdjustment.getAdjustmentR());
magentaAdjust.append(colorAdjustment->_rgbMagentaAdjustment.getAdjustmentG());
magentaAdjust.append(colorAdjustment->_rgbMagentaAdjustment.getAdjustmentB());
adjustment.insert("magenta", magentaAdjust);
QJsonArray yellowAdjust;
yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentR());
yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentG());
yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentB());
adjustment.insert("yellow", yellowAdjust);
adjustment["backlightThreshold"] = colorAdjustment->_rgbTransform.getBacklightThreshold();
adjustment["backlightColored"] = colorAdjustment->_rgbTransform.getBacklightColored();
adjustment["brightness"] = colorAdjustment->_rgbTransform.getBrightness();
adjustment["brightnessCompensation"] = colorAdjustment->_rgbTransform.getBrightnessCompensation();
adjustment["gammaRed"] = colorAdjustment->_rgbTransform.getGammaR();
adjustment["gammaGreen"] = colorAdjustment->_rgbTransform.getGammaG();
adjustment["gammaBlue"] = colorAdjustment->_rgbTransform.getGammaB();
adjustmentArray.append(adjustment);
}
doCallback("adjustment-update", QVariant(adjustmentArray));
}
2020-08-08 13:09:15 +02:00
void JsonCB::handleVideoModeChange(VideoMode mode)
{
QJsonObject data;
data["videomode"] = QString(videoMode2String(mode));
doCallback("videomode-update", QVariant(data));
}
#if defined(ENABLE_EFFECTENGINE)
void JsonCB::handleEffectListChange()
{
QJsonArray effectList;
QJsonObject effects;
const std::list<EffectDefinition> & effectsDefinitions = _hyperion->getEffects();
for (const EffectDefinition & effectDefinition : effectsDefinitions)
{
QJsonObject effect;
effect["name"] = effectDefinition.name;
effect["file"] = effectDefinition.file;
effect["script"] = effectDefinition.script;
effect["args"] = effectDefinition.args;
effectList.append(effect);
};
effects["effects"] = effectList;
doCallback("effects-update", QVariant(effects));
}
#endif
2020-08-08 13:09:15 +02:00
void JsonCB::handleSettingsChange(settings::type type, const QJsonDocument& data)
{
QJsonObject dat;
if(data.isObject())
dat[typeToString(type)] = data.object();
else
dat[typeToString(type)] = data.array();
doCallback("settings-update", QVariant(dat));
}
2020-08-08 13:09:15 +02:00
void JsonCB::handleLedsConfigChange(settings::type type, const QJsonDocument& data)
{
if(type == settings::LEDS)
{
QJsonObject dat;
dat[typeToString(type)] = data.array();
doCallback("leds-update", QVariant(dat));
}
}
void JsonCB::handleInstanceChange()
{
QJsonArray arr;
for(const auto & entry : HyperionIManager::getInstance()->getInstanceData())
{
QJsonObject obj;
obj.insert("friendly_name", entry["friendly_name"].toString());
obj.insert("instance", entry["instance"].toInt());
//obj.insert("last_use", entry["last_use"].toString());
obj.insert("running", entry["running"].toBool());
arr.append(obj);
}
doCallback("instance-update", QVariant(arr));
}
void JsonCB::handleTokenChange(const QVector<AuthManager::AuthDefinition> &def)
{
QJsonArray arr;
for (const auto &entry : def)
{
QJsonObject sub;
sub["comment"] = entry.comment;
sub["id"] = entry.id;
sub["last_use"] = entry.lastUse;
arr.push_back(sub);
}
doCallback("token-update", QVariant(arr));
}