From 9ca64b8031f7ae0cd1d40dab087d7c185e074665 Mon Sep 17 00:00:00 2001 From: Awawa Date: Mon, 19 Sep 2022 21:03:11 +0200 Subject: [PATCH 1/2] Save/restore WLED state and set max brightness at startup --- sources/leddevice/dev_net/LedDeviceWled.cpp | 91 ++++++++++----------- sources/leddevice/dev_net/LedDeviceWled.h | 17 +--- sources/leddevice/schemas/schema-wled.json | 16 +++- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/sources/leddevice/dev_net/LedDeviceWled.cpp b/sources/leddevice/dev_net/LedDeviceWled.cpp index 047a01747..47bf442fe 100644 --- a/sources/leddevice/dev_net/LedDeviceWled.cpp +++ b/sources/leddevice/dev_net/LedDeviceWled.cpp @@ -32,6 +32,8 @@ LedDeviceWled::LedDeviceWled(const QJsonObject& deviceConfig) : ProviderUdp(deviceConfig) , _restApi(nullptr) , _apiPort(API_DEFAULT_PORT) + , _maxBright(true) + , _restoreConfig(false) { } @@ -47,20 +49,29 @@ LedDevice* LedDeviceWled::construct(const QJsonObject& deviceConfig) } bool LedDeviceWled::init(const QJsonObject& deviceConfig) -{ - Debug(_log, ""); +{ bool isInitOK = false; + Debug(_log, "Initializing WLED"); + + _configBackup = QJsonDocument(); + // Initialise LedDevice sub-class, ProviderUdp::init will be executed later, if connectivity is defined if (LedDevice::init(deviceConfig)) { // Initialise LedDevice configuration and execution environment int configuredLedCount = this->getLedCount(); - Debug(_log, "DeviceType : %s", QSTRING_CSTR(this->getActiveDeviceType())); - Debug(_log, "LedCount : %d", configuredLedCount); + Debug(_log, "DeviceType : %s", QSTRING_CSTR(this->getActiveDeviceType())); + Debug(_log, "LedCount : %d", configuredLedCount); + + _maxBright = deviceConfig["brightnessMax"].toBool(true); + Debug(_log, "Max brightness : %s", (_maxBright) ? "true" : "false"); + + _restoreConfig = deviceConfig["restoreOriginalState"].toBool(false); + Debug(_log, "Restore WLED : %s", (_restoreConfig) ? "true" : "false"); _maxRetry = deviceConfig["maxRetry"].toInt(60); - Debug(_log, "Max retry : %d", _maxRetry); + Debug(_log, "Max retry : %d", _maxRetry); //Set hostname as per configuration QString address = deviceConfig[CONFIG_ADDRESS].toString(); @@ -119,8 +130,16 @@ bool LedDeviceWled::initRestAPI(const QString& hostname, int port) QString LedDeviceWled::getOnOffRequest(bool isOn) const { - QString state = isOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE; - return QString("{\"on\":%1,\"live\":%1}").arg(state); + if (!isOn && _restoreConfig && !_configBackup.isEmpty()) + { + return QString(_configBackup.toJson(QJsonDocument::Compact)); + } + else + { + QString state = isOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE; + QString bri = (_maxBright && isOn) ? ",\"bri\":255" : ""; + return QString("{\"on\":%1,\"live\":%1%2}").arg(state).arg(bri); + } } bool LedDeviceWled::powerOn() @@ -133,7 +152,24 @@ bool LedDeviceWled::powerOn() { //Power-on WLED device _restApi->setPath(API_PATH_STATE); - httpResponse response = _restApi->put(getOnOffRequest(true)); + + bool readConfig = _restoreConfig && _configBackup.isEmpty(); + httpResponse response = (readConfig) ? _restApi->get() : _restApi->put(getOnOffRequest(true)); + + if (readConfig && !response.error()) + { + _configBackup = response.getBody(); + + if (_configBackup.isObject()) + { + auto copy = _configBackup.object(); + copy["live"] = false; + _configBackup.setObject(copy); + } + + response = _restApi->put(getOnOffRequest(true)); + } + if (response.error()) { this->setInError(response.getErrorReason()); @@ -271,45 +307,6 @@ QJsonObject LedDeviceWled::getProperties(const QJsonObject& params) return properties; } -void LedDeviceWled::identify(const QJsonObject& /*params*/) -{ -#if 0 - Debug(_log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData()); - - QString host = params["host"].toString(""); - if (!host.isEmpty()) - { - // Resolve hostname and port (or use default API port) - QStringList addressparts = QStringUtils::split(host, ":", QStringUtils::SplitBehavior::SkipEmptyParts); - QString apiHost = addressparts[0]; - int apiPort; - - if (addressparts.size() > 1) - apiPort = addressparts[1].toInt(); - else - apiPort = API_DEFAULT_PORT; - - // TODO: WLED::identify - Replace with valid identification code - - // initRestAPI(apiHost, apiPort); - - // QString resource = QString("%1/%2/%3").arg( API_LIGHTS ).arg( lightId ).arg( API_STATE); - // _restApi->setPath(resource); - - // QString stateCmd; - // stateCmd += QString("\"%1\":%2,").arg( API_STATE_ON ).arg( API_STATE_VALUE_TRUE ); - // stateCmd += QString("\"%1\":\"%2\"").arg( "alert" ).arg( "select" ); - // stateCmd = "{" + stateCmd + "}"; - - // // Perform request - // httpResponse response = _restApi->put(stateCmd); - // if ( response.error() ) - // { - // Warning (_log, "%s identification failed with error: '%s'", QSTRING_CSTR(_activeDeviceType), QSTRING_CSTR(response.getErrorReason())); - // } - } -#endif -} int LedDeviceWled::write(const std::vector& ledValues) { diff --git a/sources/leddevice/dev_net/LedDeviceWled.h b/sources/leddevice/dev_net/LedDeviceWled.h index f6d464ddf..de63fd067 100644 --- a/sources/leddevice/dev_net/LedDeviceWled.h +++ b/sources/leddevice/dev_net/LedDeviceWled.h @@ -60,20 +60,6 @@ class LedDeviceWled : public ProviderUdp /// QJsonObject getProperties(const QJsonObject& params) override; - /// - /// @brief Send an update to the WLED device to identify it. - /// - /// Following parameters are required - /// @code - /// { - /// "host" : "hostname or IP [:port]", - /// } - ///@endcode - /// - /// @param[in] params Parameters to address device - /// - void identify(const QJsonObject& params) override; - protected: /// @@ -130,6 +116,9 @@ class LedDeviceWled : public ProviderUdp QString _hostname; int _apiPort; + bool _maxBright; + bool _restoreConfig; + QJsonDocument _configBackup; }; #endif // LEDDEVICEWLED_H diff --git a/sources/leddevice/schemas/schema-wled.json b/sources/leddevice/schemas/schema-wled.json index 1ed9f9c35..2d29d75f9 100644 --- a/sources/leddevice/schemas/schema-wled.json +++ b/sources/leddevice/schemas/schema-wled.json @@ -7,6 +7,20 @@ "title":"edt_dev_spec_targetIpHost_title", "propertyOrder" : 1 }, + "brightnessMax": { + "type": "boolean", + "title":"edt_dev_spec_brightnessMax_title", + "format": "checkbox", + "default" : true, + "propertyOrder" : 2 + }, + "restoreOriginalState": { + "type": "boolean", + "format": "checkbox", + "title":"edt_dev_spec_restoreOriginalState_title", + "default" : false, + "propertyOrder" : 3 + }, "maxRetry": { "type" : "integer", @@ -17,7 +31,7 @@ "maximum" : 300, "default" : 60, "required" : true, - "propertyOrder" : 2 + "propertyOrder" : 4 } }, "additionalProperties": true From 6d328022539db5fe80dc56c9cca1a5529c4a25de Mon Sep 17 00:00:00 2001 From: Awawa Date: Wed, 28 Sep 2022 00:50:28 +0200 Subject: [PATCH 2/2] Custom WLED brightness level --- assets/webconfig/i18n/en.json | 2 + assets/webconfig/js/content_huebridge.js | 52 --------------------- sources/leddevice/dev_net/LedDeviceWled.cpp | 20 ++++---- sources/leddevice/dev_net/LedDeviceWled.h | 3 +- sources/leddevice/schemas/schema-wled.json | 23 +++++++-- 5 files changed, 33 insertions(+), 67 deletions(-) delete mode 100644 assets/webconfig/js/content_huebridge.js diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 9eb7664c1..09c311b8d 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -1164,6 +1164,8 @@ "philips_option_changed_bri": "

First set up your Philips LED lamps using the Philips mobile app: during setup, select the ENTERTAINMENT group for your lamps (you should get the ID of this group). Otherwise, communication performance using the old json API will be very bad!

Remember that using other home automation systems connected to lamps can cause various side effects when running HyperHDR.", "select_wled_intro" : "Select WLED", "select_wled_rescan" : "Rescan network", + "wledBrightnessOverride" : "Override WLED brightness", + "wledCustomBrightnessLevel" : "Custom WLED brightness level", "edt_conf_mqtt_heading_title" : "MQTT client", "conf_network_mqtt_intro" : "Registration of HyperHDR services with the MQTT broker", "edt_conf_mqtt_ip_title" : "Hostname", diff --git a/assets/webconfig/js/content_huebridge.js b/assets/webconfig/js/content_huebridge.js deleted file mode 100644 index 7f9001fce..000000000 --- a/assets/webconfig/js/content_huebridge.js +++ /dev/null @@ -1,52 +0,0 @@ -$(document).ready( function() { - - $("#create_user").on("click", function() { - var connectionRetries = 15; - var data = {"devicetype":"hyperhdr#"+Date.now()}; - var UserInterval = setInterval(function(){ - $.ajax({ - type: "POST", - url: 'http://'+$("#ip").val()+'/api', - processData: false, - timeout: 1000, - contentType: 'application/json', - data: JSON.stringify(data), - success: function(r) { - connectionRetries--; - $("#connectionTime").html(connectionRetries); - if(connectionRetries == 0) { - abortConnection(UserInterval); - } - else - { - $("#abortConnection").hide(); - $('#pairmodal').modal('show'); - $("#ip_alert").hide(); - if (typeof r[0].error != 'undefined') { - console.log("link not pressed"); - } - if (typeof r[0].success != 'undefined') { - $('#pairmodal').modal('hide'); - $('#user').val(r[0].success.username); - - $( "#hue_lights" ).empty(); - get_hue_lights(); - clearInterval(UserInterval); - } - } - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - $("#ip_alert").show(); - clearInterval(UserInterval); - } - }); - },1000); -}); - -function abortConnection(UserInterval){ - clearInterval(UserInterval); - $("#abortConnection").show(); - $('#pairmodal').modal('hide'); -} - -}); diff --git a/sources/leddevice/dev_net/LedDeviceWled.cpp b/sources/leddevice/dev_net/LedDeviceWled.cpp index 47bf442fe..a0538f4d6 100644 --- a/sources/leddevice/dev_net/LedDeviceWled.cpp +++ b/sources/leddevice/dev_net/LedDeviceWled.cpp @@ -32,7 +32,8 @@ LedDeviceWled::LedDeviceWled(const QJsonObject& deviceConfig) : ProviderUdp(deviceConfig) , _restApi(nullptr) , _apiPort(API_DEFAULT_PORT) - , _maxBright(true) + , _overrideBrightness(true) + , _brightnessLevel(255) , _restoreConfig(false) { } @@ -64,8 +65,11 @@ bool LedDeviceWled::init(const QJsonObject& deviceConfig) Debug(_log, "DeviceType : %s", QSTRING_CSTR(this->getActiveDeviceType())); Debug(_log, "LedCount : %d", configuredLedCount); - _maxBright = deviceConfig["brightnessMax"].toBool(true); - Debug(_log, "Max brightness : %s", (_maxBright) ? "true" : "false"); + _overrideBrightness = deviceConfig["brightnessMax"].toBool(true); + Debug(_log, "Override brightness : %s", (_overrideBrightness) ? "true" : "false"); + + _brightnessLevel = deviceConfig["brightnessMaxLevel"].toInt(255); + Debug(_log, "Set brightness level: %i", _brightnessLevel); _restoreConfig = deviceConfig["restoreOriginalState"].toBool(false); Debug(_log, "Restore WLED : %s", (_restoreConfig) ? "true" : "false"); @@ -137,7 +141,7 @@ QString LedDeviceWled::getOnOffRequest(bool isOn) const else { QString state = isOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE; - QString bri = (_maxBright && isOn) ? ",\"bri\":255" : ""; + QString bri = (_overrideBrightness && isOn) ? QString(",\"bri\":%1").arg(_brightnessLevel) : ""; return QString("{\"on\":%1,\"live\":%1%2}").arg(state).arg(bri); } } @@ -146,7 +150,6 @@ bool LedDeviceWled::powerOn() { Debug(_log, ""); bool on = false; - auto current = QDateTime::currentMSecsSinceEpoch(); if (!_retryMode) { @@ -188,15 +191,10 @@ bool LedDeviceWled::powerOn() else Error(_log, "The WLED device is not ready... give up."); - - auto delta = QDateTime::currentMSecsSinceEpoch() - current; - - delta = qMin(qMax(1000ll - delta, 50ll), 1000ll); - if (_currentRetry > 0) { _retryMode = true; - QTimer::singleShot(delta, [this]() { _retryMode = false; if (_currentRetry > 0) enableDevice(true); }); + QTimer::singleShot(1000, [this]() { _retryMode = false; if (_currentRetry > 0) enableDevice(true); }); } } } diff --git a/sources/leddevice/dev_net/LedDeviceWled.h b/sources/leddevice/dev_net/LedDeviceWled.h index de63fd067..1d20a34cb 100644 --- a/sources/leddevice/dev_net/LedDeviceWled.h +++ b/sources/leddevice/dev_net/LedDeviceWled.h @@ -116,7 +116,8 @@ class LedDeviceWled : public ProviderUdp QString _hostname; int _apiPort; - bool _maxBright; + bool _overrideBrightness; + int _brightnessLevel; bool _restoreConfig; QJsonDocument _configBackup; }; diff --git a/sources/leddevice/schemas/schema-wled.json b/sources/leddevice/schemas/schema-wled.json index 2d29d75f9..927ca7301 100644 --- a/sources/leddevice/schemas/schema-wled.json +++ b/sources/leddevice/schemas/schema-wled.json @@ -9,17 +9,34 @@ }, "brightnessMax": { "type": "boolean", - "title":"edt_dev_spec_brightnessMax_title", + "title":"wledBrightnessOverride", "format": "checkbox", "default" : true, "propertyOrder" : 2 + }, + "brightnessMaxLevel": + { + "type" : "integer", + "format" : "stepper", + "step" : 1, + "title" : "wledCustomBrightnessLevel", + "minimum" : 1, + "maximum" : 255, + "default" : 255, + "options": { + "dependencies": { + "brightnessMax": true + } + }, + "required" : true, + "propertyOrder" : 3 }, "restoreOriginalState": { "type": "boolean", "format": "checkbox", "title":"edt_dev_spec_restoreOriginalState_title", "default" : false, - "propertyOrder" : 3 + "propertyOrder" : 4 }, "maxRetry": { @@ -31,7 +48,7 @@ "maximum" : 300, "default" : 60, "required" : true, - "propertyOrder" : 4 + "propertyOrder" : 5 } }, "additionalProperties": true