|
|
|
@@ -3,6 +3,7 @@
|
|
|
|
|
#include <cassert>
|
|
|
|
|
#include <exception>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
// QT includes
|
|
|
|
|
#include <QDateTime>
|
|
|
|
@@ -13,6 +14,7 @@
|
|
|
|
|
#include <QCryptographicHash>
|
|
|
|
|
#include <QFile>
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
#include <QHostInfo>
|
|
|
|
|
|
|
|
|
|
// hyperion include
|
|
|
|
|
#include <hyperion/Hyperion.h>
|
|
|
|
@@ -317,8 +319,7 @@ QSize Hyperion::getLedLayoutGridSize(const QJsonValue& ledsConfig)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LinearColorSmoothing * Hyperion::createColorSmoothing(const QJsonObject & smoothingConfig, LedDevice* leddevice)
|
|
|
|
|
{
|
|
|
|
|
LinearColorSmoothing * Hyperion::createColorSmoothing(const QJsonObject & smoothingConfig, LedDevice* leddevice){
|
|
|
|
|
QString type = smoothingConfig["type"].toString("linear").toLower();
|
|
|
|
|
LinearColorSmoothing * device = nullptr;
|
|
|
|
|
type = "linear"; // TODO currently hardcoded type, delete it if we have more types
|
|
|
|
@@ -390,12 +391,15 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
|
|
|
|
|
, _qjsonConfig(qjsonConfig)
|
|
|
|
|
, _configFile(configFile)
|
|
|
|
|
, _timer()
|
|
|
|
|
, _timerBonjourResolver()
|
|
|
|
|
, _log(CORE_LOGGER)
|
|
|
|
|
, _hwLedCount(_ledString.leds().size())
|
|
|
|
|
, _sourceAutoSelectEnabled(true)
|
|
|
|
|
, _configHash()
|
|
|
|
|
, _ledGridSize(getLedLayoutGridSize(qjsonConfig["leds"]))
|
|
|
|
|
, _prevCompId(hyperion::COMP_INVALID)
|
|
|
|
|
, _bonjourBrowser(this)
|
|
|
|
|
, _bonjourResolver(this)
|
|
|
|
|
{
|
|
|
|
|
registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY);
|
|
|
|
|
|
|
|
|
@@ -405,6 +409,10 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
|
|
|
|
|
}
|
|
|
|
|
// set color correction activity state
|
|
|
|
|
const QJsonObject& color = qjsonConfig["color"].toObject();
|
|
|
|
|
|
|
|
|
|
_bonjourBrowser.browseForServiceType(QLatin1String("_hyperiond-http._tcp"));
|
|
|
|
|
connect(&_bonjourBrowser, SIGNAL(currentBonjourRecordsChanged(const QList<BonjourRecord>&)),this, SLOT(currentBonjourRecordsChanged(const QList<BonjourRecord> &)));
|
|
|
|
|
connect(&_bonjourResolver, SIGNAL(bonjourRecordResolved(const QHostInfo &, int)), this, SLOT(bonjourRecordResolved(const QHostInfo &, int)));
|
|
|
|
|
|
|
|
|
|
// initialize the image processor factory
|
|
|
|
|
_ledMAppingType = ImageProcessor::mappingTypeToInt(color["imageToLedMappingType"].toString());
|
|
|
|
@@ -416,11 +424,17 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
|
|
|
|
|
_device = LedDeviceFactory::construct(qjsonConfig["device"].toObject(),_hwLedCount);
|
|
|
|
|
_deviceSmooth = createColorSmoothing(qjsonConfig["smoothing"].toObject(), _device);
|
|
|
|
|
getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState());
|
|
|
|
|
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
|
|
|
|
|
|
|
|
|
|
// setup the timer
|
|
|
|
|
_timer.setSingleShot(true);
|
|
|
|
|
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
|
|
|
|
|
|
|
|
|
|
_timerBonjourResolver.setSingleShot(false);
|
|
|
|
|
_timerBonjourResolver.setInterval(1000);
|
|
|
|
|
QObject::connect(&_timerBonjourResolver, SIGNAL(timeout()), this, SLOT(bonjourResolve()));
|
|
|
|
|
_timerBonjourResolver.start();
|
|
|
|
|
|
|
|
|
|
// create the effect engine
|
|
|
|
|
_effectEngine = new EffectEngine(this,qjsonConfig["effects"].toObject());
|
|
|
|
|
|
|
|
|
@@ -470,6 +484,48 @@ unsigned Hyperion::getLedCount() const
|
|
|
|
|
return _ledString.leds().size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Hyperion::currentBonjourRecordsChanged(const QList<BonjourRecord> &list)
|
|
|
|
|
{
|
|
|
|
|
_hyperionSessions.clear();
|
|
|
|
|
for ( auto rec : list )
|
|
|
|
|
{
|
|
|
|
|
_hyperionSessions.insert(rec.serviceName, rec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Hyperion::bonjourRecordResolved(const QHostInfo &hostInfo, int port)
|
|
|
|
|
{
|
|
|
|
|
if ( _hyperionSessions.contains(_bonjourCurrentServiceToResolve))
|
|
|
|
|
{
|
|
|
|
|
QString host = hostInfo.hostName();
|
|
|
|
|
QString domain = _hyperionSessions[_bonjourCurrentServiceToResolve].replyDomain;
|
|
|
|
|
if (host.endsWith("."+domain))
|
|
|
|
|
{
|
|
|
|
|
host.remove(host.length()-domain.length()-1,domain.length()+1);
|
|
|
|
|
}
|
|
|
|
|
_hyperionSessions[_bonjourCurrentServiceToResolve].hostName = host;
|
|
|
|
|
_hyperionSessions[_bonjourCurrentServiceToResolve].port = port;
|
|
|
|
|
Debug(_log, "found hyperion session: %s:%d",QSTRING_CSTR(hostInfo.hostName()), port);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Hyperion::bonjourResolve()
|
|
|
|
|
{
|
|
|
|
|
for(auto key : _hyperionSessions.keys())
|
|
|
|
|
{
|
|
|
|
|
if (_hyperionSessions[key].port < 0)
|
|
|
|
|
{
|
|
|
|
|
_bonjourCurrentServiceToResolve = key;
|
|
|
|
|
_bonjourResolver.resolveBonjourRecord(_hyperionSessions[key]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Hyperion::BonjourRegister Hyperion::getHyperionSessions()
|
|
|
|
|
{
|
|
|
|
|
return _hyperionSessions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Hyperion::configModified()
|
|
|
|
|
{
|
|
|
|
@@ -507,19 +563,19 @@ void Hyperion::registerPriority(const QString &name, const int priority/*, const
|
|
|
|
|
{
|
|
|
|
|
Info(_log, "Register new input source named '%s' for priority channel '%d'", QSTRING_CSTR(name), priority );
|
|
|
|
|
|
|
|
|
|
for(auto const &entry : _priorityRegister)
|
|
|
|
|
for(auto key : _priorityRegister.keys())
|
|
|
|
|
{
|
|
|
|
|
WarningIf( ( entry.first != name && entry.second == priority), _log,
|
|
|
|
|
"Input source '%s' uses same priority channel (%d) as '%s'.", QSTRING_CSTR(name), priority, QSTRING_CSTR(entry.first));
|
|
|
|
|
WarningIf( ( key != name && _priorityRegister.value(key) == priority), _log,
|
|
|
|
|
"Input source '%s' uses same priority channel (%d) as '%s'.", QSTRING_CSTR(name), priority, QSTRING_CSTR(key));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_priorityRegister.emplace(name,priority);
|
|
|
|
|
_priorityRegister.insert(name, priority);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Hyperion::unRegisterPriority(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
Info(_log, "Unregister input source named '%s' from priority register", QSTRING_CSTR(name));
|
|
|
|
|
_priorityRegister.erase(name);
|
|
|
|
|
_priorityRegister.remove(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Hyperion::setSourceAutoSelectEnabled(bool enabled)
|
|
|
|
@@ -550,14 +606,20 @@ bool Hyperion::setCurrentSourcePriority(int priority )
|
|
|
|
|
|
|
|
|
|
void Hyperion::setComponentState(const hyperion::Components component, const bool state)
|
|
|
|
|
{
|
|
|
|
|
if (component == hyperion::COMP_SMOOTHING)
|
|
|
|
|
switch (component)
|
|
|
|
|
{
|
|
|
|
|
_deviceSmooth->setEnable(state);
|
|
|
|
|
getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
emit componentStateChanged(component, state);
|
|
|
|
|
case hyperion::COMP_SMOOTHING:
|
|
|
|
|
_deviceSmooth->setEnable(state);
|
|
|
|
|
getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState());
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case hyperion::COMP_LEDDEVICE:
|
|
|
|
|
_device->setEnable(state);
|
|
|
|
|
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
emit componentStateChanged(component, state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -785,10 +847,13 @@ void Hyperion::update()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write the data to the device
|
|
|
|
|
if (_deviceSmooth->enabled())
|
|
|
|
|
_deviceSmooth->setLedValues(_ledBuffer);
|
|
|
|
|
else
|
|
|
|
|
_device->setLedValues(_ledBuffer);
|
|
|
|
|
if (_device->enabled())
|
|
|
|
|
{
|
|
|
|
|
if (_deviceSmooth->enabled())
|
|
|
|
|
_deviceSmooth->setLedValues(_ledBuffer);
|
|
|
|
|
else
|
|
|
|
|
_device->setLedValues(_ledBuffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start the timeout-timer
|
|
|
|
|
if (priorityInfo.timeoutTime_ms == -1)
|
|
|
|
@@ -800,4 +865,5 @@ void Hyperion::update()
|
|
|
|
|
int timeout_ms = std::max(0, int(priorityInfo.timeoutTime_ms - QDateTime::currentMSecsSinceEpoch()));
|
|
|
|
|
_timer.start(timeout_ms);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|