populate zeroconf/avahi/bonjour records via json api (#419)

* start of integrating a bonkour service browser

* some experiments

* blub

* bonjour browser via jsonrpc ...

* fix indention

* - make leddevice as component
- extend sysinfo with domain
- add more data for  bonjour browser (e.g. split domain and hostname)

* code cleanup

* add translation

* use component names instead of ids

* fix compile
This commit is contained in:
redPanther
2017-03-21 17:55:46 +01:00
committed by GitHub
parent 9a0e1daf7b
commit 0aa467cceb
25 changed files with 601 additions and 95 deletions

View File

@@ -6,6 +6,8 @@ set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/bonjour)
# Group the headers that go through the MOC compiler
set(Bonjour_QT_HEADERS
${CURRENT_HEADER_DIR}/bonjourserviceregister.h
${CURRENT_HEADER_DIR}/bonjourservicebrowser.h
${CURRENT_HEADER_DIR}/bonjourserviceresolver.h
)
set(Bonjour_HEADERS
@@ -13,13 +15,15 @@ set(Bonjour_HEADERS
set(Bonjour_SOURCES
${CURRENT_SOURCE_DIR}/bonjourserviceregister.cpp
${CURRENT_SOURCE_DIR}/bonjourservicebrowser.cpp
${CURRENT_SOURCE_DIR}/bonjourserviceresolver.cpp
)
set(Bonjour_RESOURCES
)
#set(Bonjour_RESOURCES
#)
qt5_wrap_cpp(Bonjour_HEADERS_MOC ${Bonjour_QT_HEADERS})
qt5_add_resources(Bonjour_RESOURCES_RCC ${Bonjour_RESOURCES} OPTIONS "-no-compress")
#qt5_add_resources(Bonjour_RESOURCES_RCC ${Bonjour_RESOURCES} OPTIONS "-no-compress")
add_library(bonjour
${Bonjour_HEADERS}

View File

@@ -0,0 +1,109 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bonjour/bonjourservicebrowser.h"
#include <QtCore/QSocketNotifier>
BonjourServiceBrowser::BonjourServiceBrowser(QObject *parent)
: QObject(parent)
, dnssref(0)
, bonjourSocket(0)
{
}
BonjourServiceBrowser::~BonjourServiceBrowser()
{
if (dnssref)
{
DNSServiceRefDeallocate(dnssref);
dnssref = 0;
}
}
void BonjourServiceBrowser::browseForServiceType(const QString &serviceType)
{
DNSServiceErrorType err = DNSServiceBrowse(&dnssref, 0, 0, serviceType.toUtf8().constData(), 0, bonjourBrowseReply, this);
if (err != kDNSServiceErr_NoError)
{
emit error(err);
}
else
{
int sockfd = DNSServiceRefSockFD(dnssref);
if (sockfd == -1)
{
emit error(kDNSServiceErr_Invalid);
}
else
{
bonjourSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);
connect(bonjourSocket, SIGNAL(activated(int)), this, SLOT(bonjourSocketReadyRead()));
}
}
}
void BonjourServiceBrowser::bonjourSocketReadyRead()
{
DNSServiceErrorType err = DNSServiceProcessResult(dnssref);
if (err != kDNSServiceErr_NoError)
{
emit error(err);
}
}
void BonjourServiceBrowser::bonjourBrowseReply(DNSServiceRef , DNSServiceFlags flags,
quint32 , DNSServiceErrorType errorCode,
const char *serviceName, const char *regType,
const char *replyDomain, void *context)
{
BonjourServiceBrowser *serviceBrowser = static_cast<BonjourServiceBrowser *>(context);
if (errorCode != kDNSServiceErr_NoError)
{
emit serviceBrowser->error(errorCode);
}
else
{
BonjourRecord bonjourRecord(serviceName, regType, replyDomain);
if (flags & kDNSServiceFlagsAdd)
{
if (!serviceBrowser->bonjourRecords.contains(bonjourRecord))
{
serviceBrowser->bonjourRecords.append(bonjourRecord);
}
}
else
{
serviceBrowser->bonjourRecords.removeAll(bonjourRecord);
}
if (!(flags & kDNSServiceFlagsMoreComing))
{
emit serviceBrowser->currentBonjourRecordsChanged(serviceBrowser->bonjourRecords);
}
}
}

View File

@@ -0,0 +1,122 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <QtCore/QSocketNotifier>
#include <QtNetwork/QHostInfo>
#include "bonjour/bonjourrecord.h"
#include "bonjour/bonjourserviceresolver.h"
BonjourServiceResolver::BonjourServiceResolver(QObject *parent)
: QObject(parent)
, dnssref(0)
, bonjourSocket(0)
, bonjourPort(-1)
{
}
BonjourServiceResolver::~BonjourServiceResolver()
{
cleanupResolve();
}
void BonjourServiceResolver::cleanupResolve()
{
if (dnssref)
{
DNSServiceRefDeallocate(dnssref);
dnssref = 0;
delete bonjourSocket;
bonjourPort = -1;
}
}
bool BonjourServiceResolver::resolveBonjourRecord(const BonjourRecord &record)
{
if (dnssref)
{
//qWarning("resolve in process, aborting");
return false;
}
DNSServiceErrorType err = DNSServiceResolve(&dnssref, 0, 0,
record.serviceName.toUtf8().constData(),
record.registeredType.toUtf8().constData(),
record.replyDomain.toUtf8().constData(),
(DNSServiceResolveReply)bonjourResolveReply, this);
if (err != kDNSServiceErr_NoError)
{
emit error(err);
}
else
{
int sockfd = DNSServiceRefSockFD(dnssref);
if (sockfd == -1)
{
emit error(kDNSServiceErr_Invalid);
}
else
{
bonjourSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);
connect(bonjourSocket, SIGNAL(activated(int)), this, SLOT(bonjourSocketReadyRead()));
}
}
return true;
}
void BonjourServiceResolver::bonjourSocketReadyRead()
{
DNSServiceErrorType err = DNSServiceProcessResult(dnssref);
if (err != kDNSServiceErr_NoError)
emit error(err);
}
void BonjourServiceResolver::bonjourResolveReply(DNSServiceRef sdRef, DNSServiceFlags ,
quint32 , DNSServiceErrorType errorCode,
const char *, const char *hosttarget, quint16 port,
quint16 , const char *, void *context)
{
BonjourServiceResolver *serviceResolver = static_cast<BonjourServiceResolver *>(context);
if (errorCode != kDNSServiceErr_NoError) {
emit serviceResolver->error(errorCode);
return;
}
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
{
port = 0 | ((port & 0x00ff) << 8) | ((port & 0xff00) >> 8);
}
#endif
serviceResolver->bonjourPort = port;
QHostInfo::lookupHost(QString::fromUtf8(hosttarget), serviceResolver, SLOT(finishConnect(const QHostInfo &)));
}
void BonjourServiceResolver::finishConnect(const QHostInfo &hostInfo)
{
emit bonjourRecordResolved(hostInfo, bonjourPort);
QMetaObject::invokeMethod(this, "cleanupResolve", Qt::QueuedConnection);
}

View File

@@ -57,5 +57,6 @@ target_link_libraries(hyperion
blackborder
hyperion-utils
leddevice
bonjour
${QT_LIBRARIES}
)

View File

@@ -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);
}
}

View File

@@ -17,7 +17,6 @@ LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpd
, _outputDelay(updateDelay)
, _writeToLedsEnable(true)
, _continuousOutput(continuousOutput)
, _enabled(true)
{
_log = Logger::getInstance("Smoothing");
_timer.setSingleShot(false);
@@ -143,7 +142,8 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
void LinearColorSmoothing::setEnable(bool enable)
{
_enabled = enable;
LedDevice::setEnable(enable);
if (!enable)
{
_timer.stop();
@@ -151,8 +151,3 @@ void LinearColorSmoothing::setEnable(bool enable)
}
}
bool LinearColorSmoothing::enabled()
{
return _enabled;
}

View File

@@ -41,9 +41,6 @@ public:
virtual int switchOff();
void setEnable(bool enable);
bool enabled();
bool componentState() { return enabled(); };
private slots:
/// Timer callback which writes updated led values to the led device
@@ -91,6 +88,4 @@ private:
/// Flag for dis/enable continuous output to led device regardless there is new data or not
bool _continuousOutput;
bool _enabled;
};

View File

@@ -11,10 +11,12 @@ PriorityMuxer::PriorityMuxer(int ledCount)
, _activeInputs()
, _lowestPriorityInfo()
{
_lowestPriorityInfo.priority = LOWEST_PRIORITY;
_lowestPriorityInfo.priority = LOWEST_PRIORITY;
_lowestPriorityInfo.timeoutTime_ms = -1;
_lowestPriorityInfo.ledColors = std::vector<ColorRgb>(ledCount, {0, 0, 0});
_lowestPriorityInfo.ledColors = std::vector<ColorRgb>(ledCount, {0, 0, 0});
_lowestPriorityInfo.componentId = hyperion::COMP_COLOR;
_lowestPriorityInfo.origin = "System";
_activeInputs[_currentPriority] = _lowestPriorityInfo;
}

View File

@@ -48,6 +48,8 @@
using namespace hyperion;
int _connectionCounter = 0;
JsonClientConnection::JsonClientConnection(QTcpSocket *socket)
: QObject()
, _socket(socket)
@@ -577,6 +579,7 @@ void JsonClientConnection::handleSysInfoCommand(const QJsonObject&, const QStrin
system["productVersion"] = data.productVersion;
system["prettyName" ] = data.prettyName;
system["hostName" ] = data.hostName;
system["domainName" ] = data.domainName;
info["system"] = system;
QJsonObject hyperion;
@@ -619,22 +622,21 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
}
item["owner"] = QString(hyperion::componentToIdString(priorityInfo.componentId));
item["componentId"] = priorityInfo.componentId;
item["componentId"] = QString(hyperion::componentToIdString(priorityInfo.componentId));
item["origin"] = priorityInfo.origin;
item["component"] = QString(hyperion::componentToString(priorityInfo.componentId));
item["active"] = true;
item["visible"] = (priority == currentPriority);
foreach(auto const &entry, priorityRegister)
// remove item from prio register, because we have more valuable information via active priority
QList<QString> prios = priorityRegister.keys(priority);
if (! prios.empty())
{
if (entry.second == priority)
{
item["owner"] = entry.first;
priorityRegister.erase(entry.first);
break;
}
item["owner"] = prios[0];
priorityRegister.remove(prios[0]);
}
if(priorityInfo.componentId == 9)
if(priorityInfo.componentId == hyperion::COMP_COLOR)
{
QJsonObject LEDcolor;
@@ -679,14 +681,15 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
// priorities[priorities.size()] = item;
priorities.append(item);
}
foreach(auto const &entry, priorityRegister)
// append left over priorities
for(auto key : priorityRegister.keys())
{
QJsonObject item;
item["priority"] = entry.second;
item["priority"] = priorityRegister[key];
item["active"] = false;
item["visible"] = false;
item["owner"] = entry.first;
item["owner"] = key;
priorities.append(item);
}
@@ -827,6 +830,22 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
QJsonObject hyperion;
hyperion["config_modified" ] = _hyperion->configModified();
hyperion["config_writeable"] = _hyperion->configWriteable();
// sessions
QJsonArray sessions;
for (auto session: _hyperion->getHyperionSessions())
{
if (session.port<0) continue;
QJsonObject item;
item["name"] = session.serviceName;
item["type"] = session.registeredType;
item["domain"] = session.replyDomain;
item["host"] = session.hostName;
item["port"] = session.port;
sessions.append(item);
}
hyperion["sessions"] = sessions;
info["hyperion"] = hyperion;
// send the result

View File

@@ -21,7 +21,7 @@
"component":
{
"type" : "string",
"enum" : ["SMOOTHING", "BLACKBORDER", "KODICHECKER", "FORWARDER", "UDPLISTENER", "BOBLIGHTSERVER", "GRABBER", "V4L"],
"enum" : ["SMOOTHING", "BLACKBORDER", "KODICHECKER", "FORWARDER", "UDPLISTENER", "BOBLIGHTSERVER", "GRABBER", "V4L", "LEDDEVICE"],
"required": true
},
"state":

View File

@@ -5,6 +5,7 @@
#include <QResource>
#include <QStringList>
#include <QDir>
#include "hyperion/Hyperion.h"
LedDeviceRegistry LedDevice::_ledDeviceMap = LedDeviceRegistry();
QString LedDevice::_activeDevice = "";
@@ -19,8 +20,11 @@ LedDevice::LedDevice()
, _deviceReady(true)
, _refresh_timer()
, _refresh_timer_interval(0)
, _componentRegistered(false)
, _enabled(true)
{
LedDevice::getLedDeviceSchemas();
qRegisterMetaType<hyperion::Components>("hyperion::Components");
// setup timer
_refresh_timer.setSingleShot(false);
@@ -34,6 +38,16 @@ int LedDevice::open()
return 0;
}
void LedDevice::setEnable(bool enable)
{
if ( _enabled && !enable)
{
switchOff();
}
_enabled = enable;
}
int LedDevice::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr)
{
_ledDeviceMap.emplace(name,funcPtr);
@@ -111,12 +125,11 @@ QJsonObject LedDevice::getLedDeviceSchemas()
return result;
}
int LedDevice::setLedValues(const std::vector<ColorRgb>& ledValues)
{
if (!_deviceReady)
if (!_deviceReady || !_enabled)
return -1;
_ledValues = ledValues;
// restart the timer
@@ -142,5 +155,5 @@ void LedDevice::setLedCount(int ledCount)
int LedDevice::rewriteLeds()
{
return write(_ledValues);
return _enabled ? write(_ledValues) : -1;
}

View File

@@ -29,6 +29,7 @@ SysInfo::SysInfo()
_sysinfo.productVersion = v.productVersion;
_sysinfo.prettyName = v.prettyName;
_sysinfo.hostName = QHostInfo::localHostName();
_sysinfo.domainName = QHostInfo::localDomainName();
}
SysInfo::~SysInfo()