diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 465ec4ed..098e5fc1 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -159,16 +159,10 @@ jobs: path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey key: ${{ runner.os }}-chocolatey - - name: "Remove Redistributable" - shell: cmd - run: | - MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5} - MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7} - - - name: Install Python, NSIS, OpenSSL, DirectX SDK + - name: Install Python, NSIS, OpenSSL shell: powershell run: | - choco install --no-progress python nsis openssl directx-sdk -y + choco install --no-progress python nsis openssl -y - name: Install libjpeg-turbo run: | diff --git a/.github/workflows/push-master.yml b/.github/workflows/push-master.yml index 6b2b9fcf..4e8e5fc4 100644 --- a/.github/workflows/push-master.yml +++ b/.github/workflows/push-master.yml @@ -123,16 +123,10 @@ jobs: path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey key: ${{ runner.os }}-chocolatey - - name: "Remove Redistributable" - shell: cmd - run: | - MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5} - MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7} - - - name: Install Python, NSIS, OpenSSL, DirectX SDK + - name: Install Python, NSIS, OpenSSL shell: powershell run: | - choco install --no-progress python nsis openssl directx-sdk -y + choco install --no-progress python nsis openssl -y - name: Install libjpeg-turbo run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 12e42638..411fe242 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +- Updated dependency rpi_ws281x to latest upstream ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index aeb29d1d..5805d190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,8 +60,7 @@ IF ( ${CMAKE_SYSTEM} MATCHES "Linux" ) SET ( DEFAULT_USB_HID ON ) SET ( DEFAULT_CEC ON ) ELSEIF ( WIN32 ) - SET ( DEFAULT_DX ON ) - SET ( DEFAULT_MF ON ) + SET ( DEFAULT_DX OFF ) ELSE() SET ( DEFAULT_V4L2 OFF ) SET ( DEFAULT_FB OFF ) @@ -345,7 +344,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # Search for DirectX9 if (ENABLE_DX) find_package(DirectX9 REQUIRED) - endif() + endif(ENABLE_DX) endif() diff --git a/CompileHowto.md b/CompileHowto.md index 031f6c46..5b662e83 100644 --- a/CompileHowto.md +++ b/CompileHowto.md @@ -69,6 +69,13 @@ all linux specific led and grabber hardware via cmake. Because we use QT as fram ## Arch See [AUR](https://aur.archlinux.org/packages/?O=0&SeB=nd&K=hyperion&outdated=&SB=n&SO=a&PP=50&do_Search=Go) for PKGBUILDs on arch. If the PKGBUILD does not work ask questions there please. +## Fedora +The following dependencies are needed to build hyperion.ng on fedora. +``` +sudo dnf -y groupinstall "Development Tools" +sudo dnf install python3-devel qt-devel qt5-qtbase-devel qt5-qtserialport-devel libjpeg-devel xrandr xcb-util-image-devel qt5-qtx11extras-devel turbojpeg-devel libusb-devel avahi-libs avahi-compat-libdns_sd-devel xcb-util-devel dbus-devel openssl-devel fedora-packager rpmdevtools gcc libcec-devel +``` +After installing the dependencies, you can continue with the compile instructions later on this page (the more detailed way..). ## OSX To install on OS X you either need Homebrew or Macport but Homebrew is the recommended way to install the packages. To use Homebrew XCode is required as well, use `brew doctor` to check your install. @@ -84,7 +91,7 @@ brew install zlib ``` ## Windows (WIP) -We assume a 64bit Windows 7 or higher. Install the following; +We assume a 64bit Windows 10. Install the following; - [Git](https://git-scm.com/downloads) (Check: Add to PATH) - [CMake (Windows win64-x64 Installer)](https://cmake.org/download/) (Check: Add to PATH) - [Visual Studio 2019 Build Tools](https://go.microsoft.com/fwlink/?linkid=840931) ([direct link](https://aka.ms/vs/16/release/vs_buildtools.exe)) @@ -94,9 +101,12 @@ We assume a 64bit Windows 7 or higher. Install the following; - [Python 3 (Windows x86-64 executable installer)](https://www.python.org/downloads/windows/) (Check: Add to PATH and Debug Symbols) - Open a console window and execute `pip install aqtinstall`. - Now we can download Qt to _C:\Qt_ `mkdir c:\Qt && aqt install -O c:\Qt 5.15.0 windows desktop win64_msvc2019_64` -- [DirectX Software Development Kit](https://www.microsoft.com/en-us/download/details.aspx?id=6812) ([direct link](https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe)) -- Optional for package creation: [NSIS 3.x](https://sourceforge.net/projects/nsis/files/NSIS%203/) ([direct link](https://sourceforge.net/projects/nsis/files/latest/download)) +### Optional: +- For DirectX9 grabber: + - DirectX Software Development Kit. The download link is no longer available, so you will have to search for it yourself. +- For package creation: + - [NSIS 3.x](https://sourceforge.net/projects/nsis/files/NSIS%203/) ([direct link](https://sourceforge.net/projects/nsis/files/latest/download)) # Compiling and installing Hyperion diff --git a/README.md b/README.md index 7a3ec484..22a3a73a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![GitHub Actions](https://github.com/hyperion-project/hyperion.ng/workflows/Hyperion%20CI%20Build/badge.svg?branch=master)](https://github.com/hyperion-project/hyperion.ng/actions) [![LGTM](https://img.shields.io/lgtm/alerts/g/hyperion-project/hyperion.ng.svg)](https://lgtm.com/projects/g/hyperion-project/hyperion.ng/alerts/) [![Documentation](https://codedocs.xyz/hyperion-project/hyperion.ng.svg)](https://codedocs.xyz/hyperion-project/hyperion.ng/) +[![made-with-love](https://img.shields.io/badge/Made%20with-♥-ff0000.svg)](#) ## About Hyperion @@ -18,7 +19,7 @@ * A command line utility for testing and integration in automated environment * Priority channels are not coupled to a specific led data provider which means that a provider can post led data and leave without the need to maintain a connection to Hyperion. This is ideal for a remote application (like our [Android app](https://play.google.com/store/apps/details?id=nl.hyperion.hyperionpro)). * Black border detector and processor -* A scriptable (Python) effect engine +* A scriptable (Python) effect engine with 39 build-in effects for your inspiration * A multi language web interface to configure and remote control hyperion If you need further support please open a topic at the forum!
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/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 95fea35c..d291b8e8 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -140,7 +140,7 @@ macro(DeployUnix TARGET) # Detect the Python version and modules directory if (NOT CMAKE_VERSION VERSION_LESS "3.12") - set(PYTHON_VERSION_MAJOR_MINOR "${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}") + set(PYTHON_VERSION_MAJOR_MINOR "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") execute_process( COMMAND ${Python3_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" OUTPUT_VARIABLE PYTHON_MODULES_DIR @@ -149,7 +149,7 @@ macro(DeployUnix TARGET) else() - set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") + set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" OUTPUT_VARIABLE PYTHON_MODULES_DIR @@ -158,15 +158,22 @@ macro(DeployUnix TARGET) endif() - # Copy Python modules to 'share/hyperion/lib/python' + # Copy Python modules to 'share/hyperion/lib/python' and ignore the unnecessary stuff listed below if (PYTHON_MODULES_DIR) install( DIRECTORY ${PYTHON_MODULES_DIR}/ DESTINATION "share/hyperion/lib/python" COMPONENT "Hyperion" + PATTERN "*.pyc" EXCLUDE # compiled bytecodes + PATTERN "__pycache__" EXCLUDE # any cache + PATTERN "config-${PYTHON_VERSION_MAJOR_MINOR}*" EXCLUDE # static libs + PATTERN "lib2to3" EXCLUDE # automated Python 2 to 3 code translation + PATTERN "tkinter" EXCLUDE # Tk interface + PATTERN "turtle.py" EXCLUDE # Tk demo + PATTERN "test" EXCLUDE # unittest module + PATTERN "sitecustomize.py" EXCLUDE # site-specific configs ) - endif(PYTHON_MODULES_DIR) else() @@ -354,7 +361,7 @@ macro(DeployWindows TARGET) DESTINATION "bin" COMPONENT "Hyperion" ) - endif(ENABLE_DX) + endif (ENABLE_DX) else() # Run CMake after target was built diff --git a/cmake/nsis/template/NSIS.template.in b/cmake/nsis/template/NSIS.template.in index ccb28ce5..5f9a1a40 100644 --- a/cmake/nsis/template/NSIS.template.in +++ b/cmake/nsis/template/NSIS.template.in @@ -792,12 +792,6 @@ Section "-Core installation" ; Install Visual c++ Redistributable ExecWait '"$INSTDIR\bin\vc_redist.x64.exe" /install /quiet' -; Install DirectX 9 Redistributable -ExecWait '"$INSTDIR\bin\dx_redist.exe" /q /t:"$INSTDIR\tmp"' - ExecWait '"$INSTDIR\tmp\DXSETUP.exe" /silent' - Delete '$INSTDIR\tmp\*.*' - RMDir '$INSTDIR\tmp' - SectionEnd Section "-Add to path" diff --git a/cmake/packages.cmake b/cmake/packages.cmake index 685ac0c5..2626516e 100644 --- a/cmake/packages.cmake +++ b/cmake/packages.cmake @@ -66,7 +66,7 @@ SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) SET ( CPACK_RPM_PACKAGE_RELEASE 1 ) SET ( CPACK_RPM_PACKAGE_LICENSE "MIT" ) SET ( CPACK_RPM_PACKAGE_GROUP "Applications" ) -SET ( CPACK_RPM_PACKAGE_REQUIRES "libcec4" ) +SET ( CPACK_RPM_PACKAGE_REQUIRES "libcec >= 4.0.0" ) SET ( CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/preinst" ) SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" ) SET ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/prerm" ) diff --git a/dependencies/external/rpi_ws281x b/dependencies/external/rpi_ws281x index 31f668cc..3a20f1bd 160000 --- a/dependencies/external/rpi_ws281x +++ b/dependencies/external/rpi_ws281x @@ -1 +1 @@ -Subproject commit 31f668cc637cd96e132b611db82cbe9de9838366 +Subproject commit 3a20f1bdd740a144de180a07d8d3317920459d2d diff --git a/docs/yarn.lock b/docs/yarn.lock index 220f3d49..63d6093b 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -4418,9 +4418,9 @@ inherits@2.0.3: integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.5, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== inquirer@^7.0.0: version "7.1.0" diff --git a/effects/flag.py b/effects/flag.py index a1e6ae9e..7802b842 100644 --- a/effects/flag.py +++ b/effects/flag.py @@ -171,6 +171,18 @@ def printFlag(country): hyperion.imageSolidFill(255, 0, 0) hyperion.imageDrawLine(int(iW*0.5), int(iH*0.25), int(iW*0.5), int(iH*0.75), int(iH*0.15), 255, 255, 255) hyperion.imageDrawLine(int(iW*0.26), int(iH*0.5), int(iW*0.75), int(iH*0.5), int(iH*0.15), 255, 255, 255) + + # cmr flag (Cameroon) + if country == "cmr": + hyperion.imageSolidFill(0, 0, int(iW*0.33), iH, 0, 255, 0) + hyperion.imageSolidFill(int(iW*0.33), 0, int(iW*0.33), iH, 255, 0, 0) + hyperion.imageSolidFill(int(iW*0.66), 0, iW, iH, 255, 255, 0) + + # ru flag (Russia) + if country == "ru": + hyperion.imageSolidFill(0, 0, iW, int(iH*0.33), 255, 255, 255) + hyperion.imageSolidFill(0, int(iH*0.33), iW, int(iH*0.33), 0, 57, 166) + hyperion.imageSolidFill(0, int(iH*0.66), iW, iH, 213, 43, 30) #prepare wanted flags for cf in countries: diff --git a/effects/schema/flag.schema.json b/effects/schema/flag.schema.json index 28318d35..7a61df9d 100644 --- a/effects/schema/flag.schema.json +++ b/effects/schema/flag.schema.json @@ -10,7 +10,7 @@ "uniqueItems": true, "items": { "type": "string", - "enum": ["de","at","fr","be","it","es","bg","ee","dk","fi","hu","ie","lv","lt","lu","mt","nl","pl","pt","ro","sl","se","ch"] + "enum": ["at","be","bg","ch","cmr","cz","de","dk","ee","es","fi","fr","gr","hu","ie","it","lt","lu","lv","mt","nl","pl","pt","ro","ru","se","sl"] }, "propertyOrder" : 1 }, 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; diff --git a/libsrc/leddevice/schemas/schema-ws2801.json b/libsrc/leddevice/schemas/schema-ws2801.json index fca1dd1d..c1830381 100644 --- a/libsrc/leddevice/schemas/schema-ws2801.json +++ b/libsrc/leddevice/schemas/schema-ws2801.json @@ -5,7 +5,7 @@ "output": { "type": "string", "title":"edt_dev_spec_spipath_title", - "enum" : ["/dev/spidev0.0","/dev/spidev0.1"], + "enum" : ["/dev/spidev0.0","/dev/spidev0.1","/dev/spidev1.0","/dev/spidev1.1"], "propertyOrder" : 1 }, "rate": { diff --git a/libsrc/utils/ImageResampler.cpp b/libsrc/utils/ImageResampler.cpp index 4b44345f..15a32466 100644 --- a/libsrc/utils/ImageResampler.cpp +++ b/libsrc/utils/ImageResampler.cpp @@ -36,7 +36,7 @@ void ImageResampler::processImage(const uint8_t * data, int width, int height, i cropRight = width >> 1; break; case VideoMode::VIDEO_3DTAB: - cropBottom = width >> 1; + cropBottom = height >> 1; break; default: break; diff --git a/src/hyperiond/CMakeLists.txt b/src/hyperiond/CMakeLists.txt index 3d22efe4..2bba4d63 100644 --- a/src/hyperiond/CMakeLists.txt +++ b/src/hyperiond/CMakeLists.txt @@ -140,7 +140,17 @@ if(CMAKE_HOST_UNIX) install( CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_hyperiond )" COMPONENT "Hyperion" ) endif() -# Copy dependencies (not for OSX) +# Deploy Qt DLLs into the binary folder. +# This is necessary for starting the application from within the IDE +if(WIN32) + get_target_property(QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY) + find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_BIN_DIR}") + set(WINDEPLOYQT_PARAMS --verbose 0 --no-compiler-runtime --no-opengl-sw --no-system-d3d-compiler) + add_custom_command(TARGET hyperiond POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} ${WINDEPLOYQT_PARAMS} "$") +endif() + +# Deploy all dependencies for package creation (not for OSX) include(${CMAKE_SOURCE_DIR}/cmake/Dependencies.cmake) if (NOT ENABLE_OSX AND NOT WIN32) # Unix