diff --git a/assets/webconfig/js/wizard.js b/assets/webconfig/js/wizard.js
index 09a5cd14..aeee28c8 100644
--- a/assets/webconfig/js/wizard.js
+++ b/assets/webconfig/js/wizard.js
@@ -1263,7 +1263,7 @@ function startWizardWLED(e)
var hostAddress = conf_editor.getEditor("root.specificOptions.host").getValue();
if(hostAddress != "")
{
- getProperties_wled(hostAddress);
+ getProperties_wled(hostAddress,"info");
identify_wled(hostAddress)
}
diff --git a/docs/development/LedDevice_Flows.drawio b/docs/development/LedDevice_Flows.drawio
new file mode 100644
index 00000000..c7646141
--- /dev/null
+++ b/docs/development/LedDevice_Flows.drawio
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/docs/development/LedDevice_Flows.png b/docs/development/LedDevice_Flows.png
new file mode 100644
index 00000000..f6ce9ee0
Binary files /dev/null and b/docs/development/LedDevice_Flows.png differ
diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h
index 09d8be6b..9b301e2f 100644
--- a/include/hyperion/Hyperion.h
+++ b/include/hyperion/Hyperion.h
@@ -473,6 +473,9 @@ private slots:
///
void handleNewVideoMode(VideoMode mode) { _currVideoMode = mode; }
+
+ void handlPriorityChangedLedDevice(const quint8& priority);
+
private:
friend class HyperionDaemon;
friend class HyperionIManager;
diff --git a/include/hyperion/PriorityMuxer.h b/include/hyperion/PriorityMuxer.h
index fb444628..c1feedf5 100644
--- a/include/hyperion/PriorityMuxer.h
+++ b/include/hyperion/PriorityMuxer.h
@@ -109,6 +109,13 @@ public:
///
int getCurrentPriority() const { return _currentPriority; }
+ ///
+ /// Returns the previous priority before current priority
+ ///
+ /// @return The previous priority
+ ///
+ int getPreviousPriority() const { return _previousPriority; }
+
///
/// Returns the state (enabled/disabled) of a specific priority channel
/// @param priority The priority channel
@@ -193,13 +200,6 @@ signals:
///
void timeRunner();
- ///
- /// @brief A priority has been added (registerInput()) or deleted, method clear or timeout clear
- /// @param priority The priority which has changed
- /// @param state If true it was added else it was removed!
- ///
- void priorityChanged(quint8 priority, bool state);
-
///
/// @brief Emits whenever the visible priority has changed
/// @param priority The new visible priority
@@ -261,6 +261,9 @@ private:
/// The current priority (lowest value in _activeInputs)
int _currentPriority;
+ /// The previous priority before current priority
+ int _previousPriority;
+
/// The manual select priority set with setPriority
int _manualSelectedPriority;
diff --git a/include/leddevice/LedDevice.h b/include/leddevice/LedDevice.h
index c58fa925..a9dcf0c5 100644
--- a/include/leddevice/LedDevice.h
+++ b/include/leddevice/LedDevice.h
@@ -64,13 +64,6 @@ public:
///
void setLedCount(unsigned int ledCount);
- ///
- /// @brief Check, if the device is enabled.
- ///
- /// @return True, if enabled
- ///
- bool isEnabled() const { return _isEnabled; }
-
///
/// @brief Set a device's latch time.
///
@@ -81,6 +74,15 @@ public:
///
void setLatchTime(int latchTime_ms);
+ ///
+ /// @brief Set a device's rewrite time.
+ ///
+ /// Rewrite time is the time frame a devices requires to be refreshed, if no updated happened in the meantime.
+ ///
+ /// @param[in] rewriteTime_ms Rewrite time in milliseconds
+ ///
+ void setRewriteTime(int rewriteTime_ms);
+
///
/// @brief Discover devices of this type available (for configuration).
/// @note Mainly used for network devices. Allows to find devices, e.g. via ssdp, mDNS or cloud ways.
@@ -172,15 +174,6 @@ public slots:
///
virtual int updateLeds(const std::vector& ledValues);
- ///
- /// @brief Enables/disables the device for output.
- ///
- /// If the device is not ready, it will not be enabled.
- ///
- /// @param[in] enable The new state of the device
- ///
- void setEnable(bool enable);
-
///
/// @brief Get the currently defined LatchTime.
///
@@ -188,6 +181,13 @@ public slots:
///
int getLatchTime() const { return _latchTime_ms; }
+ ///
+ /// @brief Get the currently defined RewriteTime.
+ ///
+ /// @return Rewrite time in milliseconds
+ ///
+ int getRewriteTime() const { return _refreshTimerInterval_ms; }
+
///
/// @brief Get the number of LEDs supported by the device.
///
@@ -212,7 +212,46 @@ public slots:
///
/// @return True, if enabled
///
- inline bool componentState() const { return isEnabled(); }
+ inline bool componentState() const { return _isEnabled; }
+
+ ///
+ /// @brief Enables the device for output.
+ ///
+ /// If the device is not ready, it will not be enabled.
+ ///
+ void enable();
+
+ ///
+ /// @brief Disables the device for output.
+ ///
+ void disable();
+
+ ///
+ /// @brief Switch the LEDs on.
+ ///
+ /// Takes care that the device is opened and powered-on.
+ /// Depending on the configuration, the device may store its current state for later restore.
+ /// @see powerOn, storeState
+ ///
+ /// @return True, if success
+ ///
+ virtual bool switchOn();
+
+ ///
+ /// @brief Switch the LEDs off.
+ ///
+ /// Takes care that the LEDs and device are switched-off and device is closed.
+ /// Depending on the configuration, the device may be powered-off or restored to its previous state.
+ /// @see powerOff, restoreState
+ ///
+ /// @return True, if success
+ ///
+ virtual bool switchOff();
+
+ bool switchOnOff(bool onState)
+ {
+ return onState == true ? switchOn() : switchOff();
+ }
signals:
///
@@ -264,28 +303,6 @@ protected:
///
virtual int writeBlack(int numberOfBlack=1);
- ///
- /// @brief Switch the LEDs on.
- ///
- /// Takes care that the device is opened and powered-on.
- /// Depending on the configuration, the device may store its current state for later restore.
- /// @see powerOn, storeState
- ///
- /// @return True, if success
- ///
- virtual bool switchOn();
-
- ///
- /// @brief Switch the LEDs off.
- ///
- /// Takes care that the LEDs and device are switched-off and device is closed.
- /// Depending on the configuration, the device may be powered-off or restored to its previous state.
- /// @see powerOff, restoreState
- ///
- /// @return True, if success
- ///
- virtual bool switchOff();
-
///
/// @brief Power-/turn on the LED-device.
///
@@ -378,6 +395,9 @@ protected:
/// Is the device ready for processing?
bool _isDeviceReady;
+ /// Is the device switched on?
+ bool _isOn;
+
/// Is the device in error state and stopped?
bool _isDeviceInError;
diff --git a/include/leddevice/LedDeviceWrapper.h b/include/leddevice/LedDeviceWrapper.h
index 0413d03e..4526bc03 100644
--- a/include/leddevice/LedDeviceWrapper.h
+++ b/include/leddevice/LedDeviceWrapper.h
@@ -90,8 +90,27 @@ signals:
///
int updateLeds(const std::vector& ledValues);
- void setEnable(bool enable);
- void closeLedDevice();
+ ///
+ /// @brief Enables the LED-Device.
+ ///
+ void enable();
+
+ ///
+ /// @brief Disables the LED-Device.
+ ///
+ void disable();
+
+ ///
+ /// @brief Switch the LEDs on.
+ ///
+ void switchOn();
+
+ ///
+ /// @brief Switch the LEDs off.
+ ///
+ void switchOff();
+
+ void stopLedDevice();
private slots:
///
diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp
index 90de57c5..b5b81003 100644
--- a/libsrc/hyperion/Hyperion.cpp
+++ b/libsrc/hyperion/Hyperion.cpp
@@ -87,6 +87,7 @@ void Hyperion::start()
// connect Hyperion::update with Muxer visible priority changes as muxer updates independent
connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::update);
+ connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::handlPriorityChangedLedDevice);
connect(&_muxer, &PriorityMuxer::visibleComponentChanged, this, &Hyperion::handleVisibleComponentChanged);
// listens for ComponentRegister changes of COMP_ALL to perform core enable/disable actions
@@ -530,6 +531,26 @@ void Hyperion::handleVisibleComponentChanged(hyperion::Components comp)
_raw2ledAdjustment->setBacklightEnabled((comp != hyperion::COMP_COLOR && comp != hyperion::COMP_EFFECT));
}
+void Hyperion::handlPriorityChangedLedDevice(const quint8& priority)
+{
+ quint8 previousPriority = _muxer.getPreviousPriority();
+
+ Debug(_log,"priority[%u], previousPriority[%u]", priority, previousPriority);
+ if ( priority == PriorityMuxer::LOWEST_PRIORITY)
+ {
+ Debug(_log,"No source left -> switch LED-Device off");
+ emit _ledDeviceWrapper->switchOff();
+ }
+ else
+ {
+ if ( previousPriority == PriorityMuxer::LOWEST_PRIORITY )
+ {
+ Debug(_log,"new source available -> switch LED-Device on");
+ emit _ledDeviceWrapper->switchOn();
+ }
+ }
+}
+
void Hyperion::update()
{
// Obtain the current priority channel
diff --git a/libsrc/hyperion/PriorityMuxer.cpp b/libsrc/hyperion/PriorityMuxer.cpp
index b029434c..b7687e25 100644
--- a/libsrc/hyperion/PriorityMuxer.cpp
+++ b/libsrc/hyperion/PriorityMuxer.cpp
@@ -18,6 +18,7 @@ PriorityMuxer::PriorityMuxer(int ledCount, QObject * parent)
: QObject(parent)
, _log(Logger::getInstance("HYPERION"))
, _currentPriority(PriorityMuxer::LOWEST_PRIORITY)
+ , _previousPriority(_currentPriority)
, _manualSelectedPriority(256)
, _activeInputs()
, _lowestPriorityInfo()
@@ -156,7 +157,6 @@ 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 priorityChanged(priority, true);
emit prioritiesChanged();
return;
}
@@ -255,7 +255,6 @@ bool PriorityMuxer::clearInput(uint8_t priority)
Debug(_log,"Removed source priority %d",priority);
// on clear success update _currentPriority
setCurrentTime();
- emit priorityChanged(priority, false);
emit prioritiesChanged();
return true;
}
@@ -266,6 +265,7 @@ void PriorityMuxer::clearAll(bool forceClearAll)
{
if (forceClearAll)
{
+ _previousPriority = _currentPriority;
_activeInputs.clear();
_currentPriority = PriorityMuxer::LOWEST_PRIORITY;
_activeInputs[_currentPriority] = _lowestPriorityInfo;
@@ -296,7 +296,6 @@ void PriorityMuxer::setCurrentTime()
quint8 tPrio = infoIt->priority;
infoIt = _activeInputs.erase(infoIt);
Debug(_log,"Timeout clear for priority %d",tPrio);
- emit priorityChanged(tPrio, false);
emit prioritiesChanged();
}
else
@@ -329,6 +328,7 @@ void PriorityMuxer::setCurrentTime()
// apply & emit on change (after apply!)
if (_currentPriority != newPriority)
{
+ _previousPriority = _currentPriority;
_currentPriority = newPriority;
Debug(_log, "Set visible priority to %d", newPriority);
emit visiblePriorityChanged(newPriority);
diff --git a/libsrc/leddevice/LedDevice.cpp b/libsrc/leddevice/LedDevice.cpp
index 4d727b20..4229f2da 100644
--- a/libsrc/leddevice/LedDevice.cpp
+++ b/libsrc/leddevice/LedDevice.cpp
@@ -28,6 +28,7 @@ LedDevice::LedDevice(const QJsonObject& deviceConfig, QObject* parent)
, _isEnabled(false)
, _isDeviceInitialised(false)
, _isDeviceReady(false)
+ , _isOn(false)
, _isDeviceInError(false)
, _isInSwitchOff (false)
, _lastWriteTime(QDateTime::currentDateTime())
@@ -62,14 +63,15 @@ void LedDevice::start()
{
// Everything is OK -> enable device
_isDeviceInitialised = true;
- setEnable(true);
+ this->enable();
}
}
void LedDevice::stop()
{
- setEnable(false);
+ this->disable();
this->stopRefreshTimer();
+ Info(_log, " Stopped LedDevice '%s'", QSTRING_CSTR(_activeDeviceType) );
}
int LedDevice::open()
@@ -99,27 +101,39 @@ void LedDevice::setInError(const QString& errorMsg)
emit enableStateChanged(_isEnabled);
}
-void LedDevice::setEnable(bool enable)
+void LedDevice::enable()
{
- bool isSwitched = false;
- // switch off device when disabled, default: set black to LEDs when they should go off
- if ( _isEnabled && !enable)
+ if ( !_isEnabled )
{
- isSwitched = switchOff();
- }
- else
- {
- // switch on device when enabled
- if ( !_isEnabled && enable)
+ _isDeviceInError = false;
+
+ if ( ! _isDeviceReady )
{
- isSwitched = switchOn();
+ open();
+ }
+
+ if ( _isDeviceReady )
+ {
+ _isEnabled = true;
+ if ( switchOn() )
+ {
+ emit enableStateChanged(_isEnabled);
+ }
}
}
+}
- if ( isSwitched )
+void LedDevice::disable()
+{
+ if ( _isEnabled )
{
- _isEnabled = enable;
- emit enableStateChanged(enable);
+ _isEnabled = false;
+ this->stopRefreshTimer();
+
+ switchOff();
+ close();
+
+ emit enableStateChanged(_isEnabled);
}
}
@@ -133,30 +147,11 @@ bool LedDevice::init(const QJsonObject &deviceConfig)
Debug(_log, "deviceConfig: [%s]", QString(QJsonDocument(_devConfig).toJson(QJsonDocument::Compact)).toUtf8().constData() );
_colorOrder = deviceConfig["colorOrder"].toString("RGB");
- setLedCount(static_cast( deviceConfig["currentLedCount"].toInt(1) )); // property injected to reflect real led count
- _latchTime_ms =deviceConfig["latchTime"].toInt( _latchTime_ms );
- _refreshTimerInterval_ms = deviceConfig["rewriteTime"].toInt( _refreshTimerInterval_ms);
+ setLedCount( static_cast( deviceConfig["currentLedCount"].toInt(1) ) ); // property injected to reflect real led count
+ setLatchTime( deviceConfig["latchTime"].toInt( _latchTime_ms ) );
+ setRewriteTime ( deviceConfig["rewriteTime"].toInt( _refreshTimerInterval_ms) );
- if ( _refreshTimerInterval_ms > 0 )
- {
- _isRefreshEnabled = true;
-
- if (_refreshTimerInterval_ms <= _latchTime_ms )
- {
- int new_refresh_timer_interval = _latchTime_ms + 10;
- Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refreshTimerInterval_ms, new_refresh_timer_interval);
- _refreshTimerInterval_ms = new_refresh_timer_interval;
- _refreshTimer->setInterval( _refreshTimerInterval_ms );
- }
-
- Debug(_log, "Refresh interval = %dms",_refreshTimerInterval_ms );
- _refreshTimer->setInterval( _refreshTimerInterval_ms );
-
- _lastWriteTime = QDateTime::currentDateTime();
-
- this->startRefreshTimer();
- }
return true;
}
@@ -176,9 +171,9 @@ void LedDevice::stopRefreshTimer()
int LedDevice::updateLeds(const std::vector& ledValues)
{
int retval = 0;
- if ( !isEnabled() || !_isDeviceReady || _isDeviceInError )
+ if ( !_isEnabled || !_isOn || !_isDeviceReady || _isDeviceInError )
{
- //std::cout << "LedDevice::updateLeds(), LedDevice NOT ready!" << std::endl;
+ //std::cout << "LedDevice::updateLeds(), LedDevice NOT ready! ";
return -1;
}
else
@@ -256,20 +251,20 @@ int LedDevice::writeBlack(int numberOfBlack)
bool LedDevice::switchOn()
{
bool rc = false;
- if ( _isDeviceInitialised && ! _isDeviceReady && ! _isEnabled )
+
+ if ( _isOn )
{
- _isDeviceInError = false;
- if ( open() < 0 )
- {
- rc = false;
- }
- else
+ rc = true;
+ }
+ else
+ {
+ if ( _isEnabled &&_isDeviceInitialised )
{
storeState();
if ( powerOn() )
{
- _isEnabled = true;
+ _isOn = true;
rc = true;
}
}
@@ -281,38 +276,37 @@ bool LedDevice::switchOff()
{
bool rc = false;
- if ( _isDeviceInitialised )
+ if ( !_isOn )
{
- // Disable device to ensure no standard Led updates are written/processed
- _isEnabled = false;
- _isInSwitchOff = true;
-
- this->stopRefreshTimer();
-
rc = true;
-
- if ( _isDeviceReady )
+ }
+ else
+ {
+ if ( _isDeviceInitialised )
{
- if ( _isRestoreOrigState )
- {
- //Restore devices state
- restoreState();
- }
- else
- {
- powerOff();
- }
+ // Disable device to ensure no standard Led updates are written/processed
+ _isOn = false;
+ _isInSwitchOff = true;
- }
- if ( close() < 0 )
- {
- rc = false;
+ rc = true;
+
+ if ( _isDeviceReady )
+ {
+ if ( _isRestoreOrigState )
+ {
+ //Restore devices state
+ restoreState();
+ }
+ else
+ {
+ powerOff();
+ }
+ }
}
}
return rc;
}
-
bool LedDevice::powerOff()
{
bool rc = false;
@@ -403,7 +397,33 @@ void LedDevice::setLedCount(unsigned int ledCount)
void LedDevice::setLatchTime( int latchTime_ms )
{
_latchTime_ms = latchTime_ms;
- Debug(_log, "LatchTime updated to %dms", this->getLatchTime());
+ Debug(_log, "LatchTime updated to %dms", _latchTime_ms);
+}
+
+void LedDevice::setRewriteTime( int rewriteTime_ms )
+{
+ _refreshTimerInterval_ms = rewriteTime_ms;
+
+ if ( _refreshTimerInterval_ms > 0 )
+ {
+
+ _isRefreshEnabled = true;
+
+ if (_refreshTimerInterval_ms <= _latchTime_ms )
+ {
+ int new_refresh_timer_interval = _latchTime_ms + 10;
+ Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refreshTimerInterval_ms, new_refresh_timer_interval);
+ _refreshTimerInterval_ms = new_refresh_timer_interval;
+ _refreshTimer->setInterval( _refreshTimerInterval_ms );
+ }
+
+ Debug(_log, "Refresh interval = %dms",_refreshTimerInterval_ms );
+ _refreshTimer->setInterval( _refreshTimerInterval_ms );
+
+ _lastWriteTime = QDateTime::currentDateTime();
+ }
+
+ Debug(_log, "RewriteTime updated to %dms", _refreshTimerInterval_ms);
}
void LedDevice::printLedValues(const std::vector& ledValues)
diff --git a/libsrc/leddevice/LedDeviceWrapper.cpp b/libsrc/leddevice/LedDeviceWrapper.cpp
index f03dce46..43a35e79 100644
--- a/libsrc/leddevice/LedDeviceWrapper.cpp
+++ b/libsrc/leddevice/LedDeviceWrapper.cpp
@@ -52,14 +52,19 @@ void LedDeviceWrapper::createLedDevice(const QJsonObject& config)
thread->setObjectName("LedDeviceThread");
_ledDevice = LedDeviceFactory::construct(config);
_ledDevice->moveToThread(thread);
-
// setup thread management
connect(thread, &QThread::started, _ledDevice, &LedDevice::start);
// further signals
connect(this, &LedDeviceWrapper::updateLeds, _ledDevice, &LedDevice::updateLeds, Qt::QueuedConnection);
- connect(this, &LedDeviceWrapper::setEnable, _ledDevice, &LedDevice::setEnable);
- connect(this, &LedDeviceWrapper::closeLedDevice, _ledDevice, &LedDevice::stop, Qt::BlockingQueuedConnection);
+
+ connect(this, &LedDeviceWrapper::enable, _ledDevice, &LedDevice::enable);
+ connect(this, &LedDeviceWrapper::disable, _ledDevice, &LedDevice::disable);
+
+ connect(this, &LedDeviceWrapper::switchOn, _ledDevice, &LedDevice::switchOn);
+ connect(this, &LedDeviceWrapper::switchOff, _ledDevice, &LedDevice::switchOff);
+
+ connect(this, &LedDeviceWrapper::stopLedDevice, _ledDevice, &LedDevice::stop, Qt::BlockingQueuedConnection);
connect(_ledDevice, &LedDevice::enableStateChanged, this, &LedDeviceWrapper::handleInternalEnableState, Qt::QueuedConnection);
@@ -155,7 +160,14 @@ void LedDeviceWrapper::handleComponentState(hyperion::Components component, bool
{
if(component == hyperion::COMP_LEDDEVICE)
{
- emit setEnable(state);
+ if ( state )
+ {
+ emit enable();
+ }
+ else
+ {
+ emit disable();
+ }
//Get device's state, considering situations where it is not ready
bool deviceState = false;
@@ -169,13 +181,17 @@ void LedDeviceWrapper::handleInternalEnableState(bool newState)
{
_hyperion->setNewComponentState(hyperion::COMP_LEDDEVICE, newState);
_enabled = newState;
+
+ if (_enabled)
+ {
+ _hyperion->update();
+ }
}
void LedDeviceWrapper::stopDeviceThread()
{
// turns the LEDs off & stop refresh timers
- emit closeLedDevice();
- std::cout << "[hyperiond LedDeviceWrapper] LedDevice \'" << QSTRING_CSTR(getActiveDeviceType()) << "\' closed" << std::endl;
+ emit stopLedDevice();
// get current thread
QThread* oldThread = _ledDevice->thread();
diff --git a/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp b/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp
index 706d59b3..5b45a4d5 100644
--- a/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp
+++ b/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp
@@ -116,11 +116,12 @@ LedDeviceNanoleaf::~LedDeviceNanoleaf()
bool LedDeviceNanoleaf::init(const QJsonObject &deviceConfig)
{
// Overwrite non supported/required features
- _devConfig["latchTime"] = 0;
+ setLatchTime(0);
+ setRewriteTime(0);
+
if (deviceConfig["rewriteTime"].toInt(0) > 0)
{
Info (_log, "Device Nanoleaf does not require rewrites. Refresh time is ignored.");
- _devConfig["rewriteTime"] = 0;
}
DebugIf(verbose, _log, "deviceConfig: [%s]", QString(QJsonDocument(_devConfig).toJson(QJsonDocument::Compact)).toUtf8().constData() );
@@ -133,7 +134,7 @@ bool LedDeviceNanoleaf::init(const QJsonObject &deviceConfig)
Debug(_log, "DeviceType : %s", QSTRING_CSTR( this->getActiveDeviceType() ));
Debug(_log, "LedCount : %u", configuredLedCount);
Debug(_log, "ColorOrder : %s", QSTRING_CSTR( this->getColorOrder() ));
- Debug(_log, "RefreshTime : %d", _refreshTimerInterval_ms);
+ Debug(_log, "RewriteTime : %d", this->getRewriteTime());
Debug(_log, "LatchTime : %d", this->getLatchTime());
// Read panel organisation configuration
@@ -356,8 +357,6 @@ int LedDeviceNanoleaf::open()
int retval = -1;
_isDeviceReady = false;
- // Set Nanoleaf to External Control (UDP) mode
- Debug(_log, "Set Nanoleaf to External Control (UDP) streaming mode");
QJsonDocument responseDoc = changeToExternalControlMode();
// Resolve port for Light Panels
QJsonObject jsonStreamControllInfo = responseDoc.object();
@@ -488,6 +487,8 @@ bool LedDeviceNanoleaf::powerOn()
{
if ( _isDeviceReady)
{
+ changeToExternalControlMode();
+
//Power-on Nanoleaf device
_restApi->setPath(API_STATE);
_restApi->put( getOnOffRequest(true) );
@@ -514,6 +515,7 @@ QString LedDeviceNanoleaf::getOnOffRequest(bool isOn) const
QJsonDocument LedDeviceNanoleaf::changeToExternalControlMode()
{
+ Debug(_log, "Set Nanoleaf to External Control (UDP) streaming mode");
_extControlVersion = EXTCTRLVER_V2;
//Enable UDP Mode v2
diff --git a/libsrc/leddevice/dev_net/LedDeviceWled.cpp b/libsrc/leddevice/dev_net/LedDeviceWled.cpp
index 64b5fec0..4884e3f3 100644
--- a/libsrc/leddevice/dev_net/LedDeviceWled.cpp
+++ b/libsrc/leddevice/dev_net/LedDeviceWled.cpp
@@ -215,15 +215,10 @@ QJsonObject LedDeviceWled::getProperties(const QJsonObject& params)
apiPort = API_DEFAULT_PORT;
}
- if ( filter.startsWith("/") )
- filter.remove(0,1);
-
initRestAPI(apiHost, apiPort);
- _restApi->setPath(API_PATH_INFO);
+ _restApi->setPath(filter);
- // Perform request
- // TODO: WLED::getProperties - Check, if filter is supported
- httpResponse response = _restApi->put(filter);
+ httpResponse response = _restApi->get();
if ( response.error() )
{
Warning (_log, "%s get properties failed with error: '%s'", QSTRING_CSTR(_activeDeviceType), QSTRING_CSTR(response.getErrorReason()));
diff --git a/libsrc/leddevice/dev_net/LedDeviceYeelight.cpp b/libsrc/leddevice/dev_net/LedDeviceYeelight.cpp
index 602c6d5f..2fe39504 100644
--- a/libsrc/leddevice/dev_net/LedDeviceYeelight.cpp
+++ b/libsrc/leddevice/dev_net/LedDeviceYeelight.cpp
@@ -997,10 +997,11 @@ LedDevice* LedDeviceYeelight::construct(const QJsonObject &deviceConfig)
bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
{
// Overwrite non supported/required features
+ setRewriteTime(0);
+
if (deviceConfig["rewriteTime"].toInt(0) > 0)
{
Info (_log, "Yeelights do not require rewrites. Refresh time is ignored.");
- _devConfig["rewriteTime"] = 0;
}
DebugIf(verbose, _log, "deviceConfig: [%s]", QString(QJsonDocument(_devConfig).toJson(QJsonDocument::Compact)).toUtf8().constData() );
@@ -1012,7 +1013,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
Debug(_log, "DeviceType : %s", QSTRING_CSTR( this->getActiveDeviceType() ));
Debug(_log, "LedCount : %u", this->getLedCount());
Debug(_log, "ColorOrder : %s", QSTRING_CSTR( this->getColorOrder() ));
- Debug(_log, "RefreshTime : %d", _refreshTimerInterval_ms);
+ Debug(_log, "RewriteTime : %d", this->getRewriteTime());
Debug(_log, "LatchTime : %d", this->getLatchTime());
//Get device specific configuration
diff --git a/libsrc/leddevice/dev_serial/ProviderRs232.cpp b/libsrc/leddevice/dev_serial/ProviderRs232.cpp
index 735806da..bab2ca6d 100644
--- a/libsrc/leddevice/dev_serial/ProviderRs232.cpp
+++ b/libsrc/leddevice/dev_serial/ProviderRs232.cpp
@@ -193,7 +193,7 @@ void ProviderRs232::setInError(const QString& errorMsg)
int ProviderRs232::writeBytes(const qint64 size, const uint8_t *data)
{
- DebugIf(_isInSwitchOff, _log, "_inClosing [%d], enabled [%d], _deviceReady [%d], _frameDropCounter [%d]", _isInSwitchOff, this->isEnabled(), _isDeviceReady, _frameDropCounter);
+ DebugIf(_isInSwitchOff, _log, "_inClosing [%d], enabled [%d], _deviceReady [%d], _frameDropCounter [%d]", _isInSwitchOff, _isEnabled, _isDeviceReady, _frameDropCounter);
int rc = 0;
if (!_rs232Port.isOpen())
@@ -249,7 +249,7 @@ int ProviderRs232::writeBytes(const qint64 size, const uint8_t *data)
}
}
- DebugIf(_isInSwitchOff, _log, "[%d], _inClosing[%d], enabled [%d], _deviceReady [%d]", rc, _isInSwitchOff, this->isEnabled(), _isDeviceReady);
+ DebugIf(_isInSwitchOff, _log, "[%d], _inClosing[%d], enabled [%d], _deviceReady [%d]", rc, _isInSwitchOff, _isEnabled, _isDeviceReady);
return rc;
}