diff --git a/assets/webconfig/js/hyperion.js b/assets/webconfig/js/hyperion.js index a3dd781f..b38997ed 100644 --- a/assets/webconfig/js/hyperion.js +++ b/assets/webconfig/js/hyperion.js @@ -470,6 +470,8 @@ async function requestLedDeviceProperties(type, params) function requestLedDeviceIdentification(type, params) { - sendToHyperion("leddevice", "identify", '"ledDeviceType": "'+type+'","params": '+JSON.stringify(params)+''); + //sendToHyperion("leddevice", "identify", '"ledDeviceType": "'+type+'","params": '+JSON.stringify(params)+''); + let data = { ledDeviceType: type, params: params }; + return sendAsyncToHyperion("leddevice", "identify", data, Math.floor(Math.random() * 1000)); } diff --git a/assets/webconfig/js/wizard.js b/assets/webconfig/js/wizard.js index 19c3ead4..36bc09aa 100644 --- a/assets/webconfig/js/wizard.js +++ b/assets/webconfig/js/wizard.js @@ -826,9 +826,17 @@ async function getProperties_hue_bridge(hostAddress, username, resourceFilter) { } } -function identify_hue_device(hostAddress, username, id) { +async function identify_hue_device(hostAddress, username, id) { + + // Take care that new record cannot be save during background process + $('#btn_wiz_save').attr('disabled', true); + let params = { host: hostAddress, user: username, lightId: id }; - requestLedDeviceIdentification("philipshue", params); + const res = await requestLedDeviceIdentification('philipshue', params); + + if (!window.readOnlyMode) { + $('#btn_wiz_save').attr('disabled', false); + } } function getHueIPs() { @@ -1289,9 +1297,17 @@ async function getProperties_wled(hostAddress, resourceFilter) { } } -function identify_wled(hostAddress) { +async function identify_wled(hostAddress) { + + // Take care that new record cannot be save during background process + $('#btn_wiz_save').attr('disabled', true); + let params = { host: hostAddress }; - requestLedDeviceIdentification("wled", params); + const res = await requestLedDeviceIdentification('wled', params); + + if (!window.readOnlyMode) { + $('#btn_wiz_save').attr('disabled', false); + } } //**************************** @@ -1538,9 +1554,17 @@ async function getProperties_yeelight(hostname, port) { } } -function identify_yeelight_device(hostname, port) { +async function identify_yeelight_device(hostname, port) { + + // Take care that new record cannot be save during background process + $('#btn_wiz_save').attr('disabled', true); + let params = { hostname: hostname, port: port }; - requestLedDeviceIdentification("yeelight", params); + const res = await requestLedDeviceIdentification("yeelight", params); + + if (!window.readOnlyMode) { + $('#btn_wiz_save').attr('disabled', false); + } } //**************************** @@ -1774,9 +1798,17 @@ function assign_atmoorb_lights() { } } -function identify_atmoorb_device(orbId) { +async function identify_atmoorb_device(orbId) { + + // Take care that new record cannot be save during background process + $('#btn_wiz_save').attr('disabled', true); + let params = { id: orbId }; - requestLedDeviceIdentification("atmoorb", params); + const res = await requestLedDeviceIdentification("atmoorb", params); + + if (!window.readOnlyMode) { + $('#btn_wiz_save').attr('disabled', false); + } } //**************************** @@ -1823,9 +1855,17 @@ async function getProperties_nanoleaf(hostAddress, authToken, resourceFilter) { } } -function identify_nanoleaf(hostAddress, authToken) { +async function identify_nanoleaf(hostAddress, authToken) { + + // Take care that new record cannot be save during background process + $('#btn_wiz_save').attr('disabled', true); + let params = { host: hostAddress, token: authToken }; - requestLedDeviceIdentification("nanoleaf", params); + const res = await requestLedDeviceIdentification('nanoleaf', params); + + if (!window.readOnlyMode) { + $('#btn_wiz_save').attr('disabled', false); + } } //**************************** @@ -1890,15 +1930,13 @@ function beginWizardCololight() { d.host = lights[selectedLightId].ip; } - var coloLightProperties = lights[selectedLightId].props; + var coloLightProperties = lights[selectedLightId].props.properties; if (Object.keys(coloLightProperties).length === 0) { alert($.i18n('wiz_cololight_noprops')); d.hardwareLedCount = 1; - } else { - if (coloLightProperties.ledCount > 0) { + } + else { d.hardwareLedCount = coloLightProperties.ledCount; - } else if (coloLightProperties.modelType === "Strip") - d.hardwareLedCount = 120; } d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue(); @@ -2011,9 +2049,17 @@ async function getProperties_cololight(ip) { } } -function identify_cololight_device(hostAddress) { +async function identify_cololight_device(hostAddress) { + + // Take care that new record cannot be save during background process + $('#btn_wiz_save').attr('disabled', true); + let params = { host: hostAddress }; - requestLedDeviceIdentification("cololight", params); + const res = await requestLedDeviceIdentification('cololight', params); + + if (!window.readOnlyMode) { + $('#btn_wiz_save').attr('disabled', false); + } } //**************************** diff --git a/libsrc/leddevice/dev_net/LedDeviceCololight.cpp b/libsrc/leddevice/dev_net/LedDeviceCololight.cpp index 98a47cef..a6bac06f 100644 --- a/libsrc/leddevice/dev_net/LedDeviceCololight.cpp +++ b/libsrc/leddevice/dev_net/LedDeviceCololight.cpp @@ -17,6 +17,8 @@ const bool verbose3 = false; const char CONFIG_HW_LED_COUNT[] = "hardwareLedCount"; +const int COLOLIGHT_BEADS_PER_MODULE = 19; + // Cololight discovery service const int API_DEFAULT_PORT = 8900; @@ -24,7 +26,7 @@ const int API_DEFAULT_PORT = 8900; const char DISCOVERY_ADDRESS[] = "255.255.255.255"; const quint16 DISCOVERY_PORT = 12345; const char DISCOVERY_MESSAGE[] = "Z-SEARCH * \r\n"; -constexpr std::chrono::milliseconds DEFAULT_DISCOVERY_TIMEOUT{ 5000 }; +constexpr std::chrono::milliseconds DEFAULT_DISCOVERY_TIMEOUT{ 2000 }; constexpr std::chrono::milliseconds DEFAULT_READ_TIMEOUT{ 1000 }; constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 2000 }; @@ -34,16 +36,12 @@ const char COLOLIGHT_MAC[] = "sn"; const char COLOLIGHT_NAME[] = "name"; const char COLOLIGHT_MODEL_IDENTIFIER[] = "OD_WE_QUAN"; - -const int COLOLIGHT_BEADS_PER_MODULE = 19; -const int COLOLIGHT_MIN_STRIP_SEGMENT_SIZE = 30; - } //End of constants LedDeviceCololight::LedDeviceCololight(const QJsonObject& deviceConfig) : ProviderUdp(deviceConfig) , _modelType(-1) - , _ledLayoutType(STRIP_LAYOUT) + , _ledLayoutType(-1) , _ledBeadCount(0) , _distance(0) , _sequenceNumber(1) @@ -94,11 +92,11 @@ bool LedDeviceCololight::initLedsConfiguration() QString modelTypeText; switch (_modelType) { - case 0: + case STRIP: modelTypeText = "Strip"; _ledLayoutType = STRIP_LAYOUT; break; - case 1: + case PLUS: _ledLayoutType = MODLUE_LAYOUT; modelTypeText = "Plus"; break; @@ -116,33 +114,24 @@ bool LedDeviceCololight::initLedsConfiguration() setLedCount(_devConfig[CONFIG_HW_LED_COUNT].toInt(0)); } - if (_modelType == STRIP && (getLedCount() % COLOLIGHT_MIN_STRIP_SEGMENT_SIZE != 0)) + Debug(_log, "LedCount : %d", getLedCount()); + + int configuredLedCount = _devConfig["currentLedCount"].toInt(1); + + if (getLedCount() < configuredLedCount) { - QString errorReason = QString("Hardware LED count must be multiple of %1 for Cololight Strip!") - .arg(COLOLIGHT_MIN_STRIP_SEGMENT_SIZE); + QString errorReason = QString("Not enough LEDs [%1] for configured LEDs in layout [%2] found!") + .arg(getLedCount()) + .arg(configuredLedCount); this->setInError(errorReason); } else { - Debug(_log, "LedCount : %d", getLedCount()); - - int configuredLedCount = _devConfig["currentLedCount"].toInt(1); - - if (getLedCount() < configuredLedCount) + if (getLedCount() > configuredLedCount) { - QString errorReason = QString("Not enough LEDs [%1] for configured LEDs in layout [%2] found!") - .arg(getLedCount()) - .arg(configuredLedCount); - this->setInError(errorReason); - } - else - { - if (getLedCount() > configuredLedCount) - { - Info(_log, "%s: More LEDs [%d] than configured LEDs in layout [%d].", QSTRING_CSTR(this->getActiveDeviceType()), getLedCount(), configuredLedCount); - } - isInitOK = true; + Info(_log, "%s: More LEDs [%d] than configured LEDs in layout [%d].", QSTRING_CSTR(this->getActiveDeviceType()), getLedCount(), configuredLedCount); } + isInitOK = true; } } @@ -204,22 +193,35 @@ bool LedDeviceCololight::getInfo() if (ledNum != 0xFFFF) { _ledBeadCount = ledNum; + // Cololight types are not identifyable currently + // Work under the assumption that modules (Cololight Plus) have a number of beads and a Colologht Strip does not have a multiple of beads + // The assumption will not hold true, if a user cuts the Strip to a multiple of beads... if (ledNum % COLOLIGHT_BEADS_PER_MODULE == 0) { - _modelType = MODLUE_LAYOUT; + _modelType = PLUS; + _ledLayoutType = MODLUE_LAYOUT; _distance = ledNum / COLOLIGHT_BEADS_PER_MODULE; setLedCount(_distance); } + else + { + _modelType = STRIP; + _ledLayoutType = STRIP_LAYOUT; + _distance = 0; + setLedCount(ledNum); + } + isCmdOK = true; + Debug(_log, "#LEDs found [0x%x], [%u], distance [%d]", _ledBeadCount, _ledBeadCount, _distance); } else { - _modelType = STRIP; + _modelType = -1; + _ledLayoutType = -1; + _distance = 0; setLedCount(0); + isCmdOK = false; + Error(_log, "Number of LEDs cannot be resolved"); } - - Debug(_log, "#LEDs found [0x%x], [%u], distance [%d]", _ledBeadCount, _ledBeadCount, _distance); - - isCmdOK = true; } } @@ -545,20 +547,15 @@ bool LedDeviceCololight::powerOff() return off; } -QJsonObject LedDeviceCololight::discover(const QJsonObject& /*params*/) +QJsonArray LedDeviceCololight::discover() { - QJsonObject devicesDiscovered; - devicesDiscovered.insert("ledDeviceType", _activeDeviceType); - - QJsonArray deviceList; - QUdpSocket udpSocket; udpSocket.writeDatagram(QString(DISCOVERY_MESSAGE).toUtf8(), QHostAddress(DISCOVERY_ADDRESS), DISCOVERY_PORT); if (udpSocket.waitForReadyRead(DEFAULT_DISCOVERY_TIMEOUT.count())) { - while (udpSocket.waitForReadyRead(500)) + while (udpSocket.waitForReadyRead(200)) { QByteArray datagram; @@ -602,6 +599,7 @@ QJsonObject LedDeviceCololight::discover(const QJsonObject& /*params*/) } } + QJsonArray deviceList; QMap>::iterator i; for (i = _services.begin(); i != _services.end(); ++i) { @@ -647,9 +645,23 @@ QJsonObject LedDeviceCololight::discover(const QJsonObject& /*params*/) deviceList << obj; } + return deviceList; +} +QJsonObject LedDeviceCololight::discover(const QJsonObject& /*params*/) +{ + QJsonObject devicesDiscovered; + devicesDiscovered.insert("ledDeviceType", _activeDeviceType); + + QString discoveryMethod("ssdp"); + QJsonArray deviceList; + + deviceList = discover(); + + devicesDiscovered.insert("discoveryMethod", discoveryMethod); devicesDiscovered.insert("devices", deviceList); - DebugIf(verbose, _log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData()); + + //Debug(_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData()); return devicesDiscovered; } @@ -662,6 +674,7 @@ QJsonObject LedDeviceCololight::getProperties(const QJsonObject& params) QString apiHostname = params["host"].toString(""); quint16 apiPort = static_cast(params["port"].toInt(API_DEFAULT_PORT)); + QJsonObject propertiesDetails; if (!apiHostname.isEmpty()) { QJsonObject deviceConfig; @@ -675,21 +688,26 @@ QJsonObject LedDeviceCololight::getProperties(const QJsonObject& params) QString modelTypeText; switch (_modelType) { - case 1: + case STRIP: + modelTypeText = "Strip"; + break; + case PLUS: modelTypeText = "Plus"; break; default: modelTypeText = "Strip"; break; } - properties.insert("modelType", modelTypeText); - properties.insert("ledCount", static_cast(getLedCount())); - properties.insert("ledBeadCount", _ledBeadCount); - properties.insert("distance", _distance); + propertiesDetails.insert("modelType", modelTypeText); + propertiesDetails.insert("ledCount", static_cast(getLedCount())); + propertiesDetails.insert("ledBeadCount", _ledBeadCount); + propertiesDetails.insert("distance", _distance); } } } + properties.insert("properties", propertiesDetails); + DebugIf(verbose, _log, "properties: [%s]", QString(QJsonDocument(properties).toJson(QJsonDocument::Compact)).toUtf8().constData()); return properties; diff --git a/libsrc/leddevice/dev_net/LedDeviceCololight.h b/libsrc/leddevice/dev_net/LedDeviceCololight.h index 7d9365be..0818176b 100644 --- a/libsrc/leddevice/dev_net/LedDeviceCololight.h +++ b/libsrc/leddevice/dev_net/LedDeviceCololight.h @@ -284,6 +284,14 @@ private: /// bool readResponse(QByteArray& response); + /// + /// @brief Discover Cololight devices available (for configuration). + /// Cololight specific UDP Broadcast discovery + /// + /// @return A JSON structure holding a list of devices found + /// + QJsonArray discover(); + // Cololight model, e.g. CololightPlus, CololightStrip int _modelType;