diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json index 9a6fd87f..34218a95 100644 --- a/assets/webconfig/i18n/de.json +++ b/assets/webconfig/i18n/de.json @@ -137,7 +137,7 @@ "conf_leds_optgroup_RPiPWM": "RPi PWM", "conf_leds_optgroup_RPiGPIO": "RPi GPIO", "conf_leds_optgroup_network": "Netzwerk", - "conf_leds_optgroup_usb": "USB", + "conf_leds_optgroup_usb": "USB/Seriell", "conf_leds_optgroup_debug": "Debug", "conf_leds_layout_btn_checklist": "Zeige Checkliste", "conf_leds_layout_checkp1": "Die schwarze eingefärbte LED ist die erste LED. Das ist der Punkt, an dem die Daten eingespeist werden.", @@ -487,6 +487,10 @@ "edt_dev_spec_clientKey_title": "Clientkey", "edt_dev_spec_printTimeStamp_title" : "Mit Zeitstempel", "edt_dev_spec_groupId_title": "Gruppen ID", + "edt_dev_spec_panelorganisation_title" : "Nummerierungsreihenfolge der Panels", + "edt_dev_spec_order_top_down_title" : "1.", + "edt_dev_spec_order_left_right_title" : "2.", + "edt_dev_spec_panel_start_position" : "Startpanel [0-max Panels]", "edt_conf_general_enable_title": "Aktiviert", "edt_conf_general_enable_expl": "Wenn aktiviert, ist die Komponente aktiv.", "edt_conf_general_priority_title": "Priorität", @@ -522,6 +526,10 @@ "edt_conf_enum_dl_informational": "informativ", "edt_conf_enum_dl_verbose": "sehr detailiert", "edt_conf_enum_custom": "Benutzerdefiniert", + "edt_conf_enum_bottom_up": "von unten nach oben", + "edt_conf_enum_top_down": "von oben nach unten", + "edt_conf_enum_right_left": "von rechts and links", + "edt_conf_enum_left_right": "von links nach rechts", "edt_conf_gen_heading_title": "Allgemeine Einstellungen", "edt_conf_gen_name_title": "Name der Konfiguration", "edt_conf_gen_name_expl": "Der Name wird verwendet, um Hyperion besser zu identifizieren. (Hilfreich bei mehreren Instanzen)", diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index b4309f65..98fd39ff 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -137,7 +137,7 @@ "conf_leds_optgroup_RPiPWM" : "RPi PWM", "conf_leds_optgroup_RPiGPIO" : "RPi GPIO", "conf_leds_optgroup_network" : "Network", - "conf_leds_optgroup_usb" : "USB", + "conf_leds_optgroup_usb" : "USB/Serial", "conf_leds_optgroup_debug" : "Debug", "conf_leds_layout_btn_checklist" : "Show checklist", "conf_leds_layout_checkp1" : "The black led is your first led, the first led is the point where you input your data signal.", @@ -488,6 +488,10 @@ "edt_dev_spec_printTimeStamp_title" : "Add timestamp", "edt_dev_spec_clientKey_title" : "Clientkey", "edt_dev_spec_groupId_title" : "Group Id", + "edt_dev_spec_panelorganisation_title" : "Panel numbering sequence", + "edt_dev_spec_order_top_down_title" : "1.", + "edt_dev_spec_order_left_right_title" : "2.", + "edt_dev_spec_panel_start_position" : "Startpanel [0-max panels]", "edt_conf_general_enable_title" : "Activate", "edt_conf_general_enable_expl" : "If checked, the component is enabled.", "edt_conf_general_priority_title" : "Priority channel", @@ -523,6 +527,10 @@ "edt_conf_enum_dl_informational": "Informational", "edt_conf_enum_dl_verbose": "Verbose", "edt_conf_enum_custom": "Custom", + "edt_conf_enum_bottom_up": "Bottom up", + "edt_conf_enum_top_down": "Top down", + "edt_conf_enum_right_left": "Right to left", + "edt_conf_enum_left_right": "Left to right", "edt_conf_gen_heading_title" : "General Settings", "edt_conf_gen_name_title" : "Configuration name", "edt_conf_gen_name_expl" : "A user defined name which is used to detect Hyperion. (Helpful with more than one Hyperion instance)", diff --git a/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp b/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp index 665c2b6c..e734592a 100644 --- a/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp +++ b/libsrc/leddevice/dev_net/LedDeviceNanoleaf.cpp @@ -21,6 +21,10 @@ static const char CONFIG_ADDRESS[] = "host"; //static const char CONFIG_PORT[] = "port"; static const char CONFIG_AUTH_TOKEN[] ="token"; +static const char CONFIG_PANEL_ORDER_TOP_DOWN[] ="panelOrderTopDown"; +static const char CONFIG_PANEL_ORDER_LEFT_RIGHT[] ="panelOrderLeftRight"; +static const char CONFIG_PANEL_START_POS[] ="panelStartPos"; + // Panel configuration settings static const char PANEL_LAYOUT[] = "layout"; static const char PANEL_NUM[] = "numPanels"; @@ -123,6 +127,19 @@ bool LedDeviceNanoleaf::init(const QJsonObject &deviceConfig) Debug(_log, "RefreshTime : %d", _refresh_timer_interval); Debug(_log, "LatchTime : %d", this->getLatchTime()); + // Read panel organisation configuration + if ( deviceConfig[ CONFIG_PANEL_ORDER_TOP_DOWN ].isString() ) + _topDown = deviceConfig[ CONFIG_PANEL_ORDER_TOP_DOWN ].toString().toInt() == 0 ? true : false; + else + _topDown = deviceConfig[ CONFIG_PANEL_ORDER_TOP_DOWN ].toInt() == 0 ? true : false; + + if ( deviceConfig[ CONFIG_PANEL_ORDER_LEFT_RIGHT ].isString() ) + _leftRight = deviceConfig[ CONFIG_PANEL_ORDER_LEFT_RIGHT ].toString().toInt() == 0 ? true : false; + else + _leftRight = deviceConfig[ CONFIG_PANEL_ORDER_LEFT_RIGHT ].toInt() == 0 ? true : false; + + _startPos = deviceConfig[ CONFIG_PANEL_START_POS ].toInt(0); + //Set hostname as per configuration and_defaultHost default port _hostname = deviceConfig[ CONFIG_ADDRESS ].toString(); _api_port = API_DEFAULT_PORT; @@ -211,30 +228,57 @@ bool LedDeviceNanoleaf::initLeds() } } - // Sort panels top down, left right + // Travers panels top down for(auto posY = panelMap.crbegin(); posY != panelMap.crend(); ++posY) { - // posY.first is the first key - for(auto const &posX : posY->second) + // Sort panels left to right + if ( _leftRight ) { - // posX.first is the second key, posX.second is the data - DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX.first, posX.second ); - _panelIds.push_back(posX.second); + for( auto posX = posY->second.cbegin(); posX != posY->second.cend(); ++posX) + { + DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX->first, posX->second ); + + if ( _topDown ) + _panelIds.push_back(posX->second); + else + _panelIds.push_front(posX->second); + } + } + else + { + // Sort panels right to left + for( auto posX = posY->second.crbegin(); posX != posY->second.crend(); ++posX) + { + DebugIf(verbose3, _log, "panelMap[%u][%u]=%u", posY->first, posX->first, posX->second ); + + if ( _topDown ) + _panelIds.push_back(posX->second); + else + _panelIds.push_front(posX->second); + } } } + this->_panelLedCount = static_cast(_panelIds.size()); _devConfig["hardwareLedCount"] = static_cast(_panelLedCount); Debug(_log, "PanelsNum : %u", panelNum); Debug(_log, "PanelLedCount : %u", _panelLedCount); - // Check. if enough panelds were found. + // Check. if enough panels were found. uint configuredLedCount = this->getLedCount(); + _endPos = _startPos + configuredLedCount - 1; + + Debug(_log, "Sort Top>Down : %d", _topDown); + Debug(_log, "Sort Left>Right: %d", _leftRight); + Debug(_log, "Start Panel Pos: %u", _startPos); + Debug(_log, "End Panel Pos : %u", _endPos); + if (_panelLedCount < configuredLedCount ) { QString errorReason = QString("Not enough panels [%1] for configured LEDs [%2] found!") - .arg(_panelLedCount) - .arg(configuredLedCount); + .arg(_panelLedCount) + .arg(configuredLedCount); this->setInError(errorReason); isInitOK = false; } @@ -242,10 +286,21 @@ bool LedDeviceNanoleaf::initLeds() { if ( _panelLedCount > this->getLedCount() ) { - Warning(_log, "Nanoleaf: More panels [%u] than configured LEDs [%u].", _panelLedCount, configuredLedCount ); + Info(_log, "Nanoleaf: More panels [%u] than configured LEDs [%u].", _panelLedCount, configuredLedCount ); + } + + // Check, if start position + number of configured LEDs is greater than number of panels available + if ( _endPos >= _panelLedCount ) + { + QString errorReason = QString("Start panel [%1] out of range. Start panel position can be max [%2] given [%3] panel available!") + .arg(_startPos).arg(_panelLedCount-configuredLedCount).arg(_panelLedCount); + + this->setInError(errorReason); + isInitOK = false; } } } + return isInitOK; } @@ -460,6 +515,9 @@ int LedDeviceNanoleaf::write(const std::vector & ledValues) udpbuffer[i++] = lowByte; ColorRgb color; + + //Maintain LED counter independent from PanelCounter + uint ledCounter = 0; for ( uint panelCounter=0; panelCounter < _panelLedCount; panelCounter++ ) { uint panelID = _panelIds[panelCounter]; @@ -468,12 +526,13 @@ int LedDeviceNanoleaf::write(const std::vector & ledValues) lowByte = static_cast(panelID & 0xFF); // Set panels configured - if( panelCounter < this->getLedCount() ) { - color = static_cast(ledValues.at(panelCounter)); + if( panelCounter >= _startPos && panelCounter <= _endPos ) { + color = static_cast(ledValues.at(ledCounter)); + ++ledCounter; } else { - // Set panels not configed to black; + // Set panels not configured to black; color = ColorRgb::BLACK; DebugIf(verbose3, _log, "[%u] >= panelLedCount [%u] => Set to BLACK", panelCounter, _panelLedCount ); } diff --git a/libsrc/leddevice/dev_net/LedDeviceNanoleaf.h b/libsrc/leddevice/dev_net/LedDeviceNanoleaf.h index 5ef704f5..d2d1f0af 100644 --- a/libsrc/leddevice/dev_net/LedDeviceNanoleaf.h +++ b/libsrc/leddevice/dev_net/LedDeviceNanoleaf.h @@ -82,22 +82,6 @@ protected: virtual int open() override; private: - // QNetworkAccessManager object for sending requests. - QNetworkAccessManager* _networkmanager; - - QString _hostname; - QString _api_port; - QString _auth_token; - - //Nanoleaf device details - QString _deviceModel; - QString _deviceFirmwareVersion; - ushort _extControlVersion; - /// The number of panels with leds - uint _panelLedCount; - /// Array of the pannel ids. - std::vector _panelIds; - /// /// Discover Nanoleaf device via SSDP identifiers /// @@ -162,4 +146,26 @@ private: /// @param uint8_t vector /// @return vector as string of hex values std::string uint8_vector_to_hex_string( const std::vector& buffer ) const; + + // QNetworkAccessManager object for sending requests. + QNetworkAccessManager* _networkmanager; + + QString _hostname; + QString _api_port; + QString _auth_token; + + bool _topDown; + bool _leftRight; + uint _startPos; + uint _endPos; + + //Nanoleaf device details + QString _deviceModel; + QString _deviceFirmwareVersion; + ushort _extControlVersion; + /// The number of panels with leds + uint _panelLedCount; + /// Array of the pannel ids. + QVector _panelIds; + }; diff --git a/libsrc/leddevice/dev_spi/LedDeviceLpd8806.cpp b/libsrc/leddevice/dev_spi/LedDeviceLpd8806.cpp index 42c17d96..e9e08851 100644 --- a/libsrc/leddevice/dev_spi/LedDeviceLpd8806.cpp +++ b/libsrc/leddevice/dev_spi/LedDeviceLpd8806.cpp @@ -24,38 +24,6 @@ bool LedDeviceLpd8806::init(const QJsonObject &deviceConfig) return isInitOK; } -int LedDeviceLpd8806::open() -{ - int retval = -1; - QString errortext; - _deviceReady = false; - - // General initialisation and configuration of LedDevice - if ( init(_devConfig) ) - { - // Perform an initial reset to start accepting data on the first led - - const unsigned clearSize = _ledCount/32+1; - if ( writeBytes(clearSize, _ledBuffer.data()) < 0 ) - { - errortext = QString ("Failed to do initial write"); - } - else - { - // Everything is OK -> enable device - _deviceReady = true; - setEnable(true); - retval = 0; - } - // On error/exceptions, set LedDevice in error - if ( retval < 0 ) - { - this->setInError( errortext ); - } - } - return retval; -} - int LedDeviceLpd8806::write(const std::vector &ledValues) { // Copy the colors from the ColorRgb vector to the Ldp8806 data vector diff --git a/libsrc/leddevice/dev_spi/LedDeviceLpd8806.h b/libsrc/leddevice/dev_spi/LedDeviceLpd8806.h index 95eb8c04..482ef299 100644 --- a/libsrc/leddevice/dev_spi/LedDeviceLpd8806.h +++ b/libsrc/leddevice/dev_spi/LedDeviceLpd8806.h @@ -95,14 +95,6 @@ public: /// @return true if success virtual bool init(const QJsonObject &deviceConfig) override; -protected: - /// - /// Opens and initiatialises the output device - /// - /// @return Zero on succes (i.e. device is ready and enabled) else negative - /// - virtual int open() override; - private: /// /// Writes the led color values to the led-device diff --git a/libsrc/leddevice/schemas/schema-nanoleaf.json b/libsrc/leddevice/schemas/schema-nanoleaf.json index 4bf6e39d..97fac11f 100644 --- a/libsrc/leddevice/schemas/schema-nanoleaf.json +++ b/libsrc/leddevice/schemas/schema-nanoleaf.json @@ -11,6 +11,47 @@ "type": "string", "title":"edt_dev_auth_key_title", "propertyOrder" : 2 + }, + "title": { + "type" : "object", + "title":"edt_dev_spec_panelorganisation_title", + "access" : "advanced", + "propertyOrder" : 3 + }, + "panelOrderTopDown": { + "type": "integer", + "title":"edt_dev_spec_order_top_down_title", + "enum" : [0, 1], + "default" : 0, + "options" : { + "enum_titles" : ["edt_conf_enum_top_down", "edt_conf_enum_bottom_up"] + }, + "minimum" : 0, + "maximum" : 1, + "access" : "advanced", + "propertyOrder" : 4 + }, + "panelOrderLeftRight": { + "type": "integer", + "title":"edt_dev_spec_order_left_right_title", + "enum" : [0, 1], + "default" : 0, + "options" : { + "enum_titles" : ["edt_conf_enum_left_right", "edt_conf_enum_right_left"] + }, + "minimum" : 0, + "maximum" : 1, + "access" : "advanced", + "propertyOrder" : 5 + }, + "panelStartPos": { + "type": "integer", + "title":"edt_dev_spec_panel_start_position", + "step": 1, + "minimum" : 0, + "default": 0, + "access" : "advanced", + "propertyOrder" : 6 } }, "additionalProperties": true