Compare commits
31 Commits
Author | SHA1 | Date |
---|---|---|
LordGrey | cd22d4454d | |
dependabot[bot] | 33722c9a09 | |
dependabot[bot] | 41bffecc0b | |
dependabot[bot] | f49e1a2c0b | |
LordGrey | 08dc59c885 | |
LordGrey | 48cea4ad9b | |
LordGrey | 7909997398 | |
LordGrey | a5bb7e905b | |
LordGrey | d1879c2e39 | |
LordGrey | c0dc08b0c0 | |
LordGrey | 5bf25c98ad | |
LordGrey | da275dd448 | |
Paulchen-Panther | 1257cfff70 | |
LordGrey | 42c98da470 | |
LordGrey | 64642a4457 | |
Christoph Pohl | af1a31b842 | |
dependabot[bot] | a7ce0f8a4c | |
Paulchen-Panther | 00ce3ff089 | |
Paulchen-Panther | 54d03b8065 | |
lsellens | 2a17de37f1 | |
LordGrey | 5535b884bf | |
Hyperion-Bot | 79b31e16e0 | |
dependabot[bot] | e3496eb4dc | |
Paulchen-Panther | 08e7c7d8c2 | |
Paulchen-Panther | e0060eb406 | |
dependabot[bot] | 2f09f9a0b8 | |
Portisch | 85eb62f314 | |
Hyperion-Bot | c73f8623b8 | |
Harald | e59e456b00 | |
Rastafabisch | a393f6211c | |
LordGrey | b2fcea3bbd |
76
.codedocs
76
.codedocs
|
@ -1,76 +0,0 @@
|
|||
# Hyperion.NG .codedocs Configuration File
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# CodeDocs Configuration
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# Include the Doxygen configuration from another file.
|
||||
# The file must be a relative path with respect to the root of the repository.
|
||||
|
||||
DOXYFILE =
|
||||
|
||||
# Specify external repository to link documentation with.
|
||||
# This is similar to Doxygen's TAGFILES option, but will automatically link to
|
||||
# tags of other repositories already using CodeDocs. List each repository to
|
||||
# link with by giving its location in the form of owner/repository.
|
||||
# For example:
|
||||
# TAGLINKS = doxygen/doxygen CodeDocs/osg
|
||||
# Note: these repositories must already be built on CodeDocs.
|
||||
|
||||
TAGLINKS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Doxygen Configuration
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# Doxygen configuration may also be placed in this file.
|
||||
# Currently, the following Doxygen configuration options are available. Refer
|
||||
# to http://doxygen.org/manual/config.html for detailed explanation of the
|
||||
# options. To request support for more options, contact support@codedocs.xyz.
|
||||
#
|
||||
# ABBREVIATE_BRIEF =
|
||||
# ALIASES =
|
||||
# ALPHABETICAL_INDEX =
|
||||
# ALWAYS_DETAILED_SEC =
|
||||
# CASE_SENSE_NAMES =
|
||||
# CLASS_DIAGRAMS =
|
||||
# DISABLE_INDEX =
|
||||
# DISTRIBUTE_GROUP_DOC =
|
||||
# EXAMPLE_PATH =
|
||||
EXCLUDE = .ci/ \
|
||||
assets/ \
|
||||
bin/
|
||||
config/ \
|
||||
effects/ \
|
||||
test/ \
|
||||
# EXCLUDE_PATTERNS =
|
||||
# EXCLUDE_SYMBOLS =
|
||||
# EXTENSION_MAPPING =
|
||||
# EXTRACT_LOCAL_CLASSES =
|
||||
# FILE_PATTERNS =
|
||||
# GENERATE_TAGFILE =
|
||||
# GENERATE_TREEVIEW =
|
||||
# HIDE_COMPOUND_REFERENCE =
|
||||
# HIDE_SCOPE_NAMES =
|
||||
# HIDE_UNDOC_CLASSES =
|
||||
# HIDE_UNDOC_MEMBERS =
|
||||
# HTML_TIMESTAMP =
|
||||
# INLINE_GROUPED_CLASSES =
|
||||
# INPUT_ENCODING =
|
||||
# INTERNAL_DOCS =
|
||||
# OPTIMIZE_OUTPUT_FOR_C =
|
||||
PROJECT_BRIEF = "The successor to Hyperion aka Hyperion Next Generation"
|
||||
PROJECT_NAME = "Hyperion.NG"
|
||||
# PROJECT_NUMBER =
|
||||
# SHORT_NAMES =
|
||||
# SHOW_FILES =
|
||||
# SHOW_INCLUDE_FILES =
|
||||
# SHOW_NAMESPACES =
|
||||
# SORT_BRIEF_DOCS =
|
||||
# SORT_BY_SCOPE_NAME =
|
||||
# SORT_MEMBER_DOCS =
|
||||
# STRICT_PROTO_MATCHING =
|
||||
# TYPEDEF_HIDES_STRUCT =
|
||||
USE_MDFILE_AS_MAINPAGE = README.md
|
||||
# VERBATIM_HEADERS =
|
||||
#
|
|
@ -1,6 +1,26 @@
|
|||
name: Hyperion APT Build
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
head_sha:
|
||||
type: string
|
||||
description: The branch, tag or SHA to checkout
|
||||
required: true
|
||||
secrets:
|
||||
APT_GPG:
|
||||
required: true
|
||||
APT_USER:
|
||||
required: true
|
||||
APT_PASSWORD:
|
||||
required: true
|
||||
APT_DRAFT:
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
head_sha:
|
||||
type: string
|
||||
description: The branch, tag or SHA to checkout
|
||||
required: true
|
||||
secrets:
|
||||
APT_GPG:
|
||||
required: true
|
||||
|
@ -16,7 +36,7 @@ jobs:
|
|||
name: Setup APT build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set APT matrix
|
||||
id: apt-ppa
|
||||
run: |
|
||||
|
@ -34,8 +54,9 @@ jobs:
|
|||
matrix: ${{ fromJson(needs.setup.outputs.apt-matrix) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.head_sha || github.event.client_payload.head_sha }}
|
||||
submodules: true
|
||||
|
||||
- name: Generate environment variables
|
||||
|
@ -73,7 +94,7 @@ jobs:
|
|||
cp ../hyperion_*.deb /deploy"
|
||||
|
||||
- name: Upload package artifact
|
||||
if: startsWith(github.event.ref, 'refs/tags')
|
||||
if: ${{ startsWith(github.event.ref, 'refs/tags') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: deploy
|
||||
|
@ -81,15 +102,17 @@ jobs:
|
|||
|
||||
publish:
|
||||
name: Publish APT packages
|
||||
if: startsWith(github.event.ref, 'refs/tags')
|
||||
if: ${{ startsWith(github.event.ref, 'refs/tags') || github.event_name == 'workflow_dispatch' }}
|
||||
needs: [setup, build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.head_sha || github.event.client_payload.head_sha }}
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v5.2.0
|
||||
uses: crazy-max/ghaction-import-gpg@v6.0.0
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.APT_GPG }}
|
||||
|
||||
|
@ -121,7 +144,7 @@ jobs:
|
|||
done
|
||||
|
||||
- name: Upload packages to APT server (DRAFT)
|
||||
uses: SamKirkland/FTP-Deploy-Action@4.3.3
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
|
||||
with:
|
||||
server: apt.hyperion-project.org
|
||||
username: ${{ secrets.APT_USER }}
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
[
|
||||
{
|
||||
"distribution": "Bionic",
|
||||
"architecture": "amd64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl1.0-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.6, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls10, libasound2, libturbojpeg, libcec4",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 18.04 (Bionic Beaver) (amd64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Focal",
|
||||
"architecture": "amd64",
|
||||
|
@ -32,12 +24,12 @@
|
|||
"description": "Ubuntu 22.10 (Kinetic Kudu) (amd64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Stretch",
|
||||
"distribution": "Lunar",
|
||||
"architecture": "amd64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl1.0-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.5, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls10, libasound2, libturbojpeg0, libcec4",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.11, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg, libcec6",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 9.x (Stretch) (amd64)"
|
||||
"description": "Ubuntu 23.04 (Lunar Lobster) (amd64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Buster",
|
||||
|
@ -59,7 +51,7 @@
|
|||
"distribution": "Bookworm",
|
||||
"architecture": "amd64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg0, libcec6",
|
||||
"package-depends": "libpython3.11, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg0, libcec6",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 12.x (Bookworm) (amd64)"
|
||||
}
|
||||
|
|
|
@ -1,57 +1,49 @@
|
|||
[
|
||||
{
|
||||
"distribution": "Bionic",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl1.0-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.6, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls10, libturbojpeg, libcec4",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 18.04 (Bionic Beaver) (arm64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Focal",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.8, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg, libcec4",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.8, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg, libcec4",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 20.04 (Focal Fossa) (arm64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Jammy",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libturbojpeg, libcec6",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg, libcec6",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 22.04 (Jammy Jellyfish) (arm64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Kinetic",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libturbojpeg, libcec6",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg, libcec6",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 22.10 (Kinetic Kudu) (arm64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Buster",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.7, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg0, libcec4",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.7, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg0, libcec4",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 10.x (Buster) (arm64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Bullseye",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg0, libcec6",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg0, libcec6",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 11.x (Bullseye) (arm64)"
|
||||
},
|
||||
{
|
||||
"distribution": "Bookworm",
|
||||
"architecture": "arm64",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg0, libcec6",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.11, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg0, libcec6",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 12.x (Bookworm) (arm64)",
|
||||
"exclude" : true
|
||||
|
|
|
@ -1,65 +1,49 @@
|
|||
[
|
||||
{
|
||||
"distribution": "Bionic",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl1.0-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.6, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls10, libturbojpeg, libcec4",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 18.04 (Bionic Beaver) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Focal",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.8, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg, libcec4",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.8, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg, libcec4",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 20.04 (Focal Fossa) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Jammy",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libturbojpeg, libcec6",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg, libcec6",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 22.04 (Jammy Jellyfish) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Kinetic",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libturbojpeg, libcec6",
|
||||
"build-depends": "git, cmake, build-essential, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, libqt5x11extras5-dev, libusb-1.0-0-dev, python3-dev, libcec-dev, libxcb-image0-dev, libxcb-util0-dev, libxcb-shm0-dev, libxcb-render0-dev, libxcb-randr0-dev, libxrandr-dev, libxrender-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libssl-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.10, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg, libcec6",
|
||||
"cmake-environment": "-DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DENABLE_XCB=ON -DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Ubuntu 22.10 (Kinetic Kudu) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Stretch",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl1.0-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.5, libusb-1.0-0, libqt5widgets5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls10, libturbojpeg0, libcec4",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description":"Debian 9.x (Stretch) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Buster",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl1.0-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.7, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg0, libcec4",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl1.0-dev, libraspberrypi-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.7, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg0, libcec4",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 10.x (Buster) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Bullseye",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg0, libcec6",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libasound2, libturbojpeg0, libcec6",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 11.x (Bullseye) (armhf)"
|
||||
},
|
||||
{
|
||||
"distribution": "Bookworm",
|
||||
"architecture": "armhf",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.9, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls12, libturbojpeg0, libcec6",
|
||||
"build-depends": "git, cmake, python3-dev, qtbase5-dev, libqt5serialport5-dev, libqt5sql5-sqlite, libqt5svg5-dev, build-essential, libusb-1.0-0-dev, libcec-dev, libssl-dev, libraspberrypi-dev, libasound2-dev, libturbojpeg0-dev, libjpeg-dev, libmbedtls-dev",
|
||||
"package-depends": "libpython3.11, libusb-1.0-0, libqt5widgets5, libqt5x11extras5, libqt5sql5, libqt5sql5-sqlite, libqt5serialport5, libmbedtls14, libasound2, libturbojpeg0, libcec6",
|
||||
"cmake-environment": "-DUSE_SYSTEM_MBEDTLS_LIBS=ON -DENABLE_DEPLOY_DEPENDENCIES=OFF -DCMAKE_BUILD_TYPE=Release",
|
||||
"description": "Debian 12.x (Bookworm) (armhf)",
|
||||
"exclude" : true
|
||||
|
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
@ -68,7 +68,7 @@ jobs:
|
|||
with:
|
||||
sarif_file: sarif-results/${{ matrix.language }}.sarif
|
||||
- name: Upload loc as a Build Artifact
|
||||
uses: actions/upload-artifact@v2.2.0
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: sarif-results
|
||||
path: sarif-results
|
||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
if: github.repository_owner == 'hyperion-project'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
|
@ -48,7 +48,7 @@ jobs:
|
|||
if: github.repository_owner == 'hyperion-project'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Check if commit has changed
|
||||
id: build-necessary
|
||||
run: |
|
||||
|
@ -66,7 +66,7 @@ jobs:
|
|||
if: ${{ needs.check.outputs.build-nightly == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set nightly matrix
|
||||
id: nightly-ppa
|
||||
run: |
|
||||
|
@ -84,9 +84,9 @@ jobs:
|
|||
matrix: ${{ fromJson(needs.setup.outputs.nightly-matrix) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
- name: Generate environment variables
|
||||
run: |
|
||||
|
@ -135,10 +135,10 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v5.2.0
|
||||
uses: crazy-max/ghaction-import-gpg@v6.0.0
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.APT_GPG }}
|
||||
|
||||
|
@ -171,7 +171,7 @@ jobs:
|
|||
done
|
||||
|
||||
- name: Upload packages to nightly server
|
||||
uses: SamKirkland/FTP-Deploy-Action@4.3.3
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
|
||||
with:
|
||||
server: nightly.apt.hyperion-project.org
|
||||
username: ${{ secrets.NIGHTLY_USER }}
|
||||
|
|
|
@ -18,23 +18,23 @@ jobs:
|
|||
dockerImage: [ x86_64, armv6l, armv7l, aarch64 ]
|
||||
include:
|
||||
- dockerImage: x86_64
|
||||
dockerName: Debian Stretch (x86_64)
|
||||
dockerName: Debian Buster (x86_64)
|
||||
platform: x11
|
||||
- dockerImage: armv6l
|
||||
dockerName: Debian Stretch (Raspberry Pi v1 & ZERO)
|
||||
dockerName: Debian Buster (Raspberry Pi v1 & ZERO)
|
||||
platform: rpi
|
||||
- dockerImage: armv7l
|
||||
dockerName: Debian Stretch (Raspberry Pi 2 & 3)
|
||||
dockerName: Debian Buster (Raspberry Pi 2 & 3)
|
||||
platform: rpi
|
||||
- dockerImage: aarch64
|
||||
dockerName: Debian Stretch (Generic AARCH64)
|
||||
dockerName: Debian Buster (Generic AARCH64)
|
||||
platform: amlogic
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
# Append PR number to .version
|
||||
- name: Append PR number to version
|
||||
|
@ -47,7 +47,7 @@ jobs:
|
|||
- name: Build packages
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ matrix.dockerImage }}
|
||||
DOCKER_TAG: stretch
|
||||
DOCKER_TAG: buster
|
||||
DOCKER_NAME: ${{ matrix.dockerName }}
|
||||
PLATFORM: ${{ matrix.platform }}
|
||||
shell: bash
|
||||
|
@ -76,9 +76,9 @@ jobs:
|
|||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
# Append PR number to .version
|
||||
- name: Append PR number to version
|
||||
|
@ -125,9 +125,9 @@ jobs:
|
|||
QT_VERSION: 5.15.2
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
# Append PR number to .version
|
||||
- name: Append PR number to version
|
||||
|
@ -150,7 +150,7 @@ jobs:
|
|||
with:
|
||||
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
|
||||
key: ${{ runner.os }}-chocolatey
|
||||
|
||||
|
||||
# - name: Install Python
|
||||
# shell: powershell
|
||||
# run: |
|
||||
|
@ -159,7 +159,8 @@ jobs:
|
|||
- name: Install OpenSSL, DirectX SDK
|
||||
shell: powershell
|
||||
run: |
|
||||
choco install --no-progress openssl directx-sdk -y
|
||||
choco install --no-progress openssl --version=1.1.1.2100 -y
|
||||
choco install --no-progress directx-sdk -y
|
||||
|
||||
- name: Install libjpeg-turbo
|
||||
run: |
|
||||
|
|
|
@ -20,28 +20,28 @@ jobs:
|
|||
dockerImage: [ x86_64, armv6l, armv7l, aarch64 ]
|
||||
include:
|
||||
- dockerImage: x86_64
|
||||
dockerName: Debian Stretch (x86_64)
|
||||
dockerName: Debian Buster (x86_64)
|
||||
platform: x11
|
||||
- dockerImage: armv6l
|
||||
dockerName: Debian Stretch (Raspberry Pi v1 & ZERO)
|
||||
dockerName: Debian Buster (Raspberry Pi v1 & ZERO)
|
||||
platform: rpi
|
||||
- dockerImage: armv7l
|
||||
dockerName: Debian Stretch (Raspberry Pi 2 & 3)
|
||||
dockerName: Debian Buster (Raspberry Pi 2 & 3)
|
||||
platform: rpi
|
||||
- dockerImage: aarch64
|
||||
dockerName: Debian Stretch (Generic AARCH64)
|
||||
dockerName: Debian Buster (Generic AARCH64)
|
||||
platform: amlogic
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
# Build process
|
||||
- name: Build packages
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ matrix.dockerImage }}
|
||||
DOCKER_TAG: stretch
|
||||
DOCKER_TAG: buster
|
||||
DOCKER_NAME: ${{ matrix.dockerName }}
|
||||
PLATFORM: ${{ matrix.platform }}
|
||||
shell: bash
|
||||
|
@ -62,9 +62,9 @@ jobs:
|
|||
name: macOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
# Install dependencies
|
||||
- name: Install dependencies
|
||||
|
@ -97,9 +97,9 @@ jobs:
|
|||
QT_VERSION: 5.15.2
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
|
@ -124,7 +124,8 @@ jobs:
|
|||
- name: Install OpenSSL, DirectX SDK
|
||||
shell: powershell
|
||||
run: |
|
||||
choco install --no-progress openssl directx-sdk -y
|
||||
choco install --no-progress openssl --version=1.1.1.2100 -y
|
||||
choco install --no-progress directx-sdk -y
|
||||
|
||||
- name: Install libjpeg-turbo
|
||||
run: |
|
||||
|
@ -161,7 +162,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Generate environment variables
|
||||
- name: Generate environment variables from .version and tag
|
||||
|
@ -195,8 +196,6 @@ jobs:
|
|||
if: startsWith(github.event.ref, 'refs/tags')
|
||||
needs: [Linux, macOS, windows]
|
||||
uses: ./.github/workflows/apt.yml
|
||||
secrets:
|
||||
APT_GPG: ${{ secrets.APT_GPG }}
|
||||
APT_USER: ${{ secrets.APT_USER }}
|
||||
APT_PASSWORD: ${{ secrets.APT_PASSWORD }}
|
||||
APT_DRAFT: ${{ secrets.APT_DRAFT }}
|
||||
secrets: inherit
|
||||
with:
|
||||
head_sha: master
|
||||
|
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
steps:
|
||||
# Dispatch event to build new HyperBian image
|
||||
- name: Dispatch HyperBian build
|
||||
uses: peter-evans/repository-dispatch@v2.1.1
|
||||
uses: peter-evans/repository-dispatch@v2.1.2
|
||||
if: ${{ github.repository_owner == 'hyperion-project'}}
|
||||
with:
|
||||
repository: hyperion-project/HyperBian
|
||||
|
|
27
.lgtm.yml
27
.lgtm.yml
|
@ -1,27 +0,0 @@
|
|||
extraction:
|
||||
cpp:
|
||||
prepare:
|
||||
packages:
|
||||
- "git"
|
||||
- "cmake"
|
||||
- "build-essential"
|
||||
- "qtbase5-dev"
|
||||
- "libqt5serialport5-dev"
|
||||
- "libqt5sql5-sqlite"
|
||||
- "libqt5svg5-dev"
|
||||
- "libqt5x11extras5-dev"
|
||||
- "libusb-1.0-0-dev"
|
||||
- "python3-dev"
|
||||
- "libcec-dev"
|
||||
- "libxcb-image0-dev"
|
||||
- "libxcb-util0-dev"
|
||||
- "libxcb-shm0-dev"
|
||||
- "libxcb-render0-dev"
|
||||
- "libxcb-randr0-dev"
|
||||
- "libxrandr-dev"
|
||||
- "libxrender-dev"
|
||||
- "libavahi-core-dev"
|
||||
- "libavahi-compat-libdnssd-dev"
|
||||
- "libturbojpeg0-dev"
|
||||
- "libjpeg-dev"
|
||||
- "libssl-dev"
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased](https://github.com/hyperion-project/hyperion.ng/compare/2.0.15...HEAD)
|
||||
|
||||
### Breaking
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
- Fixed missing Include limits in QJsonSchemaChecker
|
||||
- Fixed dependencies for deb packages in Debian Bookworm
|
||||
|
||||
## Removed
|
||||
|
||||
## [2.0.15](https://github.com/hyperion-project/hyperion.ng/releases/tag/2.0.15) - 2023-02
|
||||
|
||||
### Added
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
|
||||
message( STATUS "CMake Version: ${CMAKE_VERSION}" )
|
||||
|
||||
|
@ -38,26 +38,24 @@ if ( CCACHE_FOUND )
|
|||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||
endif(CCACHE_FOUND)
|
||||
|
||||
# enable C++14; MSVC doesn't have c++14 feature switch
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
if(APPLE)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("Werror=unguarded-availability" REQUIRED_UNGUARDED_AVAILABILITY)
|
||||
if(REQUIRED_UNGUARDED_AVAILABILITY)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "Werror=unguarded-availability")
|
||||
endif()
|
||||
# enable C++17
|
||||
if(APPLE)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("Werror=unguarded-availability" REQUIRED_UNGUARDED_AVAILABILITY)
|
||||
if(REQUIRED_UNGUARDED_AVAILABILITY)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "Werror=unguarded-availability")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CXX_STANDARD_REQUIRED ON)
|
||||
set(CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Set build variables
|
||||
# Grabber
|
||||
SET ( DEFAULT_AMLOGIC OFF )
|
||||
|
@ -180,19 +178,18 @@ if ( "${PLATFORM}" MATCHES "osx" )
|
|||
elseif ( "${PLATFORM}" MATCHES "rpi" )
|
||||
SET ( DEFAULT_DISPMANX ON )
|
||||
SET ( DEFAULT_DEV_WS281XPWM ON )
|
||||
elseif ( "${PLATFORM}" STREQUAL "amlogic" )
|
||||
elseif ( "${PLATFORM}" MATCHES "^amlogic" )
|
||||
SET ( DEFAULT_AMLOGIC ON )
|
||||
elseif ( "${PLATFORM}" STREQUAL "amlogic-dev" )
|
||||
SET ( DEFAULT_AMLOGIC ON )
|
||||
SET ( DEFAULT_DISPMANX OFF )
|
||||
SET ( DEFAULT_QT OFF )
|
||||
SET ( DEFAULT_CEC OFF )
|
||||
elseif ( "${PLATFORM}" STREQUAL "amlogic64" )
|
||||
SET ( DEFAULT_AMLOGIC ON )
|
||||
elseif ( "${PLATFORM}" MATCHES "x11" )
|
||||
if ( "${PLATFORM}" MATCHES "-dev$" )
|
||||
SET ( DEFAULT_AMLOGIC ON )
|
||||
SET ( DEFAULT_DISPMANX OFF )
|
||||
SET ( DEFAULT_QT OFF )
|
||||
SET ( DEFAULT_CEC OFF )
|
||||
endif()
|
||||
elseif ( "${PLATFORM}" MATCHES "^x11" )
|
||||
SET ( DEFAULT_X11 ON )
|
||||
SET ( DEFAULT_XCB ON )
|
||||
if ( "${PLATFORM}" STREQUAL "x11-dev" )
|
||||
if ( "${PLATFORM}" MATCHES "-dev$" )
|
||||
SET ( DEFAULT_AMLOGIC ON)
|
||||
SET ( DEFAULT_DEV_WS281XPWM ON )
|
||||
endif()
|
||||
|
@ -201,7 +198,7 @@ elseif ( "${PLATFORM}" STREQUAL "imx6" )
|
|||
endif()
|
||||
|
||||
# enable tests for -dev builds
|
||||
if ( "${PLATFORM}" MATCHES "-dev" )
|
||||
if ( "${PLATFORM}" MATCHES "-dev$" )
|
||||
SET ( DEFAULT_TESTS ON )
|
||||
endif()
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ For Windows and macOS is an installation file available on our [Release page](ht
|
|||
|
||||
## Linux:
|
||||
On the following operating systems, Hyperion can currently be installed/updated using the method listed below:
|
||||
- Raspbian Stretch/Raspberry Pi OS and later (armhf/arm64)
|
||||
- Debian Stretch (9) and later (armhf/arm64/x86_64)
|
||||
- Ubuntu 18.04 and later (armhf/arm64/x86_64)
|
||||
- Raspbian Buster/Raspberry Pi OS and later (armhf/arm64)
|
||||
- Debian Buster(10) and later (armhf/arm64/x86_64)
|
||||
- Ubuntu 20.04 and later (armhf/arm64/x86_64)
|
||||
|
||||
***
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[![CodeQL Analysis](https://github.com/hyperion-project/hyperion.ng/actions/workflows/codeql.yml/badge.svg)](https://github.com/hyperion-project/hyperion.ng/actions/workflows/codeql.yml)
|
||||
[![Forum](https://img.shields.io/website/https/hyperion-project.org.svg?label=Forum&down_color=red&down_message=offline&up_color=4bc51d&up_message=online&logo=homeadvisor&logoColor=white)](https://www.hyperion-project.org)
|
||||
[![Documentation](https://img.shields.io/website/https/docs.hyperion-project.org.svg?label=Documentation&down_color=red&down_message=offline&up_color=4bc51d&up_message=online&logo=read-the-docs)](https://docs.hyperion-project.org)
|
||||
[![Discord](https://img.shields.io/discord/785578322167463937?label=Discord&logo=discord&logoColor=white&color=4bc51d)](https://discord.gg/khkR8Vx3ff)
|
||||
[![Discord](https://img.shields.io/discord/785578322167463937?label=Discord&logo=discord&logoColor=white&color=4bc51d)](https://discord.gg/XtVTb3HEKS)
|
||||
![made-with-love](https://img.shields.io/badge/Made%20With-♥-ff0000.svg)
|
||||
|
||||
## About Hyperion
|
||||
|
|
|
@ -86,6 +86,8 @@
|
|||
"conf_leds_layout_cl_bottomright": "Bottom Right (Corner)",
|
||||
"conf_leds_layout_cl_cornergap": "Corner Gap",
|
||||
"conf_leds_layout_cl_edgegap": "Edge Gap",
|
||||
"conf_leds_layout_cl_entertainment": "Entertainment Area",
|
||||
"conf_leds_layout_cl_entertainment_center": "Entertainment Area Center",
|
||||
"conf_leds_layout_cl_gaglength": "Gap length",
|
||||
"conf_leds_layout_cl_gappos": "gap position",
|
||||
"conf_leds_layout_cl_hleddepth": "Horizontal LED depth",
|
||||
|
@ -560,7 +562,9 @@
|
|||
"edt_conf_webc_keyPassPhrase_title": "Key password",
|
||||
"edt_conf_webc_keyPath_expl": "Path to the key file (format PEM, encrypted with RSA)",
|
||||
"edt_conf_webc_keyPath_title": "Private key path",
|
||||
"edt_conf_webc_sslport_expl": "Port oft the HTTPS-Webserver",
|
||||
"edt_conf_webc_port_expl": "Port for the WebServer, RPC and WebSocket HTTP connections",
|
||||
"edt_conf_webc_port_title": "HTTP Port",
|
||||
"edt_conf_webc_sslport_expl": "Port for the WebServer, RPC and WebSocket HTTPS connections",
|
||||
"edt_conf_webc_sslport_title": "HTTPS Port",
|
||||
"edt_dev_auth_key_title": "Authentication Token",
|
||||
"edt_dev_auth_key_title_info": "Authentication Token required to acccess the device",
|
||||
|
@ -616,7 +620,7 @@
|
|||
"edt_dev_spec_gpioBcm_title": "GPIO Pin",
|
||||
"edt_dev_spec_gpioMap_title": "GPIO mapping",
|
||||
"edt_dev_spec_gpioNumber_title": "GPIO number",
|
||||
"edt_dev_spec_groupId_title": "Group ID",
|
||||
"edt_dev_spec_groupId_title": "Group",
|
||||
"edt_dev_spec_header_title": "Specific Settings",
|
||||
"edt_dev_spec_interpolation_title": "Interpolation",
|
||||
"edt_dev_spec_intervall_title": "Interval",
|
||||
|
@ -681,6 +685,7 @@
|
|||
"edt_dev_spec_transistionTime_title": "Transition time",
|
||||
"edt_dev_spec_uid_title": "UID",
|
||||
"edt_dev_spec_universe_title": "Universe",
|
||||
"edt_dev_spec_useAPIv2_title": "Use API v2",
|
||||
"edt_dev_spec_useEntertainmentAPI_title": "Use Hue Entertainment API",
|
||||
"edt_dev_spec_useOrbSmoothing_title": "Use orb smoothing",
|
||||
"edt_dev_spec_useRgbwProtocol_title": "Use RGBW protocol",
|
||||
|
@ -1085,7 +1090,7 @@
|
|||
"wiz_cololight_noprops": "Not able to get device properties - Define Hardware LED count manually",
|
||||
"wiz_cololight_title": "Cololight Wizard",
|
||||
"wiz_guideyou": "The $1 will guide you through the settings. Just press the button!",
|
||||
"wiz_hue_blinkblue": "Let ID $1 light up blue",
|
||||
"wiz_hue_blinkblue": "Let it light up",
|
||||
"wiz_hue_clientkey": "Clientkey",
|
||||
"wiz_hue_create_user": "Create new User",
|
||||
"wiz_hue_desc1": "1. Hyperion searches automatically for a Hue-Bridge, in case it cannot find one you need to provide the hostname or IP-address and push the reload button. <br> 2. Provide a user ID, if you do not have one create a new one.",
|
||||
|
|
|
@ -327,7 +327,7 @@ $(document).ready(function () {
|
|||
var saveOptions = conf_editor_screen.getValue();
|
||||
|
||||
var instCaptOptions = window.serverConfig.instCapture;
|
||||
instCaptOptions.systemEnable = true;
|
||||
instCaptOptions.systemEnable = saveOptions.framegrabber.enable;
|
||||
saveOptions.instCapture = instCaptOptions;
|
||||
|
||||
requestWriteConfig(saveOptions);
|
||||
|
@ -679,7 +679,7 @@ $(document).ready(function () {
|
|||
var saveOptions = conf_editor_video.getValue();
|
||||
|
||||
var instCaptOptions = window.serverConfig.instCapture;
|
||||
instCaptOptions.v4lEnable = true;
|
||||
instCaptOptions.v4lEnable = saveOptions.grabberV4L2.enable;
|
||||
saveOptions.instCapture = instCaptOptions;
|
||||
|
||||
requestWriteConfig(saveOptions);
|
||||
|
@ -805,7 +805,7 @@ $(document).ready(function () {
|
|||
const saveOptions = conf_editor_audio.getValue();
|
||||
|
||||
const instCaptOptions = window.serverConfig.instCapture;
|
||||
instCaptOptions.audioEnable = true;
|
||||
instCaptOptions.audioEnable = saveOptions.grabberAudio.enable;
|
||||
saveOptions.instCapture = instCaptOptions;
|
||||
|
||||
requestWriteConfig(saveOptions);
|
||||
|
|
|
@ -218,7 +218,9 @@ $(document).ready(function () {
|
|||
loadContent(undefined,true);
|
||||
|
||||
//Hide capture menu entries, if no grabbers are available
|
||||
if ((window.serverInfo.grabbers.screen.available.length === 0) && (window.serverInfo.grabbers.video.available.length === 0)) {
|
||||
if ((window.serverInfo.grabbers.screen.available.length === 0) &&
|
||||
(window.serverInfo.grabbers.video.available.length === 0) &&
|
||||
(window.serverInfo.grabbers.audio.available.length === 0)) {
|
||||
$("#MenuItemGrabber").attr('style', 'display:none')
|
||||
if ((jQuery.inArray("boblight", window.serverInfo.services) === -1)) {
|
||||
$("#MenuItemInstCapture").attr('style', 'display:none')
|
||||
|
|
|
@ -1021,11 +1021,6 @@ $(document).ready(function () {
|
|||
var generalOptions = window.serverSchema.properties.device;
|
||||
|
||||
var ledType = $(this).val();
|
||||
|
||||
// philipshueentertainment backward fix
|
||||
if (ledType == "philipshueentertainment")
|
||||
ledType = "philipshue";
|
||||
|
||||
var specificOptions = window.serverSchema.properties.alldevices[ledType];
|
||||
|
||||
conf_editor = createJsonEditor('editor_container_leddevice', {
|
||||
|
@ -1060,13 +1055,10 @@ $(document).ready(function () {
|
|||
$('#btn_led_device_wiz').off();
|
||||
|
||||
if (ledType == "philipshue") {
|
||||
$('#root_specificOptions_useEntertainmentAPI').on("change", function () {
|
||||
var ledWizardType = (this.checked) ? "philipshueentertainment" : ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var hue_title = (this.checked) ? 'wiz_hue_e_title' : 'wiz_hue_title';
|
||||
changeWizard(data, hue_title, startWizardPhilipsHue);
|
||||
});
|
||||
$("#root_specificOptions_useEntertainmentAPI").trigger("change");
|
||||
var ledWizardType = ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var hue_title = 'wiz_hue_title';
|
||||
changeWizard(data, hue_title, startWizardPhilipsHue);
|
||||
}
|
||||
else if (ledType == "atmoorb") {
|
||||
var ledWizardType = (this.checked) ? "atmoorb" : ledType;
|
||||
|
@ -2069,7 +2061,7 @@ var updateOutputSelectList = function (ledType, discoveryInfo) {
|
|||
case "devRPiPWM":
|
||||
key = ledType;
|
||||
|
||||
if (discoveryInfo.devices.length == 0) {
|
||||
if (!discoveryInfo.isUserAdmin) {
|
||||
enumVals.push("NONE");
|
||||
enumTitleVals.push($.i18n('edt_dev_spec_devices_discovered_none'));
|
||||
$('#btn_submit_controller').prop('disabled', true);
|
||||
|
@ -2331,6 +2323,7 @@ function updateElementsWled(ledType, key) {
|
|||
var enumSegSelectVals = [];
|
||||
var enumSegSelectTitleVals = [];
|
||||
var enumSegSelectDefaultVal = "";
|
||||
var defaultSegmentId = "-1";
|
||||
|
||||
if (devicesProperties[ledType] && devicesProperties[ledType][key]) {
|
||||
var ledDeviceProperties = devicesProperties[ledType][key];
|
||||
|
@ -2338,9 +2331,8 @@ function updateElementsWled(ledType, key) {
|
|||
if (!jQuery.isEmptyObject(ledDeviceProperties)) {
|
||||
|
||||
if (ledDeviceProperties.info) {
|
||||
if (ledDeviceProperties.info.liveseg && ledDeviceProperties.info.liveseg < 0) {
|
||||
if (!ledDeviceProperties.info.hasOwnProperty("liveseg") || ledDeviceProperties.info.liveseg < 0) {
|
||||
// "Use main segment only" is disabled
|
||||
var defaultSegmentId = "-1";
|
||||
enumSegSelectVals.push(defaultSegmentId);
|
||||
enumSegSelectTitleVals.push($.i18n('edt_dev_spec_segments_disabled_title'));
|
||||
enumSegSelectDefaultVal = defaultSegmentId;
|
||||
|
@ -2392,13 +2384,12 @@ function updateElementsWled(ledType, key) {
|
|||
hardwareLedCount = 1;
|
||||
}
|
||||
|
||||
if (segmentConfig) {
|
||||
if (segmentConfig && segmentConfig.streamSegmentId > defaultSegmentId) {
|
||||
var configuredstreamSegmentId = window.serverConfig.device.segments.streamSegmentId.toString();
|
||||
enumSegSelectVals = [configuredstreamSegmentId];
|
||||
enumSegSelectTitleVals = ["Segment " + configuredstreamSegmentId];
|
||||
enumSegSelectDefaultVal = configuredstreamSegmentId;
|
||||
} else {
|
||||
defaultSegmentId = "-1";
|
||||
enumSegSelectVals.push(defaultSegmentId);
|
||||
enumSegSelectTitleVals.push($.i18n('edt_dev_spec_segments_disabled_title'));
|
||||
enumSegSelectDefaultVal = defaultSegmentId;
|
||||
|
|
|
@ -604,7 +604,7 @@ var lightPosTopLeft112 = { hmin: 0, hmax: 0.5, vmin: 0, vmax: 0.15 };
|
|||
var lightPosTopLeft121 = { hmin: 0.5, hmax: 1, vmin: 0, vmax: 0.15 };
|
||||
var lightPosTopLeftNewMid = { hmin: 0.25, hmax: 0.75, vmin: 0, vmax: 0.15 };
|
||||
|
||||
function assignLightPos(id, pos, name) {
|
||||
function assignLightPos(pos, name) {
|
||||
var i = null;
|
||||
|
||||
if (pos === "top")
|
||||
|
@ -695,52 +695,50 @@ devicesProperties = {};
|
|||
|
||||
var hueIPs = [];
|
||||
var hueIPsinc = 0;
|
||||
var hueLights = null;
|
||||
var hueGroups = null;
|
||||
var hueLights = [];
|
||||
var hueEntertainmentConfigs = [];
|
||||
var hueEntertainmentServices = [];
|
||||
var lightLocation = [];
|
||||
var groupLights = [];
|
||||
var groupChannels = [];
|
||||
var groupLightsLocations = [];
|
||||
var hueType = "philipshue";
|
||||
var isAPIv2Ready = true;
|
||||
var isEntertainmentReady = true;
|
||||
|
||||
function startWizardPhilipsHue(e) {
|
||||
if (typeof e.data.type != "undefined") hueType = e.data.type;
|
||||
|
||||
//create html
|
||||
|
||||
var hue_title = 'wiz_hue_title';
|
||||
var hue_intro1 = 'wiz_hue_intro1';
|
||||
var hue_intro1 = 'wiz_hue_e_intro1';
|
||||
var hue_desc1 = 'wiz_hue_desc1';
|
||||
var hue_create_user = 'wiz_hue_create_user';
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
hue_title = 'wiz_hue_e_title';
|
||||
hue_intro1 = 'wiz_hue_e_intro1';
|
||||
hue_desc1 = 'wiz_hue_e_desc1';
|
||||
hue_create_user = 'wiz_hue_e_create_user';
|
||||
}
|
||||
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(hue_title));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(hue_title) + '</h4><p>' + $.i18n(hue_intro1) + '</p>');
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
|
||||
|
||||
var hidePort = "hidden-lg";
|
||||
if (storedAccess === 'expert') {
|
||||
hidePort = "";
|
||||
}
|
||||
|
||||
$('#wh_topcontainer').append('<p class="text-left" style="font-weight:bold">' + $.i18n(hue_desc1) + '</p>' +
|
||||
var topContainer_html = '<p class="text-left" style="font-weight:bold">' + $.i18n(hue_desc1) + '</p>' +
|
||||
'<div class="row">' +
|
||||
'<div class="col-md-2">' +
|
||||
' <p class="text-left">' + $.i18n('wiz_hue_ip') + '</p></div>' +
|
||||
' <div class="col-md-7"><div class="input-group">' +
|
||||
' <span class="input-group-addon" id="retry_bridge" style="cursor:pointer"><i class="fa fa-refresh"></i></span>' +
|
||||
' <input type="text" class="input-group form-control" id="host" placeholder="' + $.i18n('wiz_hue_ip') + '"></div></div>' +
|
||||
' <div class="col-md-3 ' + hidePort + '"><div class="input-group">' +
|
||||
' <span class="input-group-addon">:</span>' +
|
||||
' <input type="text" class="input-group form-control" id="port" placeholder="' + $.i18n('edt_conf_general_port_title') + '"></div></div>' +
|
||||
'</div><p><span style="font-weight:bold;color:red" id="wiz_hue_ipstate"></span><span style="font-weight:bold;" id="wiz_hue_discovered"></span></p>'
|
||||
);
|
||||
$('#wh_topcontainer').append();
|
||||
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
|
||||
' <select id="hue_bridge_select" class="hue_bridge_sel_watch form-control">' + '</select>' + '</div></div>' +
|
||||
' <div class="col-md-7"><div class="input-group">' +
|
||||
' <span class="input-group-addon"><i class="fa fa-arrow-right"></i></span>' +
|
||||
' <input type="text" class="input-group form-control" id="host" placeholder="' + $.i18n('wiz_hue_ip') + '"></div></div>';
|
||||
|
||||
if (storedAccess === 'expert') {
|
||||
topContainer_html += '<div class="col-md-3"><div class="input-group">' +
|
||||
'<span class="input-group-addon">:</span>' +
|
||||
'<input type="text" class="input-group form-control" id="port" placeholder="' + $.i18n('edt_conf_general_port_title') + '"></div></div>';
|
||||
}
|
||||
|
||||
topContainer_html += '</div><p><span style="font-weight:bold;color:red" id="wiz_hue_ipstate"></span><span style="font-weight:bold;" id="wiz_hue_discovered"></span></p>';
|
||||
topContainer_html += '<div class="form-group" id="usrcont" style="display:none"></div>';
|
||||
|
||||
$('#wh_topcontainer').append(topContainer_html);
|
||||
|
||||
$('#usrcont').append('<div class="row"><div class="col-md-2"><p class="text-left">' + $.i18n('wiz_hue_username') + '</p ></div>' +
|
||||
'<div class="col-md-7">' +
|
||||
|
@ -751,23 +749,18 @@ function startWizardPhilipsHue(e) {
|
|||
'</div><input type="hidden" id="groupId">'
|
||||
);
|
||||
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
$('#usrcont').append('<div class="row"><div class="col-md-2"><p class="text-left">' + $.i18n('wiz_hue_clientkey') +
|
||||
'</p></div><div class="col-md-7"><input class="form-control" id="clientkey" type="text"></div></div><br>');
|
||||
}
|
||||
$('#usrcont').append('<div id="hue_client_key_r" class="row"><div class="col-md-2"><p class="text-left">' + $.i18n('wiz_hue_clientkey') +
|
||||
'</p></div><div class="col-md-7"><input class="form-control" id="clientkey" type="text"></div></div><br>');
|
||||
|
||||
$('#usrcont').append('<p><span style="font-weight:bold;color:red" id="wiz_hue_usrstate"></span><\p>' +
|
||||
'<button type="button" class="btn btn-primary" style="display:none" id="wiz_hue_create_user"> <i class="fa fa-fw fa-plus"></i>' + $.i18n(hue_create_user) + '</button>');
|
||||
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
$('#wizp2_body').append('<div id="hue_grp_ids_t" style="display:none"><p class="text-left" style="font-weight:bold">' + $.i18n('wiz_hue_e_desc2') + '</p></div>');
|
||||
createTable("gidsh", "gidsb", "hue_grp_ids_t");
|
||||
$('.gidsh').append(createTableRow([$.i18n('edt_dev_spec_groupId_title'), $.i18n('wiz_hue_e_use_group')], true));
|
||||
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p class="text-left" style="font-weight:bold" id="hue_id_headline">' + $.i18n('wiz_hue_e_desc3') + '</p></div>');
|
||||
}
|
||||
else {
|
||||
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p class="text-left" style="font-weight:bold" id="hue_id_headline">' + $.i18n('wiz_hue_desc2') + '</p></div>');
|
||||
}
|
||||
$('#wizp2_body').append('<div id="hue_grp_ids_t" style="display:none"><p class="text-left" style="font-weight:bold">' + $.i18n('wiz_hue_e_desc2') + '</p></div>');
|
||||
createTable("gidsh", "gidsb", "hue_grp_ids_t");
|
||||
$('.gidsh').append(createTableRow([$.i18n('edt_dev_spec_groupId_title'), ""], true));
|
||||
|
||||
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p class="text-left" style="font-weight:bold" id="hue_id_headline">' + $.i18n('wiz_hue_e_desc3') + '</p></div>');
|
||||
|
||||
createTable("lidsh", "lidsb", "hue_ids_t");
|
||||
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lightid_title'), $.i18n('wiz_pos'), $.i18n('wiz_identify')], true));
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>' + $.i18n('general_btn_save') + '</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
|
@ -793,13 +786,26 @@ function startWizardPhilipsHue(e) {
|
|||
|
||||
function checkHueBridge(cb, hueUser) {
|
||||
var usr = (typeof hueUser != "undefined") ? hueUser : 'config';
|
||||
if (usr == 'config') $('#wiz_hue_discovered').html("");
|
||||
if (usr === 'config') {
|
||||
$('#wiz_hue_discovered').html("");
|
||||
}
|
||||
|
||||
if (hueIPs[hueIPsinc]) {
|
||||
var host = hueIPs[hueIPsinc].host;
|
||||
var port = hueIPs[hueIPsinc].port;
|
||||
|
||||
getProperties_hue_bridge(cb, decodeURIComponent(host), port, usr);
|
||||
if (usr != '')
|
||||
{
|
||||
getProperties_hue_bridge(cb, decodeURIComponent(host), port, usr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cb(false, usr);
|
||||
}
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
$('#port').val(443);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,37 +817,51 @@ function checkBridgeResult(reply, usr) {
|
|||
$('#port').val(hueIPs[hueIPsinc].port)
|
||||
|
||||
$('#usrcont').toggle(true);
|
||||
checkHueBridge(checkUserResult, $('#user').val() ? $('#user').val() : "newdeveloper");
|
||||
|
||||
checkHueBridge(checkUserResult, $('#user').val());
|
||||
}
|
||||
else {
|
||||
//increment and check again
|
||||
if (hueIPs.length - 1 > hueIPsinc) {
|
||||
hueIPsinc++;
|
||||
checkHueBridge(checkBridgeResult);
|
||||
}
|
||||
else {
|
||||
$('#usrcont').toggle(false);
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
}
|
||||
$('#usrcont').toggle(false);
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
}
|
||||
};
|
||||
|
||||
function checkUserResult(reply, usr) {
|
||||
function checkUserResult(reply, username) {
|
||||
$('#usrcont').toggle(true);
|
||||
if (reply) {
|
||||
$('#user').val(usr);
|
||||
if (hueType == 'philipshueentertainment' && $('#clientkey').val() == "") {
|
||||
|
||||
var hue_create_user = 'wiz_hue_e_create_user';
|
||||
if (!isEntertainmentReady) {
|
||||
hue_create_user = 'wiz_hue_create_user';
|
||||
$('#hue_client_key_r').toggle(false);
|
||||
} else {
|
||||
$('#hue_client_key_r').toggle(true);
|
||||
}
|
||||
|
||||
$('#wiz_hue_create_user').text($.i18n(hue_create_user));
|
||||
$('#wiz_hue_create_user').toggle(true);
|
||||
|
||||
if (reply) {
|
||||
$('#user').val(username);
|
||||
|
||||
if (isEntertainmentReady && $('#clientkey').val() == "") {
|
||||
$('#wiz_hue_usrstate').html($.i18n('wiz_hue_e_clientkey_needed'));
|
||||
$('#wiz_hue_create_user').toggle(true);
|
||||
} else {
|
||||
$('#wiz_hue_usrstate').html("");
|
||||
$('#wiz_hue_create_user').toggle(false);
|
||||
if (hueType == 'philipshue') {
|
||||
get_hue_lights();
|
||||
}
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
get_hue_groups();
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
$('#hue_id_headline').text($.i18n('wiz_hue_e_desc3'));
|
||||
$('#hue_grp_ids_t').toggle(true);
|
||||
|
||||
get_hue_groups(username);
|
||||
|
||||
} else {
|
||||
$('#hue_id_headline').text($.i18n('wiz_hue_desc2'));
|
||||
$('#hue_grp_ids_t').toggle(false);
|
||||
|
||||
get_hue_lights(username);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -852,22 +872,73 @@ function checkUserResult(reply, usr) {
|
|||
}
|
||||
};
|
||||
|
||||
function useGroupId(id) {
|
||||
$('#groupId').val(id);
|
||||
function useGroupId(id, username) {
|
||||
$('#groupId').val(hueEntertainmentConfigs[id].id);
|
||||
if (isAPIv2Ready) {
|
||||
var group = hueEntertainmentConfigs[id];
|
||||
|
||||
//Ensure ligthIDs are strings
|
||||
groupLights = hueGroups[id].lights.map(num => {
|
||||
return String(num);
|
||||
});
|
||||
groupLights = [];
|
||||
for (const light of group.light_services) {
|
||||
groupLights.push(light.rid);
|
||||
}
|
||||
|
||||
groupLightsLocations = hueGroups[id].locations;
|
||||
get_hue_lights();
|
||||
groupChannels = [];
|
||||
for (const channel of group.channels) {
|
||||
groupChannels.push(channel);
|
||||
}
|
||||
|
||||
groupLightsLocations = [];
|
||||
for (const location of group.locations.service_locations) {
|
||||
groupLightsLocations.push(location);
|
||||
}
|
||||
} else {
|
||||
//Ensure ligthIDs are strings
|
||||
groupLights = hueEntertainmentConfigs[id].lights.map(num => {
|
||||
return String(num);
|
||||
});
|
||||
|
||||
var lightLocations = hueEntertainmentConfigs[id].locations;
|
||||
for (var locationID in lightLocations) {
|
||||
var lightLocation = {};
|
||||
|
||||
let position = {
|
||||
x: lightLocations[locationID][0],
|
||||
y: lightLocations[locationID][1],
|
||||
z: lightLocations[locationID][2]
|
||||
};
|
||||
lightLocation.position = position;
|
||||
|
||||
groupLightsLocations.push(lightLocation);
|
||||
}
|
||||
}
|
||||
|
||||
get_hue_lights(username);
|
||||
}
|
||||
|
||||
function updateBridgeDetails(properties) {
|
||||
var ledDeviceProperties = properties.config;
|
||||
|
||||
if (!jQuery.isEmptyObject(ledDeviceProperties)) {
|
||||
isEntertainmentReady = properties.isEntertainmentReady;
|
||||
isAPIv2Ready = properties.isAPIv2Ready;
|
||||
|
||||
if (ledDeviceProperties.name && ledDeviceProperties.bridgeid && ledDeviceProperties.modelid) {
|
||||
$('#wiz_hue_discovered').html(
|
||||
"Bridge: " + ledDeviceProperties.name +
|
||||
", Modelid: " + ledDeviceProperties.modelid +
|
||||
", Firmware: " + ledDeviceProperties.swversion + "<br/>" +
|
||||
"API-Version: " + ledDeviceProperties.apiversion +
|
||||
", Entertainment: " + (isEntertainmentReady ? "✓" : "-") +
|
||||
", APIv2: " + (isAPIv2Ready ? "✓" : "-")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function discover_hue_bridges() {
|
||||
$('#wiz_hue_ipstate').html($.i18n('edt_dev_spec_devices_discovery_inprogress'));
|
||||
$('#wiz_hue_discovered').html("")
|
||||
|
||||
// $('#wiz_hue_discovered').html("")
|
||||
const res = await requestLedDeviceDiscovery('philipshue');
|
||||
if (res && !res.error) {
|
||||
const r = res.info;
|
||||
|
@ -903,11 +974,6 @@ async function discover_hue_bridges() {
|
|||
port = device.port;
|
||||
}
|
||||
|
||||
//Remap https port to http port until Hue-API v2 is supported
|
||||
if (port == 443) {
|
||||
port = 80;
|
||||
}
|
||||
|
||||
if (host) {
|
||||
|
||||
if (!hueIPs.some(item => item.host === host)) {
|
||||
|
@ -916,22 +982,39 @@ async function discover_hue_bridges() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#wiz_hue_ipstate').html("");
|
||||
$('#host').val(hueIPs[hueIPsinc].host)
|
||||
$('#port').val(hueIPs[hueIPsinc].port)
|
||||
|
||||
var usr = $('#user').val();
|
||||
if (usr != "") {
|
||||
checkHueBridge(checkUserResult, usr);
|
||||
} else {
|
||||
checkHueBridge(checkBridgeResult);
|
||||
$('#hue_bridge_select').html("");
|
||||
|
||||
for (var key in hueIPs) {
|
||||
$('#hue_bridge_select').append(createSelOpt(key, hueIPs[key].host));
|
||||
}
|
||||
|
||||
$('.hue_bridge_sel_watch').on("click", function () {
|
||||
hueIPsinc = $(this).val();
|
||||
|
||||
var name = $("#hue_bridge_select option:selected").text();
|
||||
$('#host').val(name);
|
||||
$('#port').val(hueIPs[hueIPsinc].port)
|
||||
|
||||
var usr = $('#user').val();
|
||||
if (usr != "") {
|
||||
checkHueBridge(checkUserResult, usr);
|
||||
} else {
|
||||
checkHueBridge(checkBridgeResult);
|
||||
}
|
||||
});
|
||||
|
||||
$('.hue_bridge_sel_watch').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getProperties_hue_bridge(cb, hostAddress, port, username, resourceFilter) {
|
||||
let params = { host: hostAddress, user: username, filter: resourceFilter };
|
||||
let params = { host: hostAddress, username: username, filter: resourceFilter };
|
||||
if (port !== 'undefined') {
|
||||
params.port = parseInt(port);
|
||||
}
|
||||
|
@ -945,23 +1028,27 @@ async function getProperties_hue_bridge(cb, hostAddress, port, username, resourc
|
|||
}
|
||||
|
||||
// Use device's properties, if properties in chache
|
||||
if (devicesProperties[ledType][key]) {
|
||||
if (devicesProperties[ledType][key] && devicesProperties[ledType][key][username]) {
|
||||
updateBridgeDetails(devicesProperties[ledType][key]);
|
||||
cb(true, username);
|
||||
} else {
|
||||
const res = await requestLedDeviceProperties(ledType, params);
|
||||
|
||||
|
||||
if (res && !res.error) {
|
||||
var ledDeviceProperties = res.info.properties;
|
||||
if (!jQuery.isEmptyObject(ledDeviceProperties)) {
|
||||
|
||||
devicesProperties[ledType][key] = {};
|
||||
devicesProperties[ledType][key][username] = ledDeviceProperties;
|
||||
|
||||
isAPIv2Ready = res.info.isAPIv2Ready;
|
||||
devicesProperties[ledType][key].isAPIv2Ready = isAPIv2Ready;
|
||||
isEntertainmentReady = res.info.isEntertainmentReady;
|
||||
devicesProperties[ledType][key].isEntertainmentReady = isEntertainmentReady;
|
||||
|
||||
updateBridgeDetails(devicesProperties[ledType][key]);
|
||||
if (username === "config") {
|
||||
if (ledDeviceProperties.name && ledDeviceProperties.bridgeid && ledDeviceProperties.modelid) {
|
||||
$('#wiz_hue_discovered').html("Bridge: " + ledDeviceProperties.name + ", Modelid: " + ledDeviceProperties.modelid + ", API-Version: " + ledDeviceProperties.apiversion);
|
||||
cb(true);
|
||||
}
|
||||
cb(true);
|
||||
} else {
|
||||
devicesProperties[ledType][key] = ledDeviceProperties;
|
||||
cb(true, username);
|
||||
}
|
||||
} else {
|
||||
|
@ -973,12 +1060,12 @@ async function getProperties_hue_bridge(cb, hostAddress, port, username, resourc
|
|||
}
|
||||
}
|
||||
|
||||
async function identify_hue_device(hostAddress, port, username, id) {
|
||||
async function identify_hue_device(hostAddress, port, username, name, id, id_v1) {
|
||||
var disabled = $('#btn_wiz_save').is(':disabled');
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').prop('disabled', true);
|
||||
|
||||
let params = { host: decodeURIComponent(hostAddress), user: username, lightId: id };
|
||||
let params = { host: decodeURIComponent(hostAddress), username: username, lightName: decodeURIComponent(name), lightId: id, lightId_v1: id_v1 };
|
||||
|
||||
if (port !== 'undefined') {
|
||||
params.port = parseInt(port);
|
||||
|
@ -1003,11 +1090,9 @@ function beginWizardHue() {
|
|||
$('#user').val(usr);
|
||||
}
|
||||
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
var clkey = eV("clientkey");
|
||||
if (clkey != "") {
|
||||
$('#clientkey').val(clkey);
|
||||
}
|
||||
var clkey = eV("clientkey");
|
||||
if (clkey != "") {
|
||||
$('#clientkey').val(clkey);
|
||||
}
|
||||
|
||||
//check if host is empty/reachable/search for bridge
|
||||
|
@ -1022,13 +1107,13 @@ function beginWizardHue() {
|
|||
$('#host').val(host);
|
||||
|
||||
var port = eV("port");
|
||||
if (port == 0) {
|
||||
$('#port').val(80);
|
||||
}
|
||||
else {
|
||||
if (port > 0) {
|
||||
$('#port').val(port);
|
||||
}
|
||||
hueIPs.unshift({ host: host, port: port });
|
||||
else {
|
||||
$('#port').val('');
|
||||
}
|
||||
hueIPs.push({ host: host, port: port });
|
||||
|
||||
if (usr != "") {
|
||||
checkHueBridge(checkUserResult, usr);
|
||||
|
@ -1038,18 +1123,18 @@ function beginWizardHue() {
|
|||
}
|
||||
|
||||
$('#retry_bridge').off().on('click', function () {
|
||||
var host = $('#host').val();
|
||||
var port = parseInt($('#port').val());
|
||||
|
||||
if ($('#host').val() != "") {
|
||||
if (host != "") {
|
||||
|
||||
hueIPs = [];
|
||||
hueIPsinc = 0;
|
||||
|
||||
var port = $('#port').val();
|
||||
if (isNaN(port) || port < 1 || port > 65535) {
|
||||
port = 80;
|
||||
$('#port').val(80);
|
||||
var idx = hueIPs.findIndex(item => item.host === host && item.port === port);
|
||||
if (idx === -1) {
|
||||
hueIPs.push({ host: host, port: port });
|
||||
hueIPsinc = hueIPs.length - 1;
|
||||
} else {
|
||||
hueIPsinc = idx;
|
||||
}
|
||||
hueIPs.push({ host: $('#host').val(), port: port });
|
||||
}
|
||||
else {
|
||||
discover_hue_bridges();
|
||||
|
@ -1064,29 +1149,177 @@ function beginWizardHue() {
|
|||
});
|
||||
|
||||
$('#retry_usr').off().on('click', function () {
|
||||
checkHueBridge(checkUserResult, $('#user').val() ? $('#user').val() : "newdeveloper");
|
||||
checkHueBridge(checkUserResult, $('#user').val());
|
||||
});
|
||||
|
||||
$('#wiz_hue_create_user').off().on('click', function () {
|
||||
if ($('#host').val() != "") {
|
||||
hueIPs.unshift({ host: $('#host').val(), port: $('#port').val() });
|
||||
}
|
||||
createHueUser();
|
||||
});
|
||||
|
||||
function assignLightEntertainmentPos(isFocusCenter, position, name, id) {
|
||||
|
||||
var x = position.x;
|
||||
var z = position.z;
|
||||
|
||||
if (isFocusCenter) {
|
||||
// Map lights as in centered range -0.5 to 0.5
|
||||
if (x < -0.5) {
|
||||
x = -0.5;
|
||||
} else if (x > 0.5) {
|
||||
x = 0.5;
|
||||
}
|
||||
if (z < -0.5) {
|
||||
z = -0.5;
|
||||
} else if (z > 0.5) {
|
||||
z = 0.5;
|
||||
}
|
||||
} else {
|
||||
// Map lights as in full range -1 to 1
|
||||
x /= 2;
|
||||
z /= 2;
|
||||
}
|
||||
|
||||
var h = x + 0.5;
|
||||
var v = -z + 0.5;
|
||||
|
||||
var hmin = h - 0.05;
|
||||
var hmax = h + 0.05;
|
||||
var vmin = v - 0.05;
|
||||
var vmax = v + 0.05;
|
||||
|
||||
let layoutObject = {
|
||||
hmin: hmin < 0 ? 0 : hmin,
|
||||
hmax: hmax > 1 ? 1 : hmax,
|
||||
vmin: vmin < 0 ? 0 : vmin,
|
||||
vmax: vmax > 1 ? 1 : vmax,
|
||||
name: name
|
||||
};
|
||||
|
||||
if (id) {
|
||||
layoutObject.name += "_" + id;
|
||||
}
|
||||
return layoutObject;
|
||||
}
|
||||
|
||||
function assignSegmentedLightPos(segment, position, name) {
|
||||
var layoutObjects = [];
|
||||
|
||||
var segTotalLength = 0;
|
||||
for (var key in segment) {
|
||||
|
||||
segTotalLength += segment[key].length;
|
||||
}
|
||||
|
||||
var min;
|
||||
var max;
|
||||
var horizontal = true;
|
||||
|
||||
var layoutObject = assignLightPos(position, name);
|
||||
if (position === "left" || position === "right") {
|
||||
// vertical distribution
|
||||
min = layoutObject.vmin;
|
||||
max = layoutObject.vmax;
|
||||
horizontal = false;
|
||||
|
||||
} else {
|
||||
// horizontal distribution
|
||||
min = layoutObject.hmin;
|
||||
max = layoutObject.hmax;
|
||||
}
|
||||
|
||||
var step = (max - min) / segTotalLength;
|
||||
var start = min;
|
||||
|
||||
for (var key in segment) {
|
||||
min = start;
|
||||
max = round(start + segment[key].length * step);
|
||||
|
||||
if (horizontal) {
|
||||
layoutObject.hmin = min;
|
||||
layoutObject.hmax = max;
|
||||
} else {
|
||||
layoutObject.vmin = min;
|
||||
layoutObject.vmax = max;
|
||||
}
|
||||
layoutObject.name = name + "_" + key;
|
||||
layoutObjects.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
|
||||
start = max;
|
||||
}
|
||||
|
||||
return layoutObjects;
|
||||
}
|
||||
|
||||
$('#btn_wiz_save').off().on("click", function () {
|
||||
var hueLedConfig = [];
|
||||
var finalLightIds = [];
|
||||
var channelNumber = 0;
|
||||
|
||||
//create hue led config
|
||||
for (var key in hueLights) {
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
if (groupLights.indexOf(key) == -1) continue;
|
||||
}
|
||||
if ($('#hue_' + key).val() != "disabled") {
|
||||
finalLightIds.push(key);
|
||||
var idx_content = assignLightPos(key, $('#hue_' + key).val(), hueLights[key].name);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
||||
for (var key in groupLights) {
|
||||
var lightId = groupLights[key];
|
||||
|
||||
if ($('#hue_' + lightId).val() != "disabled") {
|
||||
finalLightIds.push(lightId);
|
||||
|
||||
var lightName;
|
||||
if (isAPIv2Ready) {
|
||||
var light = hueLights.find(light => light.id === lightId);
|
||||
lightName = light.metadata.name;
|
||||
} else {
|
||||
lightName = hueLights[lightId].name;
|
||||
}
|
||||
|
||||
var position = $('#hue_' + lightId).val();
|
||||
var lightIdx = groupLights.indexOf(lightId);
|
||||
var lightLocation = groupLightsLocations[lightIdx];
|
||||
|
||||
var serviceID;
|
||||
if (isAPIv2Ready) {
|
||||
serviceID = lightLocation.service.rid;
|
||||
}
|
||||
|
||||
if (position.startsWith("entertainment")) {
|
||||
|
||||
// Layout per entertainment area definition at bridge
|
||||
var isFocusCenter = false;
|
||||
if (position === "entertainment_center") {
|
||||
isFocusCenter = true;
|
||||
}
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
|
||||
groupChannels.forEach((channel) => {
|
||||
if (channel.members[0].service.rid === serviceID) {
|
||||
var layoutObject = assignLightEntertainmentPos(isFocusCenter, channel.position, lightName, channel.channel_id);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
++channelNumber;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var layoutObject = assignLightEntertainmentPos(isFocusCenter, lightLocation.position, lightName);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Layout per manual settings
|
||||
var maxSegments = 1;
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
var service = hueEntertainmentServices.find(service => service.id === serviceID);
|
||||
maxSegments = service.segments.max_segments;
|
||||
}
|
||||
|
||||
if (maxSegments > 1) {
|
||||
var segment = service.segments.segments;
|
||||
var layoutObjects = assignSegmentedLightPos(segment, position, lightName);
|
||||
hueLedConfig.push(...layoutObjects);
|
||||
} else {
|
||||
var layoutObject = assignLightPos(position, lightName);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
}
|
||||
channelNumber += maxSegments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1354,7 @@ function beginWizardHue() {
|
|||
d.brightnessFactor = parseFloat(eV("brightnessFactor", 1));
|
||||
|
||||
d.clientkey = $('#clientkey').val();
|
||||
d.groupId = parseInt($('#groupId').val());
|
||||
d.groupId = $('#groupId').val();
|
||||
d.blackLightsTimeout = parseInt(eV("blackLightsTimeout", 5000));
|
||||
d.brightnessMin = parseFloat(eV("brightnessMin", 0));
|
||||
d.brightnessMax = parseFloat(eV("brightnessMax", 1));
|
||||
|
@ -1134,8 +1367,16 @@ function beginWizardHue() {
|
|||
d.enableAttempts = parseInt(conf_editor.getEditor("root.generalOptions.enableAttempts").getValue());
|
||||
d.enableAttemptsInterval = parseInt(conf_editor.getEditor("root.generalOptions.enableAttemptsInterval").getValue());
|
||||
|
||||
if (hueType == 'philipshue') {
|
||||
d.useEntertainmentAPI = false;
|
||||
d.useEntertainmentAPI = isEntertainmentReady;
|
||||
d.useAPIv2 = isAPIv2Ready;
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
d.hardwareLedCount = channelNumber;
|
||||
if (window.serverConfig.device.type !== d.type) {
|
||||
//smoothing on, if new device
|
||||
sc.smoothing = { enable: true };
|
||||
}
|
||||
} else {
|
||||
d.hardwareLedCount = finalLightIds.length;
|
||||
d.verbose = false;
|
||||
if (window.serverConfig.device.type !== d.type) {
|
||||
|
@ -1144,15 +1385,6 @@ function beginWizardHue() {
|
|||
}
|
||||
}
|
||||
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
d.useEntertainmentAPI = true;
|
||||
d.hardwareLedCount = groupLights.length;
|
||||
if (window.serverConfig.device.type !== d.type) {
|
||||
//smoothing on, if new device
|
||||
sc.smoothing = { enable: true };
|
||||
}
|
||||
}
|
||||
|
||||
window.serverConfig.device = d;
|
||||
|
||||
requestWriteConfig(sc, true);
|
||||
|
@ -1163,7 +1395,6 @@ function beginWizardHue() {
|
|||
}
|
||||
|
||||
function createHueUser() {
|
||||
|
||||
var host = hueIPs[hueIPsinc].host;
|
||||
var port = hueIPs[hueIPsinc].port;
|
||||
|
||||
|
@ -1208,7 +1439,8 @@ function createHueUser() {
|
|||
conf_editor.getEditor("root.specificOptions.host").setValue(host);
|
||||
conf_editor.getEditor("root.specificOptions.port").setValue(port);
|
||||
}
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
var clientkey = response.clientkey;
|
||||
if (clientkey != 'undefined') {
|
||||
$('#clientkey').val(clientkey);
|
||||
|
@ -1230,37 +1462,52 @@ function createHueUser() {
|
|||
}, retryInterval * 1000);
|
||||
}
|
||||
|
||||
function get_hue_groups() {
|
||||
|
||||
function get_hue_groups(username) {
|
||||
var host = hueIPs[hueIPsinc].host;
|
||||
|
||||
if (devicesProperties['philipshue'][host]) {
|
||||
var ledProperties = devicesProperties['philipshue'][host];
|
||||
if (devicesProperties['philipshue'][host] && devicesProperties['philipshue'][host][username]) {
|
||||
var ledProperties = devicesProperties['philipshue'][host][username];
|
||||
|
||||
if (!jQuery.isEmptyObject(ledProperties)) {
|
||||
hueGroups = ledProperties.groups;
|
||||
if (Object.keys(hueGroups).length > 0) {
|
||||
|
||||
$('.lidsb').html("");
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
$('#hue_grp_ids_t').toggle(true);
|
||||
|
||||
var gC = 0;
|
||||
for (var groupid in hueGroups) {
|
||||
if (hueGroups[groupid].type == 'Entertainment') {
|
||||
$('.gidsb').append(createTableRow([groupid + ' (' + hueGroups[groupid].name + ')', '<button class="btn btn-sm btn-primary" onClick=useGroupId(' + groupid + ')>' + $.i18n('wiz_hue_e_use_groupid', groupid) + '</button>']));
|
||||
gC++;
|
||||
}
|
||||
}
|
||||
if (gC == 0) {
|
||||
noAPISupport('wiz_hue_e_noegrpids');
|
||||
if (isAPIv2Ready) {
|
||||
if (!jQuery.isEmptyObject(ledProperties.data)) {
|
||||
if (Object.keys(ledProperties.data).length > 0) {
|
||||
hueEntertainmentConfigs = ledProperties.data.filter(config => {
|
||||
return config.type === "entertainment_configuration";
|
||||
});
|
||||
hueEntertainmentServices = ledProperties.data.filter(config => {
|
||||
return (config.type === "entertainment" && config.renderer === true);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!jQuery.isEmptyObject(ledProperties.groups)) {
|
||||
hueEntertainmentConfigs = [];
|
||||
var hueGroups = ledProperties.groups;
|
||||
for (var groupid in hueGroups) {
|
||||
if (hueGroups[groupid].type == 'Entertainment') {
|
||||
hueGroups[groupid].id = groupid;
|
||||
hueEntertainmentConfigs.push(hueGroups[groupid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(hueEntertainmentConfigs).length > 0) {
|
||||
|
||||
$('.lidsb').html("");
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
$('#hue_grp_ids_t').toggle(true);
|
||||
|
||||
for (var groupid in hueEntertainmentConfigs) {
|
||||
$('.gidsb').append(createTableRow([groupid + ' (' + hueEntertainmentConfigs[groupid].name + ')', '<button class="btn btn-sm btn-primary" onClick=useGroupId("' + groupid + '","' + username + '")>' + $.i18n('wiz_hue_e_use_group') + '</button>']));
|
||||
}
|
||||
} else {
|
||||
noAPISupport('wiz_hue_e_noegrpids', username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function noAPISupport(txt) {
|
||||
function noAPISupport(txt, username) {
|
||||
showNotification('danger', $.i18n('wiz_hue_e_title'), $.i18n('wiz_hue_e_noapisupport_hint'));
|
||||
conf_editor.getEditor("root.specificOptions.useEntertainmentAPI").setValue(false);
|
||||
$("#root_specificOptions_useEntertainmentAPI").trigger("change");
|
||||
|
@ -1269,51 +1516,82 @@ function noAPISupport(txt) {
|
|||
var txt = (txt) ? $.i18n(txt) : $.i18n('wiz_hue_e_nogrpids');
|
||||
$('<p style="font-weight:bold;color:red;">' + txt + '<br />' + $.i18n('wiz_hue_e_noapisupport') + '</p>').insertBefore('#wizp2_body #hue_ids_t');
|
||||
$('#hue_id_headline').html($.i18n('wiz_hue_desc2'));
|
||||
hueType = 'philipshue';
|
||||
get_hue_lights();
|
||||
|
||||
get_hue_lights(username);
|
||||
}
|
||||
|
||||
function get_hue_lights() {
|
||||
|
||||
function get_hue_lights(username) {
|
||||
var host = hueIPs[hueIPsinc].host;
|
||||
|
||||
if (devicesProperties['philipshue'][host]) {
|
||||
var ledProperties = devicesProperties['philipshue'][host];
|
||||
if (devicesProperties['philipshue'][host] && devicesProperties['philipshue'][host][username]) {
|
||||
var ledProperties = devicesProperties['philipshue'][host][username];
|
||||
|
||||
if (!jQuery.isEmptyObject(ledProperties.lights)) {
|
||||
hueLights = ledProperties.lights;
|
||||
if (Object.keys(hueLights).length > 0) {
|
||||
if (hueType == 'philipshue') {
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
if (isAPIv2Ready) {
|
||||
if (!jQuery.isEmptyObject(ledProperties.data)) {
|
||||
if (Object.keys(ledProperties.data).length > 0) {
|
||||
hueLights = ledProperties.data.filter(config => {
|
||||
return config.type === "light";
|
||||
});
|
||||
}
|
||||
$('#hue_ids_t, #btn_wiz_save').toggle(true);
|
||||
}
|
||||
} else {
|
||||
if (!jQuery.isEmptyObject(ledProperties.lights)) {
|
||||
hueLights = ledProperties.lights;
|
||||
}
|
||||
}
|
||||
|
||||
var lightOptions = [
|
||||
"top", "topleft", "topright",
|
||||
"bottom", "bottomleft", "bottomright",
|
||||
"left", "lefttop", "leftmiddle", "leftbottom",
|
||||
"right", "righttop", "rightmiddle", "rightbottom",
|
||||
"entire",
|
||||
"lightPosTopLeft112", "lightPosTopLeftNewMid", "lightPosTopLeft121",
|
||||
"lightPosBottomLeft14", "lightPosBottomLeft12", "lightPosBottomLeft34", "lightPosBottomLeft11",
|
||||
"lightPosBottomLeft112", "lightPosBottomLeftNewMid", "lightPosBottomLeft121"
|
||||
];
|
||||
if (Object.keys(hueLights).length > 0) {
|
||||
if (!isEntertainmentReady) {
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
}
|
||||
$('#hue_ids_t, #btn_wiz_save').toggle(true);
|
||||
|
||||
if (hueType == 'philipshue') {
|
||||
lightOptions.unshift("disabled");
|
||||
var lightOptions = [
|
||||
"top", "topleft", "topright",
|
||||
"bottom", "bottomleft", "bottomright",
|
||||
"left", "lefttop", "leftmiddle", "leftbottom",
|
||||
"right", "righttop", "rightmiddle", "rightbottom",
|
||||
"entire",
|
||||
"lightPosTopLeft112", "lightPosTopLeftNewMid", "lightPosTopLeft121",
|
||||
"lightPosBottomLeft14", "lightPosBottomLeft12", "lightPosBottomLeft34", "lightPosBottomLeft11",
|
||||
"lightPosBottomLeft112", "lightPosBottomLeftNewMid", "lightPosBottomLeft121"
|
||||
];
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
lightOptions.unshift("entertainment_center");
|
||||
lightOptions.unshift("entertainment");
|
||||
} else {
|
||||
lightOptions.unshift("disabled");
|
||||
groupLights = Object.keys(hueLights);
|
||||
}
|
||||
|
||||
$('.lidsb').html("");
|
||||
|
||||
var pos = "";
|
||||
for (var id in groupLights) {
|
||||
var lightId = groupLights[id];
|
||||
var lightId_v1 = "/lights/" + lightId;
|
||||
|
||||
var lightName;
|
||||
if (isAPIv2Ready) {
|
||||
var light = hueLights.find(light => light.id === lightId);
|
||||
lightName = light.metadata.name;
|
||||
lightId_v1 = light.id_v1;
|
||||
} else {
|
||||
lightName = hueLights[lightId].name;
|
||||
}
|
||||
|
||||
$('.lidsb').html("");
|
||||
var pos = "";
|
||||
for (var lightid in hueLights) {
|
||||
if (hueType == 'philipshueentertainment') {
|
||||
if (groupLights.indexOf(lightid) == -1) continue;
|
||||
if (isEntertainmentReady) {
|
||||
var lightLocation = {};
|
||||
lightLocation = groupLightsLocations[id];
|
||||
if (lightLocation) {
|
||||
if (isAPIv2Ready) {
|
||||
pos = 0;
|
||||
} else {
|
||||
var x = lightLocation.position.x;
|
||||
var y = lightLocation.position.y;
|
||||
var z = lightLocation.position.z;
|
||||
|
||||
if (groupLightsLocations.hasOwnProperty(lightid)) {
|
||||
lightLocation = groupLightsLocations[lightid];
|
||||
var x = lightLocation[0];
|
||||
var y = lightLocation[1];
|
||||
var z = lightLocation[2];
|
||||
var xval = (x < 0) ? "left" : "right";
|
||||
if (z != 1 && x >= -0.25 && x <= 0.25) xval = "";
|
||||
switch (z) {
|
||||
|
@ -1329,37 +1607,39 @@ function get_hue_lights() {
|
|||
}
|
||||
}
|
||||
}
|
||||
var options = "";
|
||||
for (var opt in lightOptions) {
|
||||
var val = lightOptions[opt];
|
||||
var txt = (val != 'entire' && val != 'disabled') ? 'conf_leds_layout_cl_' : 'wiz_ids_';
|
||||
options += '<option value="' + val + '"';
|
||||
if (pos == val) options += ' selected="selected"';
|
||||
options += '>' + $.i18n(txt + val) + '</option>';
|
||||
}
|
||||
$('.lidsb').append(createTableRow([lightid + ' (' + hueLights[lightid].name + ')', '<select id="hue_' + lightid + '" class="hue_sel_watch form-control">'
|
||||
+ options
|
||||
+ '</select>', '<button class="btn btn-sm btn-primary" onClick=identify_hue_device("' + encodeURIComponent($("#host").val()) + '","' + $('#port').val() + '","' + $("#user").val() + '",' + lightid + ')>' + $.i18n('wiz_hue_blinkblue', lightid) + '</button>']));
|
||||
}
|
||||
|
||||
if (hueType != 'philipshueentertainment') {
|
||||
$('.hue_sel_watch').on("change", function () {
|
||||
var cC = 0;
|
||||
for (var key in hueLights) {
|
||||
if ($('#hue_' + key).val() != "disabled") {
|
||||
cC++;
|
||||
}
|
||||
var options = "";
|
||||
for (var opt in lightOptions) {
|
||||
var val = lightOptions[opt];
|
||||
var txt = (val != 'entire' && val != 'disabled') ? 'conf_leds_layout_cl_' : 'wiz_ids_';
|
||||
options += '<option value="' + val + '"';
|
||||
if (pos == val) options += ' selected="selected"';
|
||||
options += '>' + $.i18n(txt + val) + '</option>';
|
||||
}
|
||||
|
||||
$('.lidsb').append(createTableRow([id + ' (' + lightName + ')', '<select id="hue_' + lightId + '" class="hue_sel_watch form-control">'
|
||||
+ options
|
||||
+ '</select>', '<button class="btn btn-sm btn-primary" onClick=identify_hue_device("' + encodeURIComponent($("#host").val()) + '","' + $('#port').val() + '","' + $("#user").val() + '","' + encodeURIComponent(lightName) + '","' + lightId + '","' + lightId_v1 + '")>' + $.i18n('wiz_hue_blinkblue', id) + '</button>']));
|
||||
}
|
||||
|
||||
if (!isEntertainmentReady) {
|
||||
$('.hue_sel_watch').on("change", function () {
|
||||
var cC = 0;
|
||||
for (var key in hueLights) {
|
||||
if ($('#hue_' + key).val() != "disabled") {
|
||||
cC++;
|
||||
}
|
||||
}
|
||||
|
||||
(cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').prop("disabled", true) : $('#btn_wiz_save').prop("disabled", false);
|
||||
});
|
||||
}
|
||||
$('.hue_sel_watch').trigger('change');
|
||||
}
|
||||
else {
|
||||
var txt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_hue_noids') + '</p>';
|
||||
$('#wizp2_body').append(txt);
|
||||
(cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').prop("disabled", true) : $('#btn_wiz_save').prop("disabled", false);
|
||||
});
|
||||
}
|
||||
$('.hue_sel_watch').trigger('change');
|
||||
}
|
||||
else {
|
||||
var txt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_hue_noids') + '</p>';
|
||||
$('#wizp2_body').append(txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1437,7 +1717,7 @@ function beginWizardYeelight() {
|
|||
|
||||
finalLights.push(lights[key]);
|
||||
|
||||
var idx_content = assignLightPos(key, $('#yee_' + key).val(), name);
|
||||
var idx_content = assignLightPos($('#yee_' + key).val(), name);
|
||||
yeelightLedConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
||||
}
|
||||
}
|
||||
|
@ -1733,7 +2013,7 @@ function beginWizardAtmoOrb() {
|
|||
if (lights[key].host !== "")
|
||||
name += ':' + lights[key].host;
|
||||
|
||||
var idx_content = assignLightPos(key, $('#orb_' + key).val(), name);
|
||||
var idx_content = assignLightPos($('#orb_' + key).val(), name);
|
||||
atmoorbLedConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,8 +62,7 @@ function printHelp {
|
|||
echo "########################################################
|
||||
## A script to compile Hyperion inside a docker container
|
||||
## Requires installed Docker: https://www.docker.com/
|
||||
## Without arguments it will compile Hyperion for Debian Buster (x86_64) and uses Hyperion code from GitHub repository.
|
||||
## Supports Raspberry Pi (armv6l, armv7l) cross compilation (Debian Stretch/Buster) and native compilation (Raspbian Stretch/Buster)
|
||||
## Without arguments it will compile Hyperion for Debian Bullseye (x86_64) and uses Hyperion code from GitHub repository.
|
||||
## For all images and tags currently available, see https://github.com/orgs/hyperion-project/packages
|
||||
##
|
||||
## Homepage: https://www.hyperion-project.org
|
||||
|
@ -72,8 +71,8 @@ echo "########################################################
|
|||
# These are possible arguments to modify the script behaviour with their default values
|
||||
#
|
||||
# docker-compile.sh -h, --help # Show this help message
|
||||
# docker-compile.sh -i, --image # The docker image, e.g., x86_64, armv6l, armv7l, aarch64, rpi-raspbian
|
||||
# docker-compile.sh -t, --tag # The docker tag, e.g., stretch, buster, bullseye, bookworm
|
||||
# docker-compile.sh -i, --image # The docker image, e.g., x86_64, armv6l, armv7l, aarch64
|
||||
# docker-compile.sh -t, --tag # The docker tag, e.g., buster, bullseye, bookworm
|
||||
# docker-compile.sh -b, --type # Release or Debug build
|
||||
# docker-compile.sh -p, --packages # If true, build packages with CPack
|
||||
# docker-compile.sh -l, --local # Run build using local code files
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
#!/bin/bash
|
||||
# Script for downloading a specific open Pull Request Artifact from Hyperion.NG
|
||||
|
||||
# Fixed variables
|
||||
api_url="https://api.github.com/repos/hyperion-project/hyperion.ng"
|
||||
type wget > /dev/null 2> /dev/null
|
||||
hasWget=$?
|
||||
type curl > /dev/null 2> /dev/null
|
||||
hasCurl=$?
|
||||
type python3 > /dev/null 2> /dev/null
|
||||
hasPython3=$?
|
||||
type python > /dev/null 2> /dev/null
|
||||
hasPython2=$?
|
||||
|
||||
if [[ "${hasWget}" -ne 0 ]] && [[ "${hasCurl}" -ne 0 ]]; then
|
||||
echo '---> Critical Error: wget or curl required to download pull request artifacts'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${hasPython3}" -eq 0 ]]; then
|
||||
pythonCmd="python3"
|
||||
else
|
||||
if [[ "${hasPython2}" -eq 0 ]]; then
|
||||
pythonCmd="python"
|
||||
else
|
||||
echo '---> Critical Error: python3 or python2 required to download pull request artifacts'
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function request_call() {
|
||||
if [ $hasWget -eq 0 ]; then
|
||||
echo $(wget --quiet --header="Authorization: token ${PR_TOKEN}" -O - $1)
|
||||
elif [ $hasCurl -eq 0 ]; then
|
||||
echo $(curl -skH "Authorization: token ${PR_TOKEN}" $1)
|
||||
fi
|
||||
}
|
||||
|
||||
while getopts ":c:t:m:r:" opt; do
|
||||
case "$opt" in
|
||||
t) PR_TOKEN=$OPTARG ;;
|
||||
r) run_id=$OPTARG ;;
|
||||
m) ARCHITECTURE=$OPTARG ;;
|
||||
c) CONFIGDIR=$OPTARG ;;
|
||||
esac
|
||||
done
|
||||
shift $(( OPTIND - 1 ))
|
||||
|
||||
# Check for a command line argument (PR number)
|
||||
if [ "$1" == "" ] || [ $# -gt 1 ] || [ -z ${PR_TOKEN} ]; then
|
||||
echo "Usage: $0 -t <git_token> -m <architecture> -r <run_id> -c <hyperion config directory> <PR_NUMBER>" >&2
|
||||
exit 1
|
||||
else
|
||||
pr_number="$1"
|
||||
fi
|
||||
|
||||
# Set welcome message
|
||||
echo '*******************************************************************************'
|
||||
echo 'This script will download a specific open Pull Request Artifact from Hyperion.NG'
|
||||
echo 'Created by hyperion-project.org - the official Hyperion source.'
|
||||
echo '*******************************************************************************'
|
||||
|
||||
# Determine the architecture, if not given
|
||||
if [[ -z ${ARCHITECTURE} ]]; then
|
||||
ARCHITECTURE=`uname -m`
|
||||
fi
|
||||
|
||||
#Test if multiarchitecture setup, i.e. user-space is 32bit
|
||||
if [ ${ARCHITECTURE} == "aarch64" ]; then
|
||||
USER_ARCHITECTURE=$ARCHITECTURE
|
||||
IS_V7L=`cat /proc/$$/maps |grep -m1 -c v7l`
|
||||
if [ $IS_V7L -ne 0 ]; then
|
||||
USER_ARCHITECTURE="armv7l"
|
||||
else
|
||||
IS_V6L=`cat /proc/$$/maps |grep -m1 -c v6l`
|
||||
if [ $IS_V6L -ne 0 ]; then
|
||||
USER_ARCHITECTURE="armv6l"
|
||||
fi
|
||||
fi
|
||||
if [ $ARCHITECTURE != $USER_ARCHITECTURE ]; then
|
||||
echo "---> Identified kernel target architecture: $ARCHITECTURE"
|
||||
echo "---> Identified user space target architecture: $USER_ARCHITECTURE"
|
||||
ARCHITECTURE=$USER_ARCHITECTURE
|
||||
fi
|
||||
fi
|
||||
|
||||
echo 'armv6l armv7l aarch64 x86_64' | grep -qw ${ARCHITECTURE}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "---> Critical Error: Target architecture $ARCHITECTURE is unknown -> abort"
|
||||
exit 1
|
||||
else
|
||||
echo "---> Download Pull Request for identified runtime architecture: $ARCHITECTURE"
|
||||
fi
|
||||
|
||||
# Determine if PR number exists
|
||||
pulls=$(request_call "$api_url/pulls?state=open")
|
||||
|
||||
pr_exists=$(echo "$pulls" | tr '\r\n' ' ' | ${pythonCmd} -c """
|
||||
import json,sys
|
||||
data = json.load(sys.stdin)
|
||||
|
||||
for i in data:
|
||||
if i['number'] == "$pr_number":
|
||||
print('exists')
|
||||
break
|
||||
""" 2>/dev/null)
|
||||
|
||||
if [ "$pr_exists" != "exists" ]; then
|
||||
echo "---> Pull Request $pr_number not found as open PR -> abort"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get head_sha value from 'pr_number'
|
||||
head_sha=$(echo "$pulls" | tr '\r\n' ' ' | ${pythonCmd} -c """
|
||||
import json,sys
|
||||
data = json.load(sys.stdin)
|
||||
|
||||
for i in data:
|
||||
if i['number'] == "$pr_number":
|
||||
print(i['head']['sha'])
|
||||
break
|
||||
""" 2>/dev/null)
|
||||
|
||||
if [ -z "$head_sha" ]; then
|
||||
echo "---> The specified PR #$pr_number has no longer any artifacts or has been closed."
|
||||
echo "---> It may be older than 14 days. Ask the PR creator to recreate the artifacts at the following URL:"
|
||||
echo "---> https://github.com/hyperion-project/hyperion.ng/pull/$pr_number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$run_id" ]; then
|
||||
# Determine run_id from head_sha
|
||||
runs=$(request_call "$api_url/actions/runs?head_sha=$head_sha")
|
||||
run_id=$(echo "$runs" | tr '\r\n' ' ' | ${pythonCmd} -c """
|
||||
import json,sys
|
||||
data = json.load(sys.stdin)
|
||||
|
||||
for i in data['workflow_runs']:
|
||||
if i['name'] == 'Hyperion PR Build':
|
||||
print(i['id'])
|
||||
break
|
||||
""" 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -z "$run_id" ]; then
|
||||
echo "---> The specified PR #$pr_number has no longer any artifacts."
|
||||
echo "---> It may be older than 14 days. Ask the PR creator to recreate the artifacts at the following URL:"
|
||||
echo "---> https://github.com/hyperion-project/hyperion.ng/pull/$pr_number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get archive_download_url from workflow
|
||||
artifacts=$(request_call "$api_url/actions/runs/$run_id/artifacts")
|
||||
archive_download_url=$(echo "$artifacts" | tr '\r\n' ' ' | ${pythonCmd} -c """
|
||||
import json,sys
|
||||
data = json.load(sys.stdin)
|
||||
|
||||
for i in data['artifacts']:
|
||||
if i['name'] == '"$ARCHITECTURE"':
|
||||
print(i['archive_download_url'])
|
||||
break
|
||||
""" 2>/dev/null)
|
||||
|
||||
if [ -z "$archive_download_url" ]; then
|
||||
echo "---> The specified PR #$pr_number has no longer any artifacts."
|
||||
echo "---> It may be older than 14 days. Ask the PR creator to recreate the artifacts at the following URL:"
|
||||
echo "---> https://github.com/hyperion-project/hyperion.ng/pull/$pr_number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download packed PR artifact
|
||||
echo "---> Downloading the Pull Request #$pr_number"
|
||||
if [ $hasCurl -eq 0 ]; then
|
||||
curl -skH "Authorization: token ${PR_TOKEN}" -o $HOME/temp.zip -L --get $archive_download_url
|
||||
elif [ $hasWget -eq 0 ]; then
|
||||
echo "wget"
|
||||
wget --quiet --header="Authorization: token ${PR_TOKEN}" -O $HOME/temp.zip $archive_download_url
|
||||
fi
|
||||
|
||||
# Create new folder & extract PR artifact
|
||||
echo "---> Extracting packed Artifact"
|
||||
mkdir -p $HOME/hyperion_pr$pr_number
|
||||
unzip -p $HOME/temp.zip | tar --strip-components=2 -C $HOME/hyperion_pr$pr_number share/hyperion/ -xz
|
||||
|
||||
# Delete PR artifact
|
||||
echo '---> Remove temporary files'
|
||||
rm $HOME/temp.zip 2>/dev/null
|
||||
|
||||
# Create the startup script
|
||||
echo '---> Create startup script'
|
||||
STARTUP_SCRIPT="#!/bin/bash -e
|
||||
|
||||
# Stop hyperion service, if it is running
|
||||
"'CURRENT_SERVICE=$(systemctl --type service | { grep -o "hyperion.*\.service" || true; })
|
||||
if [[ ! -z ${CURRENT_SERVICE} ]]; then
|
||||
echo "---> Stop current service: ${CURRENT_SERVICE}"
|
||||
|
||||
STOPCMD="systemctl stop --quiet ${CURRENT_SERVICE} --now"
|
||||
USERNAME=${SUDO_USER:-$(whoami)}
|
||||
if [ ${USERNAME} != "root" ]; then
|
||||
STOPCMD="sudo ${STOPCMD}"
|
||||
fi
|
||||
|
||||
${STOPCMD} >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "---> Critical Error: Failed to stop service: ${CURRENT_SERVICE}, Hyperion may not be started. Stop Hyperion manually."
|
||||
else
|
||||
echo "---> Service ${CURRENT_SERVICE} successfully stopped, Hyperion will be started"
|
||||
fi
|
||||
fi'""
|
||||
|
||||
TARGET_CONFIGDIR="$HOME/hyperion_pr$pr_number/config"
|
||||
|
||||
if [[ ! -z ${CONFIGDIR} ]]; then
|
||||
STARTUP_SCRIPT+="
|
||||
# Copy existing configuration file
|
||||
"'echo "Copy existing configuration from "'${CONFIGDIR}"
|
||||
mkdir -p "$TARGET_CONFIGDIR"
|
||||
cp -ri "${CONFIGDIR}/*" "$TARGET_CONFIGDIR""
|
||||
fi
|
||||
|
||||
STARTUP_SCRIPT+="
|
||||
# Start PR artifact
|
||||
cd $HOME/hyperion_pr$pr_number
|
||||
./bin/hyperiond -d -u $TARGET_CONFIGDIR"
|
||||
|
||||
# Place startup script
|
||||
echo "$STARTUP_SCRIPT" > $HOME/hyperion_pr$pr_number/$pr_number.sh
|
||||
|
||||
# Set the executen bit
|
||||
chmod +x -R $HOME/hyperion_pr$pr_number/$pr_number.sh
|
||||
|
||||
echo "*******************************************************************************"
|
||||
echo "Download finished!"
|
||||
$REBOOTMESSAGE
|
||||
echo "You can test the pull request with this command: ~/hyperion_pr$pr_number/$pr_number.sh"
|
||||
echo "Remove the test installation with: rm -R ~/hyperion_pr$pr_number"
|
||||
echo "Feedback is welcome at https://github.com/hyperion-project/hyperion.ng/pull/$pr_number"
|
||||
echo "*******************************************************************************"
|
|
@ -48,6 +48,7 @@ macro(DeployMacOS TARGET)
|
|||
foreach(PLUGIN "platforms" "sqldrivers" "imageformats")
|
||||
if(EXISTS ${PLUGIN_DIR}/${PLUGIN})
|
||||
file(GLOB files "${PLUGIN_DIR}/${PLUGIN}/*")
|
||||
list(FILTER files EXCLUDE REGEX ".*libqwebp\\.dylib$")
|
||||
foreach(file ${files})
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
EXECUTABLES ${file}
|
||||
|
@ -132,28 +133,33 @@ macro(DeployLinux TARGET)
|
|||
include(GetPrerequisites)
|
||||
|
||||
set(SYSTEM_LIBS_SKIP
|
||||
"libatomic"
|
||||
"libc"
|
||||
"libdbus"
|
||||
"libdl"
|
||||
"libexpat"
|
||||
"libfontconfig"
|
||||
"libfreetype"
|
||||
"libgcc_s"
|
||||
"libgcrypt"
|
||||
"libGL"
|
||||
"libGLdispatch"
|
||||
"libglib"
|
||||
"libglib-2"
|
||||
"libGLX"
|
||||
"libgpg-error"
|
||||
"liblz4"
|
||||
"liblzma"
|
||||
"libm"
|
||||
"libpcre"
|
||||
"libpcre2"
|
||||
"libpthread"
|
||||
"librt"
|
||||
"libstdc++"
|
||||
"libsystemd"
|
||||
"libudev"
|
||||
"libusb"
|
||||
"libusb-1"
|
||||
"libutil"
|
||||
"libX11"
|
||||
"libuuid"
|
||||
"libz"
|
||||
)
|
||||
)
|
||||
|
||||
if (ENABLE_DISPMANX)
|
||||
list(APPEND SYSTEM_LIBS_SKIP "libcec")
|
||||
|
@ -161,7 +167,9 @@ macro(DeployLinux TARGET)
|
|||
|
||||
# Extract dependencies ignoring the system ones
|
||||
get_prerequisites(${TARGET_FILE} DEPENDENCIES 0 1 "" "")
|
||||
|
||||
|
||||
message(STATUS "Dependencies for target file: ${DEPENDENCIES}")
|
||||
|
||||
# Append symlink and non-symlink dependencies to the list
|
||||
set(PREREQUISITE_LIBS "")
|
||||
foreach(DEPENDENCY ${DEPENDENCIES})
|
||||
|
@ -203,6 +211,8 @@ macro(DeployLinux TARGET)
|
|||
get_filename_component(file_canonical ${openssl_lib} REALPATH)
|
||||
gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
|
||||
endforeach()
|
||||
else()
|
||||
message( WARNING "OpenSSL NOT found (https webserver will not work)")
|
||||
endif(OPENSSL_FOUND)
|
||||
|
||||
# Detect the Qt plugin directory, source: https://github.com/lxde/lxqt-qtplugin/blob/master/src/CMakeLists.txt
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
execute_process( COMMAND git config --global --add safe.directory ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ERROR_QUIET )
|
||||
execute_process( COMMAND git log -1 --format=%cn-%t/%h-%ct WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE BUILD_ID ERROR_QUIET )
|
||||
execute_process( COMMAND sh -c "git branch | grep '^*' | sed 's;^*;;g' " WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE VERSION_ID ERROR_QUIET )
|
||||
execute_process( COMMAND sh -c "git remote --verbose | grep origin | grep fetch | cut -f2 | cut -d' ' -f1" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_REMOTE_PATH ERROR_QUIET )
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>LSUIElement</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>Source Code</key>
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
Origin: Hyperion-Project
|
||||
Label: apt.hyperion-project.org
|
||||
Codename: bionic
|
||||
Architectures: amd64 armhf arm64
|
||||
Components: main
|
||||
Description: Official APT Repository by Hyperion Project
|
||||
SignWith: yes
|
||||
|
||||
Origin: Hyperion-Project
|
||||
Label: apt.hyperion-project.org
|
||||
Codename: focal
|
||||
|
@ -32,9 +24,8 @@ SignWith: yes
|
|||
|
||||
Origin: Hyperion-Project
|
||||
Label: apt.hyperion-project.org
|
||||
Suite: oldoldstable
|
||||
Codename: stretch
|
||||
Architectures: armhf amd64
|
||||
Codename: lunar
|
||||
Architectures: amd64
|
||||
Components: main
|
||||
Description: Official APT Repository by Hyperion Project
|
||||
SignWith: yes
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(qmdnsengine)
|
||||
|
||||
|
|
|
@ -133,6 +133,9 @@ endif()
|
|||
|
||||
if(ENABLE_PROTOBUF_SERVER)
|
||||
set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system")
|
||||
|
||||
# defines for 3rd party sub-modules
|
||||
set(ABSL_PROPAGATE_CXX_STD ON CACHE BOOL "Build abseil-cpp with C++ version requirements propagated")
|
||||
|
||||
if (USE_SYSTEM_PROTO_LIBS)
|
||||
find_package(Protobuf REQUIRED)
|
||||
|
@ -160,6 +163,7 @@ if(ENABLE_PROTOBUF_SERVER)
|
|||
|
||||
# define the protobuf library
|
||||
set(PROTOBUF_LIBRARIES protobuf::libprotobuf)
|
||||
|
||||
endif()
|
||||
|
||||
# redefine at parent scope
|
||||
|
@ -266,7 +270,7 @@ if(ENABLE_DEV_NETWORK)
|
|||
set(USE_SYSTEM_MBEDTLS_LIBS OFF)
|
||||
endif (NOT MBEDTLS_FOUND)
|
||||
else()
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0071 NEW)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8468eab83bacc8bbd6cb5ae22197af06a9437b2d
|
||||
Subproject commit 0100f6a5779831fa7a651e4b67ef389a8752bd9b
|
|
@ -1 +1 @@
|
|||
Subproject commit 8c89224991adff88d53cd380f42a2baa36f91454
|
||||
Subproject commit 1873d3bfc2da771672bd8e7e8f41f57e0af77f33
|
|
@ -1 +1 @@
|
|||
Subproject commit f0dc78d7e6e331b8c6bb2d5283e06aa26883ca7c
|
||||
Subproject commit 2c5fa078d8e86e5f4bd34e6f4c9ea9e8d7d4d44a
|
|
@ -1 +1 @@
|
|||
Subproject commit 1ba8e385708fb7802b09c0177a7ea4293948e25c
|
||||
Subproject commit 1f47b59ed603223d1376d36c788c89af67ae2fdc
|
|
@ -1,34 +1,12 @@
|
|||
|
||||
# With Docker
|
||||
If you are using [Docker](https://www.docker.com/), you can compile Hyperion inside a docker container. This keeps your system clean and with a simple script it's easy to use. Supported is also cross compiling for Raspberry Pi (Debian Stretch or higher). To compile Hyperion just execute one of the following commands.
|
||||
If you are using [Docker](https://www.docker.com/), you can compile Hyperion inside a docker container. This keeps your system clean and with a simple script it's easy to use. Supported is also cross compiling for Raspberry Pi (Debian Buster or higher). To compile Hyperion just execute one of the following commands.
|
||||
|
||||
The compiled binaries and packages will be available at the deploy folder next to the script.<br/>
|
||||
Note: call the script with `./docker-compile.sh -h` for more options.
|
||||
|
||||
## Native compilation on Raspberry Pi for:
|
||||
|
||||
**Raspbian Stretch**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i rpi-raspbian -t stretch
|
||||
```
|
||||
**Raspbian Buster/Raspberry Pi OS**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i rpi-raspbian -t buster
|
||||
```
|
||||
**Raspberry Pi OS Bullseye**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i rpi-raspbian -t bullseye
|
||||
```
|
||||
**Raspberry Pi OS Bookworm**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i rpi-raspbian -t bookworm
|
||||
```
|
||||
## Cross compilation on x86_64 for:
|
||||
|
||||
**x86_64 (Debian Stretch):**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i x86_64 -t stretch
|
||||
```
|
||||
**x86_64 (Debian Buster):**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i x86_64 -t buster
|
||||
|
@ -41,10 +19,6 @@ wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/
|
|||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i x86_64 -t bookworm
|
||||
```
|
||||
**Raspberry Pi v1 & ZERO (Debian Stretch)**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i armv6l -t stretch
|
||||
```
|
||||
**Raspberry Pi v1 & ZERO (Debian Buster)**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i armv6l -t buster
|
||||
|
@ -57,10 +31,6 @@ wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/
|
|||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i armv6l -t bookworm
|
||||
```
|
||||
**Raspberry Pi 2/3/4 (Debian Stretch)**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i armv7l -t stretch
|
||||
```
|
||||
**Raspberry Pi 2/3/4 (Debian Buster)**
|
||||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i armv7l -t buster
|
||||
|
@ -69,6 +39,7 @@ wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/
|
|||
```console
|
||||
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -i armv7l -t bullseye
|
||||
```
|
||||
|
||||
## Cross compilation on x86_64 for developers
|
||||
Using additional options you can cross compile locally
|
||||
-l: use a local hyperion source code directory rather than cloning from GitHub
|
||||
|
@ -79,6 +50,7 @@ Using additional options you can cross compile locally
|
|||
cd $HYPERION_HOME
|
||||
./bin/scripts/docker-compile.sh -l -c -i armv7l -t bullseye
|
||||
```
|
||||
|
||||
# The usual way
|
||||
|
||||
## Debian/Ubuntu/Win10LinuxSubsystem
|
||||
|
@ -94,7 +66,7 @@ sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev
|
|||
|
||||
```console
|
||||
sudo apt-get update
|
||||
sudo apt-get install git cmake build-essential qt6-base-dev libqt6serialport6-dev libvulkan-dev libgl1-mesa-dev libusb-1.0-0-dev python3-dev libasound2-dev libturbojpeg0-dev libjpeg-dev libssl-dev pkg-config
|
||||
sudo apt-get install git cmake build-essential qt6-base-dev libqt6serialport6-dev libxkbcommon-dev libvulkan-dev libgl1-mesa-dev libusb-1.0-0-dev python3-dev libasound2-dev libturbojpeg0-dev libjpeg-dev libssl-dev pkg-config
|
||||
```
|
||||
|
||||
**For Linux X11/XCB grabber support**
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# Build a new Release
|
||||
|
||||
## Preparation
|
||||
|
||||
- Check, if new Ubuntu or Debian versions need to be added as build environment or remove unsupported (optional)
|
||||
|
||||
- Merge all outstading PRs or changes valid to be included in the release. Address any github-code-scanning findings before.
|
||||
|
||||
- Update missing non-English translations in Poeditor (optional)
|
||||
|
||||
- Export translations provided since last release from Poeditor into Hyperion-Git
|
||||
|
||||
- Update the `.version` file with the new release version
|
||||
|
||||
- Update the `CHANGELOG.md` with missing documentation and change from "Unreleased" to new release version.
|
||||
|
||||
- Push updated `.version` & `CHANGELOG.md` to master or create an PR (in case you might want to add some minor, late fixes)
|
||||
|
||||
## Execution
|
||||
|
||||
- Push a new tag to the master branch of hyperion-project/hyperion.ng repository, e.g. `git push origin 2.0.15`
|
||||
The push will create a draft release including an update to Hyperion's apt repository
|
||||
|
||||
- On Hyperion's apt repository,
|
||||
- Backup the main directory, in case a fall back is requried (optional)
|
||||
- Move the content of the `draft-release` directory into the main diectory
|
||||
|
||||
- On GitHub, edit the draft release's description and publish the release
|
||||
(this triggers the HyperBian build on top of the release)
|
||||
|
||||
- Check the HyperBian is build sucessfully with the correct release
|
||||
|
||||
## Rollover
|
||||
|
||||
Prepare next beta release and nighly builds
|
||||
|
||||
- Update the `.version` file with the next release version incl. beta.1, e.g. `2.0.16-beta.1`
|
||||
|
||||
- Add an "Unreleased" selection to `CHANGELOG.md`, plus empty sections to allow capturing changes.
|
||||
|
||||
- Push updated `.version` & `CHANGELOG.md` to master
|
||||
|
|
@ -7,12 +7,12 @@ In case of problems, it is recommended checking with the wider Hyperion communit
|
|||
| Hardware | OS | Version | Screen-Grabber | Package | Comments |
|
||||
|-----------|-----------------|--------------------|-----------------------------------------|-------------------------------------------------------------------------------|------------------------------------|
|
||||
| X64 | Windows | 10 | QT¹ | [Windows-AMD64.exe](https://github.com/hyperion-project/hyperion.ng/releases) | Direct X9 Grabber via self-compile |
|
||||
| X64 | Ubuntu | 18.04, 20.04, 22.04² | QT¹<br/>XCB/X11¹ | [Linux-x86_64.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| X64 | Debian | 9, 10, 11, 12³| QT¹<br/>XCB/X11¹ | [Linux-x86_64.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 4 | HyperBian | 9, 10, 11, 12³| QT¹<br/>XCB/X11¹<br/>DispmanX | [HyperBian.zip](https://github.com/Hyperion-Project/HyperBian/releases) | |
|
||||
| RPi 4 | Raspberry Pi OS | 9, 10, 11, 12³| QT¹<br/>XCB/X11¹<br/>DispmanX | [Linux-armv7l.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 3 /3+ | HyperBian | 9, 10, 11, 12³| QT¹<br/>XCB/X11¹<br/>DispmanX | [HyperBian.zip](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 3 /3+ | Raspberry Pi OS | 9, 10, 11, 12³| QT¹<br/>XCB/X11¹<br/>DispmanX | [Linux-armv7l.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| X64 | Ubuntu | 20.04, 22.04, 23.04² | QT¹<br/>XCB/X11¹ | [Linux-x86_64.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| X64 | Debian | 10, 11, 12³ | QT¹<br/>XCB/X11¹ | [Linux-x86_64.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 4 | HyperBian | 10, 11, 12³ | QT¹<br/>XCB/X11¹<br/>DispmanX | [HyperBian.zip](https://github.com/Hyperion-Project/HyperBian/releases) | |
|
||||
| RPi 4 | Raspberry Pi OS | 10, 11, 12³ | QT¹<br/>XCB/X11¹<br/>DispmanX | [Linux-armv7l.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 3 /3+ | HyperBian | 10, 11, 12³ | QT¹<br/>XCB/X11¹<br/>DispmanX | [HyperBian.zip](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 3 /3+ | Raspberry Pi OS | 10, 11, 12³ | QT¹<br/>XCB/X11¹<br/>DispmanX | [Linux-armv7l.deb](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
|
||||
## Unofficial
|
||||
In case you have an additional working setups you would like to share with the community, please get in touch or issue a PR to have the table updated.
|
||||
|
@ -20,13 +20,18 @@ In case you have an additional working setups you would like to share with the c
|
|||
| Hardware | OS | Version | Screen-Grabber | Package | Comments |
|
||||
|---------------|-----------------|----------------|-----------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| X64 | macOS | 11, 12 | QT<br>OSX | [macOS-x86_64.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | M1 not tested |
|
||||
| X64 | Fedora | 35 | QT¹<br/>XCB/X11¹ | [Linux-x86_64.rpm](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| X64 | Fedora | 38 | QT¹<br/>XCB/X11¹ | [Linux-x86_64.rpm](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| X64 | Arch | | QT¹<br/>XCB/X11¹ | [Linux-x86_64.rpm](https://github.com/hyperion-project/hyperion.ng/releases) | |
|
||||
| RPi 0/ 1 / 2 | Raspberry Pi OS | 9, 10, 11, 12³| QT¹<br/>XCB/X11¹<br/>DispmanX | [Linux-armv6l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | No recommended |
|
||||
| RPi 0/ 1 / 2 | Raspberry Pi OS | 10, 11, 12³| QT¹<br/>XCB/X11¹<br/>DispmanX | [Linux-armv6l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | No recommended |
|
||||
| X64 | LibreElec | 11.x (Nexus) | [Kodi add-on](https://github.com/hyperion-project/hyperion.kodi/releases) | [Linux-x86_64.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| RPi 4 | LibreElec | 11.x (Nexus) | - | [Linux-armv7l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| RPi 4 | LibreElec | 10.x (Matrix) | - | [Linux-armv7l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| RPi 4 | LibreElec | 9.2.x (Leia) | QT¹<br/>DispmanX | [Linux-armv7l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| RPi 3 /3+ | LibreElec | 11.x (Nexus) | - | [Linux-armv7l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| RPi 3 /3+ | LibreElec | 10.x (Matrix) | - | [Linux-armv7l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| RPi 3 /3+ | LibreElec | 9.2.x (Leia) | QT¹<br/>DispmanX | [Linux-armv7l.tar.gz](https://github.com/hyperion-project/hyperion.ng/releases) | [Install on LibreELEC](https://hyperion-project.org/forum/index.php?thread/10463-install-hyperion-ng-on-libreelec-x86-64-rpi-inoffiziell-unofficially/) |
|
||||
| Amlogic | CoreElec | 21.x (Omega) | Amlogic | CoreElec Plugin | Supported via CoreElec project |
|
||||
| Amlogic | CoreElec | 20.x (Nexus) | Amlogic | CoreElec Plugin | Supported via CoreElec project |
|
||||
| Amlogic | CoreElec | 19.x (Matrix) | Amlogic | CoreElec Plugin | Supported via CoreElec project |
|
||||
| Amlogic | CoreElec | 9.2.x (Leia) | Amlogic | CoreElec Plugin | Supported via CoreElec project |
|
||||
| Vero4K | OSMC | | | | [hyperion-vero4k](https://github.com/hissingshark/hyperion-vero4k) |
|
||||
|
@ -35,5 +40,5 @@ In case you have an additional working setups you would like to share with the c
|
|||
Legend
|
||||
---
|
||||
¹ Requires an environment with `DISPLAY` defined\
|
||||
² 18=Bionic Beaver, 20=Focal Fossa, 22=Jammy Jellyfish\
|
||||
³ 9=Stretch, 10=Buster, 11=Bullseye, 12=Bookworm
|
||||
² 20=Focal Fossa, 22=Jammy Jellyfish, 23=Lunar Lobster\
|
||||
³ 10=Buster, 11=Bullseye, 12=Bookworm
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 234 KiB |
|
@ -9,8 +9,8 @@
|
|||
"cropTop": 0,
|
||||
"fps": 30,
|
||||
"grayscale": false,
|
||||
"imageSource": "url",
|
||||
"imageSource": "file",
|
||||
"reverse": false,
|
||||
"url": "https://i.gifer.com/embedded/download/1j6F.gif"
|
||||
"file": "matrix.gif"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,11 @@ private slots:
|
|||
///
|
||||
void handleInstanceStateChange(InstanceState state, quint8 instance, const QString &name = QString());
|
||||
|
||||
///
|
||||
/// @brief Stream a new LED Colors update
|
||||
///
|
||||
void streamLedColorsUpdate();
|
||||
|
||||
signals:
|
||||
///
|
||||
/// Signal emits with the reply message provided with handleMessage()
|
||||
|
|
|
@ -39,8 +39,8 @@ class AudioGrabberWindows : public AudioGrabber
|
|||
HANDLE notificationEvent;
|
||||
std::atomic<bool> isRunning{ false };
|
||||
|
||||
static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCTSTR deviceDescStr,
|
||||
LPCTSTR deviceModelStr, LPVOID context)
|
||||
static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCWSTR deviceDescStr,
|
||||
LPCWSTR deviceModelStr, LPVOID context)
|
||||
{
|
||||
// Skip undefined audio devices
|
||||
if (deviceIdGuid == NULL)
|
||||
|
@ -50,12 +50,15 @@ static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCTSTR devic
|
|||
|
||||
AudioGrabber::DeviceProperties device;
|
||||
|
||||
// Process Device Information
|
||||
QString deviceName = QString::fromWCharArray(deviceDescStr);
|
||||
|
||||
// Process Device ID
|
||||
LPOLESTR deviceIdStr;
|
||||
HRESULT res = StringFromCLSID(*deviceIdGuid, &deviceIdStr);
|
||||
if (FAILED(res))
|
||||
{
|
||||
Error(Logger::getInstance("AUDIOGRABBER"), "Failed to get CLSID-string for %s with error: 0x%08x: %s", deviceDescStr, res, std::system_category().message(res).c_str());
|
||||
Error(Logger::getInstance("AUDIOGRABBER"), "Failed to get CLSID-string for %s with error: 0x%08x: %s", QSTRING_CSTR(deviceName), res, std::system_category().message(res).c_str());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -63,10 +66,7 @@ static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCTSTR devic
|
|||
|
||||
CoTaskMemFree(deviceIdStr);
|
||||
|
||||
// Process Device Information
|
||||
QString deviceName = QString::fromLocal8Bit(deviceDescStr);
|
||||
|
||||
Debug(Logger::getInstance("AUDIOGRABBER"), "Found Audio Device: %s", deviceDescStr);
|
||||
Debug(Logger::getInstance("AUDIOGRABBER"), "Found Audio Device: %s", QSTRING_CSTR(deviceName));
|
||||
|
||||
device.id = deviceId;
|
||||
device.name = deviceName;
|
||||
|
|
|
@ -413,9 +413,13 @@ namespace hyperion
|
|||
}
|
||||
|
||||
// Compute the average of each color channel
|
||||
const uint8_t avgRed = uint8_t(std::min(std::lround(sqrt(static_cast<double>(cummRed/pixelNum))), 255L));
|
||||
const uint8_t avgGreen = uint8_t(std::min(std::lround(sqrt(static_cast<double>(cummGreen/pixelNum))), 255L));
|
||||
const uint8_t avgBlue = uint8_t(std::min(std::lround(sqrt(static_cast<double>(cummBlue/pixelNum))), 255L));
|
||||
|
||||
#ifdef WIN32
|
||||
#undef min
|
||||
#endif
|
||||
const uint8_t avgRed = static_cast<uint8_t>(std::min(std::lround(std::sqrt(static_cast<double>(cummRed / pixelNum))), 255L));
|
||||
const uint8_t avgGreen = static_cast<uint8_t>(std::min(std::lround(sqrt(static_cast<double>(cummGreen / pixelNum))), 255L));
|
||||
const uint8_t avgBlue = static_cast<uint8_t>(std::min(std::lround(sqrt(static_cast<double>(cummBlue / pixelNum))), 255L));
|
||||
|
||||
// Return the computed color
|
||||
return {avgRed, avgGreen, avgBlue};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
// QT includes
|
||||
#include <QString>
|
||||
#include <QJsonArray>
|
||||
|
||||
// Forward class declarations
|
||||
namespace Json { class Value; }
|
||||
|
@ -73,7 +74,7 @@ inline ColorOrder stringToColorOrder(const QString & order)
|
|||
}
|
||||
|
||||
///
|
||||
/// The Led structure contains the definition of the image portion used to determine a single led's
|
||||
/// The Led structure contains the definition of the image portion used to determine a single LED's
|
||||
/// color.
|
||||
/// @verbatim
|
||||
/// |--------------------image--|
|
||||
|
@ -89,39 +90,66 @@ inline ColorOrder stringToColorOrder(const QString & order)
|
|||
///
|
||||
struct Led
|
||||
{
|
||||
/// The minimum vertical scan line included for this leds color
|
||||
/// The minimum vertical scan line included for this LEDs color
|
||||
double minX_frac;
|
||||
/// The maximum vertical scan line included for this leds color
|
||||
/// The maximum vertical scan line included for this LEDs color
|
||||
double maxX_frac;
|
||||
/// The minimum horizontal scan line included for this leds color
|
||||
/// The minimum horizontal scan line included for this LEDs color
|
||||
double minY_frac;
|
||||
/// The maximum horizontal scan line included for this leds color
|
||||
/// The maximum horizontal scan line included for this LEDs color
|
||||
double maxY_frac;
|
||||
/// A LEDs at {0,0,0,0} is not visible and therefore treated as blacklisted
|
||||
bool isBlacklisted {false};
|
||||
/// the color order
|
||||
ColorOrder colorOrder;
|
||||
};
|
||||
|
||||
///
|
||||
/// The LedString contains the image integration information of the leds
|
||||
/// The LedString contains the image integration information of the LEDs
|
||||
///
|
||||
class LedString
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Returns the led specifications
|
||||
/// Returns the LED specifications
|
||||
///
|
||||
/// @return The list with led specifications
|
||||
///
|
||||
std::vector<Led>& leds();
|
||||
|
||||
///
|
||||
/// Returns the led specifications
|
||||
/// Returns the LED specifications
|
||||
///
|
||||
/// @return The list with led specifications
|
||||
///
|
||||
const std::vector<Led>& leds() const;
|
||||
|
||||
///
|
||||
/// Returns the IDs of blacklisted LEDs
|
||||
///
|
||||
/// @return ID List of blacklisted LEDs
|
||||
///
|
||||
std::vector<int>& blacklistedLedIds();
|
||||
|
||||
///
|
||||
/// Returns the IDs of blacklisted LEDs
|
||||
///
|
||||
/// @return ID List of blacklisted LEDs
|
||||
///
|
||||
const std::vector<int>& blacklistedLedIds() const;
|
||||
|
||||
///
|
||||
/// Check, if teh layout has blacklisted LEDs configured
|
||||
///
|
||||
/// @return True, if blacklisted LEDs are configured
|
||||
///
|
||||
bool hasBlackListedLeds ();
|
||||
|
||||
static LedString createLedString(const QJsonArray& ledConfigArray, const ColorOrder deviceOrder);
|
||||
|
||||
private:
|
||||
/// The list with led specifications
|
||||
std::vector<Led> mLeds;
|
||||
/// The list with LED specifications
|
||||
std::vector<Led> _leds;
|
||||
/// The list containing IDs of blacklisted LED
|
||||
std::vector<int> _blacklistedLedIds;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#define QSTRING_CSTR(str) str.toLocal8Bit().constData()
|
||||
#define QSTRING_CSTR(str) str.toUtf8().constData()
|
||||
typedef QList< int > QIntList;
|
||||
|
||||
|
||||
|
|
|
@ -177,44 +177,6 @@ namespace hyperion {
|
|||
return adjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the 'led-string' with the integration area definition per led and the color
|
||||
* ordering of the RGB channels
|
||||
* @param ledsConfig The configuration of the led areas
|
||||
* @param deviceOrder The default RGB channel ordering
|
||||
* @return The constructed ledstring
|
||||
*/
|
||||
static LedString createLedString(const QJsonArray& ledConfigArray, const ColorOrder deviceOrder)
|
||||
{
|
||||
LedString ledString;
|
||||
const QString deviceOrderStr = colorOrderToString(deviceOrder);
|
||||
|
||||
for (signed i = 0; i < ledConfigArray.size(); ++i)
|
||||
{
|
||||
const QJsonObject& ledConfig = ledConfigArray[i].toObject();
|
||||
Led led;
|
||||
|
||||
led.minX_frac = qMax(0.0, qMin(1.0, ledConfig["hmin"].toDouble()));
|
||||
led.maxX_frac = qMax(0.0, qMin(1.0, ledConfig["hmax"].toDouble()));
|
||||
led.minY_frac = qMax(0.0, qMin(1.0, ledConfig["vmin"].toDouble()));
|
||||
led.maxY_frac = qMax(0.0, qMin(1.0, ledConfig["vmax"].toDouble()));
|
||||
// Fix if the user swapped min and max
|
||||
if (led.minX_frac > led.maxX_frac)
|
||||
{
|
||||
std::swap(led.minX_frac, led.maxX_frac);
|
||||
}
|
||||
if (led.minY_frac > led.maxY_frac)
|
||||
{
|
||||
std::swap(led.minY_frac, led.maxY_frac);
|
||||
}
|
||||
|
||||
// Get the order of the rgb channels for this led (default is device order)
|
||||
led.colorOrder = stringToColorOrder(ledConfig["colorOrder"].toString(deviceOrderStr));
|
||||
ledString.leds().push_back(led);
|
||||
}
|
||||
return ledString;
|
||||
}
|
||||
|
||||
static QSize getLedLayoutGridSize(const QJsonArray& ledConfigArray)
|
||||
{
|
||||
std::vector<int> midPointsX;
|
||||
|
|
|
@ -140,6 +140,8 @@ void JsonAPI::initialize()
|
|||
connect(this, &JsonAPI::toggleSuspendAll, _instanceManager, &HyperionIManager::triggerToggleSuspend);
|
||||
connect(this, &JsonAPI::idleAll, _instanceManager, &HyperionIManager::triggerIdle);
|
||||
connect(this, &JsonAPI::toggleIdleAll, _instanceManager, &HyperionIManager::triggerToggleIdle);
|
||||
|
||||
connect(_ledStreamTimer, &QTimer::timeout, this, &JsonAPI::streamLedColorsUpdate, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
bool JsonAPI::handleInstanceSwitch(quint8 inst, bool forced)
|
||||
|
@ -404,7 +406,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
|
|||
activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY);
|
||||
int currentPriority = _hyperion->getCurrentPriority();
|
||||
|
||||
for(int priority : qAsConst(activePriorities))
|
||||
for(int priority : std::as_const(activePriorities))
|
||||
{
|
||||
const Hyperion::InputInfo &priorityInfo = _hyperion->getPriorityInfo(priority);
|
||||
|
||||
|
@ -1139,6 +1141,11 @@ void JsonAPI::handleComponentStateCommand(const QJsonObject &message, const QStr
|
|||
sendSuccessReply(command, tan);
|
||||
}
|
||||
|
||||
void JsonAPI::streamLedColorsUpdate()
|
||||
{
|
||||
emit streamLedcolorsUpdate(_currentLedValues);
|
||||
}
|
||||
|
||||
void JsonAPI::handleLedColorsCommand(const QJsonObject &message, const QString &command, int tan)
|
||||
{
|
||||
// create result
|
||||
|
@ -1154,21 +1161,21 @@ void JsonAPI::handleLedColorsCommand(const QJsonObject &message, const QString &
|
|||
_streaming_leds_reply["tan"] = tan;
|
||||
|
||||
connect(_hyperion, &Hyperion::rawLedColors, this, [=](const std::vector<ColorRgb> &ledValues) {
|
||||
_currentLedValues = ledValues;
|
||||
|
||||
// necessary because Qt::UniqueConnection for lambdas does not work until 5.9
|
||||
// see: https://bugreports.qt.io/browse/QTBUG-52438
|
||||
if (!_ledStreamConnection)
|
||||
_ledStreamConnection = connect(_ledStreamTimer, &QTimer::timeout, this, [=]() {
|
||||
emit streamLedcolorsUpdate(_currentLedValues);
|
||||
},
|
||||
Qt::UniqueConnection);
|
||||
if (ledValues != _currentLedValues)
|
||||
{
|
||||
_currentLedValues = ledValues;
|
||||
if (!_ledStreamTimer->isActive() || _ledStreamTimer->interval() != streaming_interval)
|
||||
{
|
||||
_ledStreamTimer->start(streaming_interval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ledStreamTimer->stop();
|
||||
}
|
||||
});
|
||||
|
||||
// start the timer
|
||||
if (!_ledStreamTimer->isActive() || _ledStreamTimer->interval() != streaming_interval)
|
||||
_ledStreamTimer->start(streaming_interval);
|
||||
},
|
||||
Qt::UniqueConnection);
|
||||
// push once
|
||||
_hyperion->update();
|
||||
}
|
||||
|
@ -1387,7 +1394,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject &message, const QString &
|
|||
if (API::getPendingTokenRequests(vec))
|
||||
{
|
||||
QJsonArray arr;
|
||||
for (const auto &entry : qAsConst(vec))
|
||||
for (const auto &entry : std::as_const(vec))
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj["comment"] = entry.comment;
|
||||
|
|
|
@ -199,7 +199,7 @@ void JsonCB::handlePriorityUpdate(int currentPriority, const PriorityMuxer::Inpu
|
|||
|
||||
activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY);
|
||||
|
||||
for (int priority : qAsConst(activePriorities)) {
|
||||
for (int priority : std::as_const(activePriorities)) {
|
||||
|
||||
const Hyperion::InputInfo& priorityInfo = activeInputs[priority];
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/cec)
|
|||
FILE (GLOB CEC_SOURCES "${CURRENT_HEADER_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.cpp")
|
||||
|
||||
add_library(cechandler ${CEC_SOURCES})
|
||||
list(GET CEC_LIBRARIES 0 CEC_LIBRARIES)
|
||||
add_definitions(-DCEC_LIBRARY="${CEC_LIBRARIES}")
|
||||
|
||||
include_directories(${CEC_INCLUDE_DIRS})
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <QThreadStorage>
|
||||
#include <QUuid>
|
||||
#include <QDir>
|
||||
#include <QMetaType>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdexcept>
|
||||
|
@ -425,15 +426,15 @@ void DBManager::doAddBindValue(QSqlQuery& query, const QVariantList& variants) c
|
|||
auto t = variant.userType();
|
||||
switch(t)
|
||||
{
|
||||
case QVariant::UInt:
|
||||
case QVariant::Int:
|
||||
case QVariant::Bool:
|
||||
case QMetaType::UInt:
|
||||
case QMetaType::Int:
|
||||
case QMetaType::Bool:
|
||||
query.addBindValue(variant.toInt());
|
||||
break;
|
||||
case QVariant::Double:
|
||||
case QMetaType::Double:
|
||||
query.addBindValue(variant.toFloat());
|
||||
break;
|
||||
case QVariant::ByteArray:
|
||||
case QMetaType::QByteArray:
|
||||
query.addBindValue(variant.toByteArray());
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -224,7 +224,7 @@ void EffectFileHandler::updateEffects()
|
|||
}
|
||||
|
||||
QMap<QString, EffectDefinition> availableEffects;
|
||||
for (const QString& path : qAsConst(efxPathList))
|
||||
for (const QString& path : std::as_const(efxPathList))
|
||||
{
|
||||
QDir directory(path);
|
||||
if (!directory.exists())
|
||||
|
@ -241,8 +241,8 @@ void EffectFileHandler::updateEffects()
|
|||
else
|
||||
{
|
||||
int efxCount = 0;
|
||||
QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
|
||||
for (const QString& filename : qAsConst(filenames))
|
||||
const QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
|
||||
for (const QString& filename : filenames)
|
||||
{
|
||||
EffectDefinition def;
|
||||
if (loadEffectDefinition(path, filename, def))
|
||||
|
@ -268,8 +268,8 @@ void EffectFileHandler::updateEffects()
|
|||
|
||||
QString schemaPath = path + "schema" + '/';
|
||||
directory.setPath(schemaPath);
|
||||
QStringList schemaFileNames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
|
||||
for (const QString& schemaFileName : qAsConst(schemaFileNames))
|
||||
const QStringList schemaFileNames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
|
||||
for (const QString& schemaFileName : schemaFileNames)
|
||||
{
|
||||
EffectSchema pyEffect;
|
||||
if (loadEffectSchema(path, directory.filePath(schemaFileName), pyEffect))
|
||||
|
@ -282,7 +282,7 @@ void EffectFileHandler::updateEffects()
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& item : qAsConst(availableEffects))
|
||||
for (const auto& item : std::as_const(availableEffects))
|
||||
{
|
||||
_availableEffects.push_back(item);
|
||||
}
|
||||
|
|
|
@ -269,7 +269,7 @@ int MessageForwarder::startJsonTargets(const QJsonObject& config)
|
|||
|
||||
if (!_jsonTargets.isEmpty())
|
||||
{
|
||||
for (const auto& targetHost : qAsConst(_jsonTargets))
|
||||
for (const auto& targetHost : std::as_const(_jsonTargets))
|
||||
{
|
||||
Info(_log, "Forwarding now to JSON-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ void MessageForwarder::stopJsonTargets()
|
|||
if (!_jsonTargets.isEmpty())
|
||||
{
|
||||
disconnect(_hyperion, &Hyperion::forwardJsonMessage, nullptr, nullptr);
|
||||
for (const auto& targetHost : qAsConst(_jsonTargets))
|
||||
for (const auto& targetHost : std::as_const(_jsonTargets))
|
||||
{
|
||||
Info(_log, "Stopped forwarding to JSON-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ int MessageForwarder::startFlatbufferTargets(const QJsonObject& config)
|
|||
|
||||
if (!_flatbufferTargets.isEmpty())
|
||||
{
|
||||
for (const auto& targetHost : qAsConst(_flatbufferTargets))
|
||||
for (const auto& targetHost : std::as_const(_flatbufferTargets))
|
||||
{
|
||||
Info(_log, "Forwarding now to Flatbuffer-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ void MessageForwarder::stopFlatbufferTargets()
|
|||
_messageForwarderFlatBufHelper = nullptr;
|
||||
}
|
||||
|
||||
for (const auto& targetHost : qAsConst(_flatbufferTargets))
|
||||
for (const auto& targetHost : std::as_const(_flatbufferTargets))
|
||||
{
|
||||
Info(_log, "Stopped forwarding to Flatbuffer-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ void MessageForwarder::forwardJsonMessage(const QJsonObject& message)
|
|||
if (_forwarder_enabled)
|
||||
{
|
||||
QTcpSocket client;
|
||||
for (const auto& targetHost : qAsConst(_jsonTargets))
|
||||
for (const auto& targetHost : std::as_const(_jsonTargets))
|
||||
{
|
||||
client.connectToHost(targetHost.host, targetHost.port);
|
||||
if (client.waitForConnected(CONNECT_TIMEOUT.count()))
|
||||
|
|
|
@ -9,6 +9,15 @@
|
|||
// Constants
|
||||
namespace {
|
||||
const uint16_t RESOLUTION = 255;
|
||||
|
||||
//Constants vuMeter
|
||||
const QJsonArray DEFAULT_HOTCOLOR { 255,0,0 };
|
||||
const QJsonArray DEFAULT_WARNCOLOR { 255,255,0 };
|
||||
const QJsonArray DEFAULT_SAFECOLOR { 0,255,0 };
|
||||
const int DEFAULT_WARNVALUE { 80 };
|
||||
const int DEFAULT_SAFEVALUE { 45 };
|
||||
const int DEFAULT_MULTIPLIER { 0 };
|
||||
const int DEFAULT_TOLERANCE { 20 };
|
||||
}
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
|
@ -28,12 +37,12 @@ AudioGrabber::AudioGrabber()
|
|||
, _deviceProperties()
|
||||
, _device("none")
|
||||
, _hotColor(QColorConstants::Red)
|
||||
, _warnValue(80)
|
||||
, _warnValue(DEFAULT_WARNVALUE)
|
||||
, _warnColor(QColorConstants::Yellow)
|
||||
, _safeValue(45)
|
||||
, _safeValue(DEFAULT_SAFEVALUE)
|
||||
, _safeColor(QColorConstants::Green)
|
||||
, _multiplier(0)
|
||||
, _tolerance(20)
|
||||
, _multiplier(DEFAULT_MULTIPLIER)
|
||||
, _tolerance(DEFAULT_TOLERANCE)
|
||||
, _dynamicMultiplier(INT16_MAX)
|
||||
, _started(false)
|
||||
{
|
||||
|
@ -61,18 +70,27 @@ void AudioGrabber::setDevice(const QString& device)
|
|||
|
||||
void AudioGrabber::setConfiguration(const QJsonObject& config)
|
||||
{
|
||||
QJsonArray hotColorArray = config["hotColor"].toArray(QJsonArray::fromVariantList(QList<QVariant>({ QVariant(255), QVariant(0), QVariant(0) })));
|
||||
QJsonArray warnColorArray = config["warnColor"].toArray(QJsonArray::fromVariantList(QList<QVariant>({ QVariant(255), QVariant(255), QVariant(0) })));
|
||||
QJsonArray safeColorArray = config["safeColor"].toArray(QJsonArray::fromVariantList(QList<QVariant>({ QVariant(0), QVariant(255), QVariant(0) })));
|
||||
QString audioEffect = config["audioEffect"].toString();
|
||||
QJsonObject audioEffectConfig = config[audioEffect].toObject();
|
||||
|
||||
_hotColor = QColor(hotColorArray.at(0).toInt(), hotColorArray.at(1).toInt(), hotColorArray.at(2).toInt());
|
||||
_warnColor = QColor(warnColorArray.at(0).toInt(), warnColorArray.at(1).toInt(), warnColorArray.at(2).toInt());
|
||||
_safeColor = QColor(safeColorArray.at(0).toInt(), safeColorArray.at(1).toInt(), safeColorArray.at(2).toInt());
|
||||
if (audioEffect == "vuMeter")
|
||||
{
|
||||
QJsonArray hotColorArray = audioEffectConfig.value("hotColor").toArray(DEFAULT_HOTCOLOR);
|
||||
QJsonArray warnColorArray = audioEffectConfig.value("warnColor").toArray(DEFAULT_WARNCOLOR);
|
||||
QJsonArray safeColorArray = audioEffectConfig.value("safeColor").toArray(DEFAULT_SAFECOLOR);
|
||||
|
||||
_warnValue = config["warnValue"].toInt(80);
|
||||
_safeValue = config["safeValue"].toInt(45);
|
||||
_multiplier = config["multiplier"].toDouble(0);
|
||||
_tolerance = config["tolerance"].toInt(20);
|
||||
_hotColor = QColor(hotColorArray.at(0).toInt(), hotColorArray.at(1).toInt(), hotColorArray.at(2).toInt());
|
||||
_warnColor = QColor(warnColorArray.at(0).toInt(), warnColorArray.at(1).toInt(), warnColorArray.at(2).toInt());
|
||||
_safeColor = QColor(safeColorArray.at(0).toInt(), safeColorArray.at(1).toInt(), safeColorArray.at(2).toInt());
|
||||
_warnValue = audioEffectConfig["warnValue"].toInt(DEFAULT_WARNVALUE);
|
||||
_safeValue = audioEffectConfig["safeValue"].toInt(DEFAULT_SAFEVALUE);
|
||||
_multiplier = audioEffectConfig["multiplier"].toDouble(DEFAULT_MULTIPLIER);
|
||||
_tolerance = audioEffectConfig["tolerance"].toInt(DEFAULT_MULTIPLIER);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Unknow Audio-Effect: \"%s\" configured", QSTRING_CSTR(audioEffect));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioGrabber::resetMultiplier()
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include <grabber/AudioGrabberWindows.h>
|
||||
|
||||
#include <climits>
|
||||
|
||||
#include <QImage>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
@ -61,7 +64,10 @@ bool AudioGrabberWindows::configureCaptureInterface()
|
|||
// wFormatTag, nChannels, nSamplesPerSec, mAvgBytesPerSec,
|
||||
// nBlockAlign, wBitsPerSample, cbSize
|
||||
|
||||
notificationSize = max(1024, audioFormat.nAvgBytesPerSec / 8);
|
||||
#ifdef WIN32
|
||||
#undef max
|
||||
#endif
|
||||
notificationSize = std::max(static_cast<DWORD>(1024), static_cast<DWORD>(audioFormat.nAvgBytesPerSec / 8));
|
||||
notificationSize -= notificationSize % audioFormat.nBlockAlign;
|
||||
|
||||
bufferCaptureSize = notificationSize * AUDIO_NOTIFICATION_COUNT;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
SET( CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber )
|
||||
SET( CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/audio )
|
||||
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(-DUNICODE -D_UNICODE)
|
||||
FILE ( GLOB AUDIO_GRABBER_SOURCES "${CURRENT_HEADER_DIR}/Audio*Windows.h" "${CURRENT_HEADER_DIR}/AudioGrabber.h" "${CURRENT_HEADER_DIR}/AudioWrapper.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*Windows.cpp" "${CURRENT_SOURCE_DIR}/AudioGrabber.cpp" "${CURRENT_SOURCE_DIR}/AudioWrapper.cpp")
|
||||
elseif(${CMAKE_SYSTEM} MATCHES "Linux")
|
||||
FILE ( GLOB AUDIO_GRABBER_SOURCES "${CURRENT_HEADER_DIR}/Audio*Linux.h" "${CURRENT_HEADER_DIR}/AudioGrabber.h" "${CURRENT_HEADER_DIR}/AudioWrapper.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*Linux.cpp" "${CURRENT_SOURCE_DIR}/AudioGrabber.cpp" "${CURRENT_SOURCE_DIR}/AudioWrapper.cpp")
|
||||
|
|
|
@ -103,7 +103,7 @@ bool QtGrabber::setupDisplay()
|
|||
|
||||
Info(_log, "Available Displays:");
|
||||
int index = 0;
|
||||
for (auto* screen : qAsConst(screens))
|
||||
for (auto* screen : std::as_const(screens))
|
||||
{
|
||||
const QRect geo = screen->geometry();
|
||||
Info(_log, "Display %d: Name: %s Resolution: [%dx%d], Geometry: (L,T,R,B) %d,%d,%d,%d Depth:%dbit", index, QSTRING_CSTR(screen->name()), geo.width(), geo.height(), geo.x(), geo.y(), geo.x() + geo.width(), geo.y() + geo.height(), screen->depth());
|
||||
|
|
|
@ -97,7 +97,7 @@ void CaptureCont::setSystemCaptureEnable(bool enable)
|
|||
}
|
||||
else
|
||||
{
|
||||
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, this, 0);
|
||||
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setSystemImage, this, nullptr);
|
||||
_hyperion->clear(_systemCaptPrio);
|
||||
_systemInactiveTimer->stop();
|
||||
_systemCaptName = "";
|
||||
|
@ -120,7 +120,7 @@ void CaptureCont::setV4LCaptureEnable(bool enable)
|
|||
}
|
||||
else
|
||||
{
|
||||
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setV4lImage, this, 0);
|
||||
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setV4lImage, this, nullptr);
|
||||
_hyperion->clear(_v4lCaptPrio);
|
||||
_v4lInactiveTimer->stop();
|
||||
_v4lCaptName = "";
|
||||
|
@ -143,7 +143,7 @@ void CaptureCont::setAudioCaptureEnable(bool enable)
|
|||
}
|
||||
else
|
||||
{
|
||||
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setAudioImage, this, 0);
|
||||
disconnect(GlobalSignals::getInstance(), &GlobalSignals::setAudioImage, this, nullptr);
|
||||
_hyperion->clear(_audioCaptPrio);
|
||||
_audioInactiveTimer->stop();
|
||||
_audioCaptName = "";
|
||||
|
|
|
@ -61,7 +61,7 @@ ComponentRegister::ComponentRegister(Hyperion* hyperion)
|
|||
vect << COMP_FORWARDER;
|
||||
#endif
|
||||
|
||||
for(auto e : qAsConst(vect))
|
||||
for(auto e : std::as_const(vect))
|
||||
{
|
||||
_componentStates.emplace(e, (e == COMP_ALL));
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ void GrabberWrapper::handleSourceRequest(hyperion::Components component, int hyp
|
|||
else
|
||||
GRABBER_AUDIO_CLIENTS.remove(hyperionInd);
|
||||
|
||||
if (GRABBER_AUDIO_CLIENTS.empty())
|
||||
if (GRABBER_AUDIO_CLIENTS.empty() || !getAudioGrabberState())
|
||||
stop();
|
||||
else
|
||||
start();
|
||||
|
|
|
@ -52,7 +52,7 @@ Hyperion::Hyperion(quint8 instance, bool readonlyMode)
|
|||
, _instIndex(instance)
|
||||
, _settingsManager(new SettingsManager(instance, this, readonlyMode))
|
||||
, _componentRegister(nullptr)
|
||||
, _ledString(hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(getSetting(settings::DEVICE).object())))
|
||||
, _ledString(LedString::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(getSetting(settings::DEVICE).object())))
|
||||
, _imageProcessor(nullptr)
|
||||
, _muxer(nullptr)
|
||||
, _raw2ledAdjustment(hyperion::createLedColorsAdjustment(static_cast<int>(_ledString.leds().size()), getSetting(settings::COLOR).object()))
|
||||
|
@ -255,7 +255,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
|
|||
#endif
|
||||
|
||||
// ledstring, img processor, muxer, ledGridSize (effect-engine image based effects), _ledBuffer and ByteOrder of ledstring
|
||||
_ledString = hyperion::createLedString(leds, hyperion::createColorOrder(getSetting(settings::DEVICE).object()));
|
||||
_ledString = LedString::createLedString(leds, hyperion::createColorOrder(getSetting(settings::DEVICE).object()));
|
||||
_imageProcessor->setLedString(_ledString);
|
||||
_muxer->updateLedColorsLength(static_cast<int>(_ledString.leds().size()));
|
||||
_ledGridSize = hyperion::getLedLayoutGridSize(leds);
|
||||
|
@ -291,7 +291,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
|
|||
// force ledString update, if device ByteOrder changed
|
||||
if(_ledDeviceWrapper->getColorOrder() != dev["colorOrder"].toString("rgb"))
|
||||
{
|
||||
_ledString = hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(dev));
|
||||
_ledString = LedString::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(dev));
|
||||
_imageProcessor->setLedString(_ledString);
|
||||
|
||||
_ledStringColorOrder.clear();
|
||||
|
@ -671,6 +671,18 @@ void Hyperion::update()
|
|||
else
|
||||
{
|
||||
_ledBuffer = priorityInfo.ledColors;
|
||||
|
||||
if (_ledString.hasBlackListedLeds())
|
||||
{
|
||||
for (int id : _ledString.blacklistedLedIds())
|
||||
{
|
||||
if (id > _ledBuffer.size()-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
_ledBuffer.at(id) = ColorRgb::BLACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit rawLedColors before transform
|
||||
|
|
|
@ -1,16 +1,92 @@
|
|||
// STL includes
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// hyperion includes
|
||||
#include <hyperion/LedString.h>
|
||||
|
||||
// QT includes
|
||||
#include <QJsonObject>
|
||||
|
||||
std::vector<Led>& LedString::leds()
|
||||
{
|
||||
return mLeds;
|
||||
return _leds;
|
||||
}
|
||||
|
||||
const std::vector<Led>& LedString::leds() const
|
||||
{
|
||||
return mLeds;
|
||||
return _leds;
|
||||
}
|
||||
|
||||
std::vector<int>& LedString::blacklistedLedIds()
|
||||
{
|
||||
return _blacklistedLedIds;
|
||||
}
|
||||
|
||||
const std::vector<int>& LedString::blacklistedLedIds() const
|
||||
{
|
||||
return _blacklistedLedIds;
|
||||
}
|
||||
|
||||
bool LedString::hasBlackListedLeds()
|
||||
{
|
||||
|
||||
if (_blacklistedLedIds.size() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the 'led-string' with the integration area definition per led and the color
|
||||
* ordering of the RGB channels
|
||||
* @param ledsConfig The configuration of the led areas
|
||||
* @param deviceOrder The default RGB channel ordering
|
||||
* @return The constructed ledstring
|
||||
*/
|
||||
LedString LedString::createLedString(const QJsonArray& ledConfigArray, const ColorOrder deviceOrder)
|
||||
{
|
||||
LedString ledString;
|
||||
const QString deviceOrderStr = colorOrderToString(deviceOrder);
|
||||
|
||||
for (signed i = 0; i < ledConfigArray.size(); ++i)
|
||||
{
|
||||
const QJsonObject& ledConfig = ledConfigArray[i].toObject();
|
||||
Led led;
|
||||
|
||||
led.minX_frac = qMax(0.0, qMin(1.0, ledConfig["hmin"].toDouble()));
|
||||
led.maxX_frac = qMax(0.0, qMin(1.0, ledConfig["hmax"].toDouble()));
|
||||
led.minY_frac = qMax(0.0, qMin(1.0, ledConfig["vmin"].toDouble()));
|
||||
led.maxY_frac = qMax(0.0, qMin(1.0, ledConfig["vmax"].toDouble()));
|
||||
// Fix if the user swapped min and max
|
||||
if (led.minX_frac > led.maxX_frac)
|
||||
{
|
||||
std::swap(led.minX_frac, led.maxX_frac);
|
||||
}
|
||||
if (led.minY_frac > led.maxY_frac)
|
||||
{
|
||||
std::swap(led.minY_frac, led.maxY_frac);
|
||||
}
|
||||
|
||||
// Get the order of the rgb channels for this led (default is device order)
|
||||
led.colorOrder = stringToColorOrder(ledConfig["colorOrder"].toString(deviceOrderStr));
|
||||
|
||||
led.isBlacklisted = false;
|
||||
if (led.minX_frac < std::numeric_limits<double>::epsilon() &&
|
||||
led.maxX_frac < std::numeric_limits<double>::epsilon() &&
|
||||
led.minY_frac < std::numeric_limits<double>::epsilon() &&
|
||||
led.maxY_frac < std::numeric_limits<double>::epsilon()
|
||||
)
|
||||
{
|
||||
led.isBlacklisted = true;
|
||||
ledString.blacklistedLedIds().push_back(i);
|
||||
}
|
||||
ledString.leds().push_back(led);
|
||||
}
|
||||
return ledString;
|
||||
}
|
||||
|
|
|
@ -58,9 +58,9 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
|
|||
}
|
||||
|
||||
// transform json to string lists
|
||||
QStringList keyList = defaultConfig.keys();
|
||||
const QStringList keyList = defaultConfig.keys();
|
||||
QStringList defValueList;
|
||||
for (const auto& key : qAsConst(keyList))
|
||||
for (const auto& key : keyList)
|
||||
{
|
||||
if (defaultConfig[key].isObject())
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
|
|||
}
|
||||
|
||||
// fill database with default data if required
|
||||
for (const auto& key : qAsConst(keyList))
|
||||
for (const auto& key : keyList)
|
||||
{
|
||||
QString val = defValueList.takeFirst();
|
||||
// prevent overwrite
|
||||
|
@ -86,7 +86,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
|
|||
// need to validate all data in database construct the entire data object
|
||||
// TODO refactor schemaChecker to accept QJsonArray in validate(); QJsonDocument container? To validate them per entry...
|
||||
QJsonObject dbConfig;
|
||||
for (const auto& key : qAsConst(keyList))
|
||||
for (const auto& key : keyList)
|
||||
{
|
||||
QJsonDocument doc = _sTable->getSettingsRecord(key);
|
||||
if (doc.isArray())
|
||||
|
@ -242,9 +242,9 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
|
|||
_qconfig = config;
|
||||
|
||||
// extract keys and data
|
||||
QStringList keyList = config.keys();
|
||||
const QStringList keyList = config.keys();
|
||||
QStringList newValueList;
|
||||
for (const auto& key : qAsConst(keyList))
|
||||
for (const auto& key : keyList)
|
||||
{
|
||||
if (config[key].isObject())
|
||||
{
|
||||
|
@ -258,7 +258,7 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
|
|||
|
||||
bool rc = true;
|
||||
// compare database data with new data to emit/save changes accordingly
|
||||
for (const auto& key : qAsConst(keyList))
|
||||
for (const auto& key : keyList)
|
||||
{
|
||||
QString data = newValueList.takeFirst();
|
||||
if (_sTable->getSettingsRecordString(key) != data)
|
||||
|
@ -269,7 +269,15 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
|
|||
}
|
||||
else
|
||||
{
|
||||
emit settingsChanged(settings::stringToType(key), QJsonDocument::fromJson(data.toLocal8Bit()));
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(data.toUtf8(), &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
Error(_log, "Error parsing JSON: %s", QSTRING_CSTR(error.errorString()));
|
||||
rc = false;
|
||||
}
|
||||
else {
|
||||
emit settingsChanged(settings::stringToType(key), jsonDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -618,10 +626,10 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
|
|||
QJsonArray json;
|
||||
if (newForwarderConfig.contains("json"))
|
||||
{
|
||||
QJsonArray oldJson = newForwarderConfig["json"].toArray();
|
||||
const QJsonArray oldJson = newForwarderConfig["json"].toArray();
|
||||
QJsonObject newJsonConfig;
|
||||
|
||||
for (const QJsonValue& value : qAsConst(oldJson))
|
||||
for (const QJsonValue& value : oldJson)
|
||||
{
|
||||
if (value.isString())
|
||||
{
|
||||
|
@ -661,10 +669,10 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
|
|||
QJsonArray flatbuffer;
|
||||
if (newForwarderConfig.contains("flat"))
|
||||
{
|
||||
QJsonArray oldFlatbuffer = newForwarderConfig["flat"].toArray();
|
||||
const QJsonArray oldFlatbuffer = newForwarderConfig["flat"].toArray();
|
||||
QJsonObject newFlattbufferConfig;
|
||||
|
||||
for (const QJsonValue& value : qAsConst(oldFlatbuffer))
|
||||
for (const QJsonValue& value : oldFlatbuffer)
|
||||
{
|
||||
if (value.isString())
|
||||
{
|
||||
|
@ -715,6 +723,7 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
|
|||
}
|
||||
|
||||
//Migration steps for versions <= 2.0.13
|
||||
_previousVersion = targetVersion;
|
||||
targetVersion.setVersion("2.0.13");
|
||||
if (_previousVersion <= targetVersion)
|
||||
{
|
||||
|
@ -766,6 +775,60 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Migration steps for versions <= 2.0.16
|
||||
_previousVersion = targetVersion;
|
||||
targetVersion.setVersion("2.0.16");
|
||||
if (_previousVersion <= targetVersion)
|
||||
{
|
||||
Info(_log, "Instance [%u]: Migrate from version [%s] to version [%s] or later", _instance, _previousVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
||||
|
||||
// Have Hostname/IP-address separate from port for LED-Devices
|
||||
if (config.contains("device"))
|
||||
{
|
||||
QJsonObject newDeviceConfig = config["device"].toObject();
|
||||
|
||||
if (newDeviceConfig.contains("type"))
|
||||
{
|
||||
QString type = newDeviceConfig["type"].toString();
|
||||
if ( type == "philipshue")
|
||||
{
|
||||
if (newDeviceConfig.contains("groupId"))
|
||||
{
|
||||
if (newDeviceConfig["groupId"].isDouble())
|
||||
{
|
||||
int groupID = newDeviceConfig["groupId"].toInt();
|
||||
newDeviceConfig["groupId"] = QString::number(groupID);
|
||||
migrated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (newDeviceConfig.contains("lightIds"))
|
||||
{
|
||||
QJsonArray lightIds = newDeviceConfig.value( "lightIds").toArray();
|
||||
// Iterate through the JSON array and update integer values to strings
|
||||
for (int i = 0; i < lightIds.size(); ++i) {
|
||||
QJsonValue value = lightIds.at(i);
|
||||
if (value.isDouble())
|
||||
{
|
||||
int lightId = value.toInt();
|
||||
lightIds.replace(i, QString::number(lightId));
|
||||
migrated = true;
|
||||
}
|
||||
}
|
||||
newDeviceConfig["lightIds"] = lightIds;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (migrated)
|
||||
{
|
||||
config["device"] = newDeviceConfig;
|
||||
Debug(_log, "LED-Device records migrated");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return migrated;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"port" :
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "edt_conf_general_port_title",
|
||||
"title" : "edt_conf_webc_port_title",
|
||||
"minimum" : 80,
|
||||
"maximum" : 65535,
|
||||
"default" : 8090,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,31 +16,6 @@
|
|||
#include "ProviderRestApi.h"
|
||||
#include "ProviderUdpSSL.h"
|
||||
|
||||
//Streaming message header and payload definition
|
||||
const uint8_t HEADER[] =
|
||||
{
|
||||
'H', 'u', 'e', 'S', 't', 'r', 'e', 'a', 'm', //protocol
|
||||
0x01, 0x00, //version 1.0
|
||||
0x01, //sequence number 1
|
||||
0x00, 0x00, //Reserved write 0’s
|
||||
0x01, //xy Brightness
|
||||
0x00, // Reserved, write 0’s
|
||||
};
|
||||
|
||||
const uint8_t PAYLOAD_PER_LIGHT[] =
|
||||
{
|
||||
0x01, 0x00, 0x06, //light ID
|
||||
//color: 16 bpc
|
||||
0xff, 0xff,
|
||||
0xff, 0xff,
|
||||
0xff, 0xff,
|
||||
/*
|
||||
(message.R >> 8) & 0xff, message.R & 0xff,
|
||||
(message.G >> 8) & 0xff, message.G & 0xff,
|
||||
(message.B >> 8) & 0xff, message.B & 0xff
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* A XY color point in the color space of the hue system without brightness.
|
||||
*/
|
||||
|
@ -145,12 +120,18 @@ public:
|
|||
/// Constructs the light.
|
||||
///
|
||||
/// @param log the logger
|
||||
/// @param bridge the bridge
|
||||
/// @param useApiV2 make use of Hue API version 2
|
||||
/// @param id the light id
|
||||
/// @param lightAttributes the light's attributes as provied by the Hue Bridge
|
||||
/// @param onBlackTimeToPowerOff Timeframe of Black output that triggers powering off the light
|
||||
/// @param onBlackTimeToPowerOn Timeframe of non Black output that triggers powering on the light
|
||||
///
|
||||
PhilipsHueLight(Logger* log, int id, QJsonObject values, int ledidx,
|
||||
int onBlackTimeToPowerOff,
|
||||
int onBlackTimeToPowerOn);
|
||||
PhilipsHueLight(Logger* log, bool useApiV2, const QString& id, const QJsonObject& lightAttributes,
|
||||
int onBlackTimeToPowerOff,
|
||||
int onBlackTimeToPowerOn);
|
||||
|
||||
void setDeviceDetails(const QJsonObject& details);
|
||||
void setEntertainmentSrvDetails(const QJsonObject& details);
|
||||
|
||||
///
|
||||
/// @param on
|
||||
|
@ -167,7 +148,14 @@ public:
|
|||
///
|
||||
void setColor(const CiColor& color);
|
||||
|
||||
int getId() const;
|
||||
QString getId() const;
|
||||
QString getdeviceId() const;
|
||||
QString getProduct() const;
|
||||
QString getModel() const;
|
||||
QString getName() const;
|
||||
QString getArcheType() const;
|
||||
|
||||
int getMaxSegments() const;
|
||||
|
||||
bool getOnOffState() const;
|
||||
int getTransitionTime() const;
|
||||
|
@ -179,7 +167,7 @@ public:
|
|||
CiColorTriangle getColorSpace() const;
|
||||
|
||||
void saveOriginalState(const QJsonObject& values);
|
||||
QString getOriginalState() const;
|
||||
QJsonObject getOriginalState() const;
|
||||
|
||||
bool isBusy();
|
||||
bool isBlack(bool isBlack);
|
||||
|
@ -189,24 +177,30 @@ public:
|
|||
private:
|
||||
|
||||
Logger* _log;
|
||||
/// light id
|
||||
int _id;
|
||||
int _ledidx;
|
||||
bool _useApiV2;
|
||||
|
||||
QString _id;
|
||||
QString _deviceId;
|
||||
QString _product;
|
||||
QString _model;
|
||||
QString _name;
|
||||
QString _archeType;
|
||||
QString _gamutType;
|
||||
|
||||
int _maxSegments;
|
||||
|
||||
bool _on;
|
||||
int _transitionTime;
|
||||
CiColor _color;
|
||||
bool _hasColor;
|
||||
/// darkes blue color in hue lamp GAMUT = black
|
||||
CiColor _colorBlack;
|
||||
/// The model id of the hue lamp which is used to determine the color space.
|
||||
QString _modelId;
|
||||
QString _lightname;
|
||||
CiColorTriangle _colorSpace;
|
||||
|
||||
/// The json string of the original state.
|
||||
QJsonObject _originalStateJSON;
|
||||
|
||||
QString _originalState;
|
||||
QJsonObject _originalState;
|
||||
CiColor _originalColor;
|
||||
qint64 _lastSendColorTime;
|
||||
qint64 _lastBlackTime;
|
||||
|
@ -242,23 +236,40 @@ public:
|
|||
QJsonDocument get(const QString& route);
|
||||
|
||||
///
|
||||
/// @brief Perform a REST-API POST
|
||||
/// @brief Perform a REST-API GET
|
||||
///
|
||||
/// @param route the route of the POST request.
|
||||
/// @param content the content of the POST request.
|
||||
/// @param routeElements the route's elements of the GET request.
|
||||
///
|
||||
QJsonDocument put(const QString& route, const QString& content, bool supressError = false);
|
||||
/// @return the content of the GET request.
|
||||
///
|
||||
QJsonDocument get(const QStringList& routeElements);
|
||||
|
||||
QJsonDocument getLightState( int lightId);
|
||||
void setLightState( int lightId = 0, const QString &state = "");
|
||||
///
|
||||
/// @brief Perform a REST-API PUT
|
||||
///
|
||||
/// @param routeElements the route's elements of the PUT request.
|
||||
/// @param content the content of the PUT request.
|
||||
/// @param supressError Treat an error as a warning
|
||||
///
|
||||
/// @return the content of the PUT request.
|
||||
///
|
||||
QJsonDocument put(const QStringList& routeElements, const QJsonObject& content, bool supressError = false);
|
||||
|
||||
QMap<int,QJsonObject> getLightMap() const;
|
||||
QJsonDocument retrieveBridgeDetails();
|
||||
QJsonObject getDeviceDetails(const QString& deviceId);
|
||||
QJsonObject getEntertainmentSrvDetails(const QString& deviceId);
|
||||
|
||||
QMap<int,QJsonObject> getGroupMap() const;
|
||||
QJsonObject getLightDetails(const QString& lightId);
|
||||
QJsonDocument setLightState(const QString& lightId, const QJsonObject& state);
|
||||
|
||||
QString getGroupName(int groupId = 0) const;
|
||||
QMap<QString,QJsonObject> getDevicesMap() const;
|
||||
QMap<QString,QJsonObject> getLightMap() const;
|
||||
QMap<QString,QJsonObject> getGroupMap() const;
|
||||
QMap<QString,QJsonObject> getEntertainmentMap() const;
|
||||
|
||||
QJsonArray getGroupLights(int groupId = 0) const;
|
||||
QString getGroupName(const QString& groupId) const;
|
||||
QStringList getGroupLights(const QString& groupId) const;
|
||||
int getGroupChannelsCount(const QString& groupId) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -289,7 +300,7 @@ protected:
|
|||
///
|
||||
/// @param[in] response from Hue-Bridge in JSON-format
|
||||
/// @param[in] suppressError Treat an error as a warning
|
||||
///
|
||||
///
|
||||
/// return True, Hue Bridge reports error
|
||||
///
|
||||
bool checkApiError(const QJsonDocument& response, bool supressError = false);
|
||||
|
@ -338,23 +349,41 @@ protected:
|
|||
///
|
||||
QJsonObject addAuthorization(const QJsonObject& params) override;
|
||||
|
||||
bool isApiEntertainmentReady(const QString& apiVersion);
|
||||
bool isAPIv2Ready (int swVersion);
|
||||
|
||||
int getFirmwareVerion() { return _deviceFirmwareVersion; }
|
||||
void setBridgeDetails( const QJsonDocument &doc, bool isLogging = false );
|
||||
|
||||
void setBaseApiEnvironment(bool apiV2 = true, const QString& path = "");
|
||||
|
||||
QJsonDocument getGroupDetails( const QString& groupId );
|
||||
QJsonDocument setGroupState( const QString& groupId, bool state);
|
||||
|
||||
bool isStreamOwner(const QString &streamOwner) const;
|
||||
|
||||
bool initDevicesMap();
|
||||
bool initLightsMap();
|
||||
bool initGroupsMap();
|
||||
bool initEntertainmentSrvsMap();
|
||||
|
||||
void log(const char* msg, const char* type, ...) const;
|
||||
|
||||
bool configureSsl();
|
||||
const int * getCiphersuites() const override;
|
||||
|
||||
///REST-API wrapper
|
||||
ProviderRestApi* _restApi;
|
||||
int _apiPort;
|
||||
/// User name for the API ("newdeveloper")
|
||||
QString _authToken;
|
||||
QString _applicationID;
|
||||
|
||||
bool _useHueEntertainmentAPI;
|
||||
bool _useEntertainmentAPI;
|
||||
bool _useApiV2;
|
||||
bool _isAPIv2Ready;
|
||||
|
||||
QJsonDocument getGroupState( int groupId );
|
||||
QJsonDocument setGroupState( int groupId, bool state);
|
||||
|
||||
bool isStreamOwner(const QString &streamOwner) const;
|
||||
bool initMaps();
|
||||
|
||||
void log(const char* msg, const char* type, ...) const;
|
||||
|
||||
const int * getCiphersuites() const override;
|
||||
bool _isDiyHue;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -364,16 +393,25 @@ private:
|
|||
///
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
QJsonArray discover();
|
||||
QJsonArray discoverSsdp();
|
||||
|
||||
QJsonDocument getAllBridgeInfos();
|
||||
void setBridgeConfig( const QJsonDocument &doc );
|
||||
QJsonDocument retrieveDeviceDetails(const QString& deviceId = "");
|
||||
QJsonDocument retrieveLightDetails(const QString& lightId = "");
|
||||
QJsonDocument retrieveGroupDetails(const QString& groupId = "");
|
||||
QJsonDocument retrieveEntertainmentSrvDetails(const QString& deviceId = "");
|
||||
|
||||
bool retrieveApplicationId();
|
||||
|
||||
void setDevicesMap( const QJsonDocument &doc );
|
||||
void setLightsMap( const QJsonDocument &doc );
|
||||
void setGroupMap( const QJsonDocument &doc );
|
||||
void setEntertainmentSrvMap( const QJsonDocument &doc );
|
||||
|
||||
//Philips Hue Bridge details
|
||||
QString _deviceName;
|
||||
QString _deviceBridgeId;
|
||||
QString _deviceModel;
|
||||
QString _deviceFirmwareVersion;
|
||||
int _deviceFirmwareVersion;
|
||||
QString _deviceAPIVersion;
|
||||
|
||||
uint _api_major;
|
||||
|
@ -382,8 +420,12 @@ private:
|
|||
|
||||
bool _isHueEntertainmentReady;
|
||||
|
||||
QMap<int,QJsonObject> _lightsMap;
|
||||
QMap<int,QJsonObject> _groupsMap;
|
||||
QMap<QString,QJsonObject> _devicesMap;
|
||||
QMap<QString,QJsonObject> _lightsMap;
|
||||
QMap<QString,QJsonObject> _groupsMap;
|
||||
QMap<QString,QJsonObject> _entertainmentMap;
|
||||
|
||||
int _lightsCount;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -440,7 +482,7 @@ public:
|
|||
///
|
||||
/// @return Number of device's LEDs
|
||||
///
|
||||
unsigned int getLightsCount() const { return _lightsCount; }
|
||||
int getLightsCount() const { return _lightsCount; }
|
||||
|
||||
void setOnOffState(PhilipsHueLight& light, bool on, bool force = false);
|
||||
void setTransitionTime(PhilipsHueLight& light);
|
||||
|
@ -547,18 +589,18 @@ private:
|
|||
|
||||
bool setLights();
|
||||
|
||||
/// creates new PhilipsHueLight(s) based on user lightid with bridge feedback
|
||||
/// creates new PhilipsHueLight(s) based on user lightId with bridge feedback
|
||||
///
|
||||
/// @param map Map of lightid/value pairs of bridge
|
||||
/// @param map Map of lightId/value pairs of bridge
|
||||
///
|
||||
bool updateLights(const QMap<int, QJsonObject> &map);
|
||||
bool updateLights(const QMap<QString, QJsonObject> &map);
|
||||
|
||||
///
|
||||
/// @brief Set the number of LEDs supported by the device.
|
||||
///
|
||||
/// @rparam[in] Number of device's LEDs
|
||||
//
|
||||
void setLightsCount( unsigned int lightsCount);
|
||||
void setLightsCount(int lightsCount);
|
||||
|
||||
bool openStream();
|
||||
bool getStreamGroupState();
|
||||
|
@ -566,10 +608,8 @@ private:
|
|||
bool startStream();
|
||||
bool stopStream();
|
||||
|
||||
void writeStream(bool flush = false);
|
||||
int writeSingleLights(const std::vector<ColorRgb>& ledValues);
|
||||
|
||||
QByteArray prepareStreamData() const;
|
||||
int writeStreamData(const std::vector<ColorRgb>& ledValues, bool flush = false);
|
||||
|
||||
///
|
||||
bool _switchOffOnBlack;
|
||||
|
@ -582,12 +622,15 @@ private:
|
|||
bool _isInitLeds;
|
||||
|
||||
/// Array of the light ids.
|
||||
std::vector<int> _lightIds;
|
||||
QStringList _lightIds;
|
||||
/// Array to save the lamps.
|
||||
std::vector<PhilipsHueLight> _lights;
|
||||
|
||||
int _lightsCount;
|
||||
int _groupId;
|
||||
int _channelsCount;
|
||||
QString _groupId;
|
||||
QString _groupName;
|
||||
QString _streamOwner;
|
||||
|
||||
int _blackLightsTimeout;
|
||||
double _blackLevel;
|
||||
|
@ -595,15 +638,5 @@ private:
|
|||
int _onBlackTimeToPowerOn;
|
||||
bool _candyGamma;
|
||||
|
||||
// TODO: Check what is the correct class
|
||||
uint32_t _handshake_timeout_min;
|
||||
uint32_t _handshake_timeout_max;
|
||||
bool _stopConnection;
|
||||
|
||||
QString _groupName;
|
||||
QString _streamOwner;
|
||||
|
||||
qint64 _lastConfirm;
|
||||
int _lastId;
|
||||
bool _groupStreamState;
|
||||
};
|
||||
|
|
|
@ -301,7 +301,7 @@ bool LedDeviceWled::isReadyForSegmentStreaming(semver::version& version) const
|
|||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Version provided to test for streaming readiness is not valid ");
|
||||
Error(_log, "Version provided to test for segment streaming readiness is not valid ");
|
||||
}
|
||||
return isReady;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ bool LedDeviceWled::isReadyForDDPStreaming(semver::version& version) const
|
|||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Version provided to test for streaming readiness is not valid ");
|
||||
Error(_log, "Version provided to test for DDP streaming readiness is not valid ");
|
||||
}
|
||||
return isReady;
|
||||
}
|
||||
|
@ -352,12 +352,12 @@ bool LedDeviceWled::powerOn()
|
|||
}
|
||||
else
|
||||
{
|
||||
QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray();
|
||||
const QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray();
|
||||
|
||||
bool isStreamSegmentIdFound { false };
|
||||
|
||||
QJsonArray segments;
|
||||
for (const auto& segmentItem : qAsConst(propertiesSegments))
|
||||
for (const auto& segmentItem : propertiesSegments)
|
||||
{
|
||||
QJsonObject segmentObj = segmentItem.toObject();
|
||||
|
||||
|
@ -505,9 +505,9 @@ bool LedDeviceWled::restoreState()
|
|||
|
||||
if (_isStreamToSegment)
|
||||
{
|
||||
QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray();
|
||||
const QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray();
|
||||
QJsonArray segments;
|
||||
for (const auto& segmentItem : qAsConst(propertiesSegments))
|
||||
for (const auto& segmentItem : propertiesSegments)
|
||||
{
|
||||
QJsonObject segmentObj = segmentItem.toObject();
|
||||
|
||||
|
|
|
@ -2,11 +2,18 @@
|
|||
#include "ProviderRestApi.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QObject>
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkReply>
|
||||
#include <QByteArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include <QFile>
|
||||
|
||||
#include <QSslSocket>
|
||||
|
||||
//std includes
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
@ -30,12 +37,12 @@ ProviderRestApi::ProviderRestApi(const QString& scheme, const QString& host, int
|
|||
: _log(Logger::getInstance("LEDDEVICE"))
|
||||
, _networkManager(nullptr)
|
||||
, _requestTimeout(DEFAULT_REST_TIMEOUT)
|
||||
,_isSeflSignedCertificateAccpeted(false)
|
||||
{
|
||||
_networkManager = new QNetworkAccessManager();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
_networkManager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
#endif
|
||||
|
||||
_apiUrl.setScheme(scheme);
|
||||
_apiUrl.setHost(host);
|
||||
_apiUrl.setPort(port);
|
||||
|
@ -46,7 +53,7 @@ ProviderRestApi::ProviderRestApi(const QString& scheme, const QString& host, int
|
|||
: ProviderRestApi(scheme, host, port, "") {}
|
||||
|
||||
ProviderRestApi::ProviderRestApi(const QString& host, int port, const QString& basePath)
|
||||
: ProviderRestApi("http", host, port, basePath) {}
|
||||
: ProviderRestApi((port == 443) ? "https" : "http", host, port, basePath) {}
|
||||
|
||||
ProviderRestApi::ProviderRestApi(const QString& host, int port)
|
||||
: ProviderRestApi(host, port, "") {}
|
||||
|
@ -59,18 +66,33 @@ ProviderRestApi::~ProviderRestApi()
|
|||
delete _networkManager;
|
||||
}
|
||||
|
||||
void ProviderRestApi::setScheme(const QString& scheme)
|
||||
{
|
||||
_apiUrl.setScheme(scheme);
|
||||
}
|
||||
|
||||
void ProviderRestApi::setUrl(const QUrl& url)
|
||||
{
|
||||
_apiUrl = url;
|
||||
_basePath = url.path();
|
||||
}
|
||||
|
||||
void ProviderRestApi::setBasePath(const QStringList& pathElements)
|
||||
{
|
||||
setBasePath(pathElements.join(ONE_SLASH));
|
||||
}
|
||||
|
||||
void ProviderRestApi::setBasePath(const QString& basePath)
|
||||
{
|
||||
_basePath.clear();
|
||||
appendPath(_basePath, basePath);
|
||||
}
|
||||
|
||||
void ProviderRestApi::clearBasePath()
|
||||
{
|
||||
_basePath.clear();
|
||||
}
|
||||
|
||||
void ProviderRestApi::setPath(const QStringList& pathElements)
|
||||
{
|
||||
_path.clear();
|
||||
|
@ -83,6 +105,11 @@ void ProviderRestApi::setPath(const QString& path)
|
|||
appendPath(_path, path);
|
||||
}
|
||||
|
||||
void ProviderRestApi::clearPath()
|
||||
{
|
||||
_path.clear();
|
||||
}
|
||||
|
||||
void ProviderRestApi::appendPath(const QString& path)
|
||||
{
|
||||
appendPath(_path, path);
|
||||
|
@ -204,6 +231,7 @@ httpResponse ProviderRestApi::executeOperation(QNetworkAccessManager::Operation
|
|||
QDateTime start = QDateTime::currentDateTime();
|
||||
QString opCode;
|
||||
QNetworkReply* reply;
|
||||
|
||||
switch (operation) {
|
||||
case QNetworkAccessManager::GetOperation:
|
||||
opCode = "GET";
|
||||
|
@ -255,11 +283,11 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
|
|||
HttpStatusCode httpStatusCode = static_cast<HttpStatusCode>(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
|
||||
response.setHttpStatusCode(httpStatusCode);
|
||||
response.setNetworkReplyError(reply->error());
|
||||
response.setHeaders(reply->rawHeaderPairs());
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
QByteArray replyData = reply->readAll();
|
||||
|
||||
if (!replyData.isEmpty())
|
||||
{
|
||||
QJsonParseError error;
|
||||
|
@ -284,40 +312,41 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
|
|||
else
|
||||
{
|
||||
QString errorReason;
|
||||
if (httpStatusCode > 0) {
|
||||
QString httpReason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||||
QString advise;
|
||||
switch ( httpStatusCode ) {
|
||||
case HttpStatusCode::BadRequest:
|
||||
advise = "Check Request Body";
|
||||
break;
|
||||
case HttpStatusCode::UnAuthorized:
|
||||
advise = "Check Authentication Token (API Key)";
|
||||
break;
|
||||
case HttpStatusCode::Forbidden:
|
||||
advise = "No permission to access the given resource";
|
||||
break;
|
||||
case HttpStatusCode::NotFound:
|
||||
advise = "Check Resource given";
|
||||
break;
|
||||
default:
|
||||
advise = httpReason;
|
||||
break;
|
||||
}
|
||||
errorReason = QString ("[%3 %4] - %5").arg(httpStatusCode).arg(httpReason, advise);
|
||||
if (reply->error() == QNetworkReply::OperationCanceledError)
|
||||
{
|
||||
errorReason = "Network request timeout error";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reply->error() == QNetworkReply::OperationCanceledError)
|
||||
{
|
||||
errorReason = "Network request timeout error";
|
||||
qDebug() << "httpStatusCode: "<< httpStatusCode;
|
||||
if (httpStatusCode > 0) {
|
||||
QString httpReason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||||
QString advise;
|
||||
switch ( httpStatusCode ) {
|
||||
case HttpStatusCode::BadRequest:
|
||||
advise = "Check Request Body";
|
||||
break;
|
||||
case HttpStatusCode::UnAuthorized:
|
||||
advise = "Check Authentication Token (API Key)";
|
||||
break;
|
||||
case HttpStatusCode::Forbidden:
|
||||
advise = "No permission to access the given resource";
|
||||
break;
|
||||
case HttpStatusCode::NotFound:
|
||||
advise = "Check Resource given";
|
||||
break;
|
||||
default:
|
||||
advise = httpReason;
|
||||
break;
|
||||
}
|
||||
errorReason = QString ("[%3 %4] - %5").arg(httpStatusCode).arg(httpReason, advise);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorReason = reply->errorString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
response.setError(true);
|
||||
response.setErrorReason(errorReason);
|
||||
}
|
||||
|
@ -344,3 +373,121 @@ void ProviderRestApi::setHeader(const QByteArray &headerName, const QByteArray &
|
|||
{
|
||||
_networkRequestHeaders.setRawHeader(headerName, headerValue);
|
||||
}
|
||||
|
||||
void httpResponse::setHeaders(const QList<QNetworkReply::RawHeaderPair>& pairs)
|
||||
{
|
||||
_responseHeaders.clear();
|
||||
for (const auto &item: pairs)
|
||||
{
|
||||
_responseHeaders[item.first] = item.second;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray httpResponse::getHeader(const QByteArray header) const
|
||||
{
|
||||
return _responseHeaders.value(header);
|
||||
}
|
||||
|
||||
bool ProviderRestApi::setCaCertificate(const QString& caFileName)
|
||||
{
|
||||
bool rc {false};
|
||||
/// Add our own CA to the default SSL configuration
|
||||
QSslConfiguration configuration = QSslConfiguration::defaultConfiguration();
|
||||
|
||||
QFile caFile (caFileName);
|
||||
if (!caFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
Error(_log,"Unable to open CA-Certificate file: %s", QSTRING_CSTR(caFileName));
|
||||
return false;
|
||||
}
|
||||
|
||||
QSslCertificate cert (&caFile);
|
||||
caFile.close();
|
||||
|
||||
QList<QSslCertificate> allowedCAs;
|
||||
allowedCAs << cert;
|
||||
configuration.setCaCertificates(allowedCAs);
|
||||
|
||||
QSslConfiguration::setDefaultConfiguration(configuration);
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
if (QSslSocket::supportsSsl())
|
||||
{
|
||||
QObject::connect( _networkManager, &QNetworkAccessManager::sslErrors, this, &ProviderRestApi::onSslErrors, Qt::UniqueConnection );
|
||||
_networkManager->connectToHostEncrypted(_apiUrl.host(), _apiUrl.port(), configuration);
|
||||
rc = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ProviderRestApi::acceptSelfSignedCertificates(bool isAccepted)
|
||||
{
|
||||
_isSeflSignedCertificateAccpeted = isAccepted;
|
||||
}
|
||||
|
||||
void ProviderRestApi::setAlternateServerIdentity(const QString& serverIdentity)
|
||||
{
|
||||
_serverIdentity = serverIdentity;
|
||||
}
|
||||
|
||||
QString ProviderRestApi::getAlternateServerIdentity() const
|
||||
{
|
||||
return _serverIdentity;
|
||||
}
|
||||
|
||||
bool ProviderRestApi::checkServerIdentity(const QSslConfiguration& sslConfig) const
|
||||
{
|
||||
bool isServerIdentified {false};
|
||||
|
||||
// Perform common name validation
|
||||
QSslCertificate serverCertificate = sslConfig.peerCertificate();
|
||||
QStringList commonName = serverCertificate.subjectInfo(QSslCertificate::CommonName);
|
||||
if ( commonName.contains(getAlternateServerIdentity(), Qt::CaseInsensitive) )
|
||||
{
|
||||
isServerIdentified = true;
|
||||
}
|
||||
|
||||
return isServerIdentified;
|
||||
}
|
||||
|
||||
void ProviderRestApi::onSslErrors(QNetworkReply* reply, const QList<QSslError>& errors)
|
||||
{
|
||||
int ignoredErrorCount {0};
|
||||
for (const QSslError &error : errors)
|
||||
{
|
||||
bool ignoreSslError{false};
|
||||
|
||||
switch (error.error()) {
|
||||
case QSslError::HostNameMismatch :
|
||||
if (checkServerIdentity(reply->sslConfiguration()) )
|
||||
{
|
||||
ignoreSslError = true;
|
||||
}
|
||||
break;
|
||||
case QSslError::SelfSignedCertificate :
|
||||
if (_isSeflSignedCertificateAccpeted)
|
||||
{
|
||||
ignoreSslError = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ignoreSslError)
|
||||
{
|
||||
++ignoredErrorCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug (_log,"SSL Error occured: [%d] %s ",error.error(), QSTRING_CSTR(error.errorString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoredErrorCount == errors.size())
|
||||
{
|
||||
reply->ignoreSslErrors();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,13 @@
|
|||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <QFile>
|
||||
#include <QBasicTimer>
|
||||
#include <QTimerEvent>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
constexpr std::chrono::milliseconds DEFAULT_REST_TIMEOUT{ 1000 };
|
||||
constexpr std::chrono::milliseconds DEFAULT_REST_TIMEOUT{ 2000 };
|
||||
|
||||
//Set QNetworkReply timeout without external timer
|
||||
//https://stackoverflow.com/questions/37444539/how-to-set-qnetworkreply-timeout-without-external-timer
|
||||
|
@ -28,7 +29,7 @@ public:
|
|||
enum HandleMethod { Abort, Close };
|
||||
|
||||
ReplyTimeout(QNetworkReply* reply, const int timeout, HandleMethod method = Abort) :
|
||||
QObject(reply), m_method(method), m_timedout(false)
|
||||
QObject(reply), m_method(method), m_timedout(false)
|
||||
{
|
||||
Q_ASSERT(reply);
|
||||
if (reply && reply->isRunning()) {
|
||||
|
@ -87,6 +88,10 @@ public:
|
|||
QJsonDocument getBody() const { return _responseBody; }
|
||||
void setBody(const QJsonDocument& body) { _responseBody = body; }
|
||||
|
||||
|
||||
QByteArray getHeader(const QByteArray header) const;
|
||||
void setHeaders(const QList<QNetworkReply::RawHeaderPair>& pairs);
|
||||
|
||||
QString getErrorReason() const { return _errorReason; }
|
||||
void setErrorReason(const QString& errorReason) { _errorReason = errorReason; }
|
||||
|
||||
|
@ -99,6 +104,8 @@ public:
|
|||
private:
|
||||
|
||||
QJsonDocument _responseBody {};
|
||||
QHash<QByteArray, QByteArray> _responseHeaders;
|
||||
|
||||
bool _hasError = false;
|
||||
QString _errorReason;
|
||||
|
||||
|
@ -131,6 +138,7 @@ class ProviderRestApi : public QObject
|
|||
|
||||
public:
|
||||
|
||||
///
|
||||
/// @brief Constructor of the REST-API wrapper
|
||||
///
|
||||
ProviderRestApi();
|
||||
|
@ -176,6 +184,20 @@ public:
|
|||
///
|
||||
virtual ~ProviderRestApi() override;
|
||||
|
||||
///
|
||||
/// @brief Set the API's scheme
|
||||
///
|
||||
/// @param[in] scheme
|
||||
///
|
||||
void setScheme(const QString& scheme);
|
||||
|
||||
///
|
||||
/// @brief Get the API's scheme
|
||||
///
|
||||
/// return schme
|
||||
///
|
||||
QString getScheme() { return _apiUrl.scheme(); }
|
||||
|
||||
///
|
||||
/// @brief Set an API's host
|
||||
///
|
||||
|
@ -190,6 +212,13 @@ public:
|
|||
///
|
||||
void setPort(const int port) { _apiUrl.setPort(port); }
|
||||
|
||||
///
|
||||
/// @brief Get the API's port
|
||||
///
|
||||
/// return port
|
||||
///
|
||||
int getPort() { return _apiUrl.port(); }
|
||||
|
||||
///
|
||||
/// @brief Set an API's url
|
||||
///
|
||||
|
@ -204,6 +233,13 @@ public:
|
|||
///
|
||||
QUrl getUrl() const;
|
||||
|
||||
///
|
||||
/// @brief Set an API's base path (the stable path element before addressing resources)
|
||||
///
|
||||
/// @param[in] pathElements to form a path, e.g. (clip,v2,resource) results in "/clip/v2/resource"
|
||||
///
|
||||
void setBasePath(const QStringList& pathElements);
|
||||
|
||||
///
|
||||
/// @brief Set an API's base path (the stable path element before addressing resources)
|
||||
///
|
||||
|
@ -211,6 +247,11 @@ public:
|
|||
///
|
||||
void setBasePath(const QString& basePath);
|
||||
|
||||
///
|
||||
/// @brief Clear an API's base path (the stable path element before addressing resources)
|
||||
///
|
||||
void clearBasePath();
|
||||
|
||||
///
|
||||
/// @brief Set an API's path to address resources
|
||||
///
|
||||
|
@ -218,12 +259,18 @@ public:
|
|||
///
|
||||
void setPath(const QString& path);
|
||||
|
||||
///
|
||||
/// @brief Set an API's path to address resources
|
||||
///
|
||||
/// @param[in] pathElements to form a path, e.g. (lights,1,state) results in "/lights/1/state/"
|
||||
///
|
||||
void setPath(const QStringList& pathElements);
|
||||
|
||||
///
|
||||
/// @brief Clear an API's path
|
||||
///
|
||||
void clearPath();
|
||||
|
||||
///
|
||||
/// @brief Append an API's path element to path set before
|
||||
///
|
||||
|
@ -252,6 +299,10 @@ public:
|
|||
///
|
||||
void setQuery(const QUrlQuery& query);
|
||||
|
||||
|
||||
QString getBasePath() {return _basePath;}
|
||||
QString getPath() {return _path;}
|
||||
|
||||
///
|
||||
/// @brief Execute GET request
|
||||
///
|
||||
|
@ -359,6 +410,14 @@ public:
|
|||
/// @param[in] timeout in milliseconds.
|
||||
void setTransferTimeout(std::chrono::milliseconds timeout = DEFAULT_REST_TIMEOUT) { _requestTimeout = timeout; }
|
||||
|
||||
|
||||
bool setCaCertificate(const QString& caFileName);
|
||||
|
||||
void acceptSelfSignedCertificates(bool accept);
|
||||
|
||||
void setAlternateServerIdentity(const QString& serverIdentity);
|
||||
QString getAlternateServerIdentity() const;
|
||||
|
||||
///
|
||||
/// @brief Set the common logger for LED-devices.
|
||||
///
|
||||
|
@ -366,6 +425,10 @@ public:
|
|||
///
|
||||
void setLogger(Logger* log) { _log = log; }
|
||||
|
||||
protected slots:
|
||||
/// Handle the SSLErrors
|
||||
void onSslErrors(QNetworkReply* reply, const QList<QSslError>& errors);
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
|
@ -379,9 +442,11 @@ private:
|
|||
|
||||
httpResponse executeOperation(QNetworkAccessManager::Operation op, const QUrl& url, const QByteArray& body = {});
|
||||
|
||||
bool checkServerIdentity(const QSslConfiguration& sslConfig) const;
|
||||
|
||||
Logger* _log;
|
||||
|
||||
// QNetworkAccessManager object for sending REST-requests.
|
||||
/// QNetworkAccessManager object for sending REST-requests.
|
||||
QNetworkAccessManager* _networkManager;
|
||||
std::chrono::milliseconds _requestTimeout;
|
||||
|
||||
|
@ -394,6 +459,9 @@ private:
|
|||
QUrlQuery _query;
|
||||
|
||||
QNetworkRequest _networkRequestHeaders;
|
||||
|
||||
QString _serverIdentity;
|
||||
bool _isSeflSignedCertificateAccpeted;
|
||||
};
|
||||
|
||||
#endif // PROVIDERRESTKAPI_H
|
||||
|
|
|
@ -150,6 +150,11 @@ const int *ProviderUdpSSL::getCiphersuites() const
|
|||
return mbedtls_ssl_list_ciphersuites();
|
||||
}
|
||||
|
||||
void ProviderUdpSSL::setPSKidentity(const QString& pskIdentity)
|
||||
{
|
||||
_psk_identity = pskIdentity;
|
||||
}
|
||||
|
||||
bool ProviderUdpSSL::initNetwork()
|
||||
{
|
||||
if ((!_isDeviceReady || _streamPaused) && _streamReady)
|
||||
|
@ -334,6 +339,11 @@ void ProviderUdpSSL::freeSSLConnection()
|
|||
}
|
||||
}
|
||||
|
||||
void ProviderUdpSSL::writeBytes(QByteArray data, bool flush)
|
||||
{
|
||||
writeBytes(static_cast<uint>(data.size()), reinterpret_cast<unsigned char*>(data.data()), flush);
|
||||
}
|
||||
|
||||
void ProviderUdpSSL::writeBytes(unsigned int size, const uint8_t* data, bool flush)
|
||||
{
|
||||
if (!_streamReady || _streamPaused)
|
||||
|
|
|
@ -100,6 +100,14 @@ protected:
|
|||
///
|
||||
void stopConnection();
|
||||
|
||||
///
|
||||
/// Writes the given bytes/bits to the UDP-device and sleeps the latch time to ensure that the
|
||||
/// values are latched.
|
||||
///
|
||||
/// @param[in] data The data
|
||||
///
|
||||
void writeBytes(QByteArray data, bool flush = false);
|
||||
|
||||
///
|
||||
/// Writes the given bytes/bits to the UDP-device and sleeps the latch time to ensure that the
|
||||
/// values are latched.
|
||||
|
@ -116,6 +124,8 @@ protected:
|
|||
///
|
||||
virtual const int * getCiphersuites() const;
|
||||
|
||||
void setPSKidentity(const QString& pskIdentity);
|
||||
|
||||
private:
|
||||
|
||||
bool initConnection();
|
||||
|
|
|
@ -159,12 +159,10 @@ QJsonObject LedDeviceWS281x::discover(const QJsonObject& /*params*/)
|
|||
|
||||
QJsonArray deviceList;
|
||||
|
||||
if (SysInfo::isUserAdmin())
|
||||
{
|
||||
//Indicate the general availability of the device, if hyperion is run under root
|
||||
deviceList << QJsonObject ({{"found",true}});
|
||||
devicesDiscovered.insert("devices", deviceList);
|
||||
}
|
||||
//Indicate the general availability of the device, if hyperion is run under root
|
||||
devicesDiscovered.insert("isUserAdmin", SysInfo::isUserAdmin());
|
||||
|
||||
devicesDiscovered.insert("devices", deviceList);
|
||||
|
||||
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
|
|
|
@ -35,26 +35,45 @@
|
|||
},
|
||||
"propertyOrder": 4
|
||||
},
|
||||
"useAPIv2": {
|
||||
"type": "boolean",
|
||||
"format": "checkbox",
|
||||
"title": "edt_dev_spec_useAPIv2_title",
|
||||
"default": false,
|
||||
"options": {
|
||||
"hidden": true
|
||||
},
|
||||
"access": "expert",
|
||||
"propertyOrder": 5
|
||||
},
|
||||
"useEntertainmentAPI": {
|
||||
"type": "boolean",
|
||||
"format": "checkbox",
|
||||
"title": "edt_dev_spec_useEntertainmentAPI_title",
|
||||
"default": true,
|
||||
"propertyOrder": 5
|
||||
"options": {
|
||||
"hidden": true
|
||||
},
|
||||
"propertyOrder": 6
|
||||
},
|
||||
"switchOffOnBlack": {
|
||||
"type": "boolean",
|
||||
"format": "checkbox",
|
||||
"title": "edt_dev_spec_switchOffOnBlack_title",
|
||||
"default": false,
|
||||
"propertyOrder": 6
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 7
|
||||
},
|
||||
"restoreOriginalState": {
|
||||
"type": "boolean",
|
||||
"format": "checkbox",
|
||||
"title": "edt_dev_spec_restoreOriginalState_title",
|
||||
"default": false,
|
||||
"propertyOrder": 7
|
||||
"propertyOrder": 8
|
||||
},
|
||||
"blackLevel": {
|
||||
"type": "number",
|
||||
|
@ -64,7 +83,12 @@
|
|||
"step": 0.01,
|
||||
"minimum": 0.001,
|
||||
"maximum": 1.0,
|
||||
"propertyOrder": 8
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 9
|
||||
},
|
||||
"onBlackTimeToPowerOff": {
|
||||
"type": "integer",
|
||||
|
@ -76,7 +100,12 @@
|
|||
"maximum": 100000,
|
||||
"default": 600,
|
||||
"required": true,
|
||||
"propertyOrder": 9
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 10
|
||||
},
|
||||
"onBlackTimeToPowerOn": {
|
||||
"type": "integer",
|
||||
|
@ -88,14 +117,24 @@
|
|||
"maximum": 100000,
|
||||
"default": 300,
|
||||
"required": true,
|
||||
"propertyOrder": 9
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 11
|
||||
},
|
||||
"candyGamma": {
|
||||
"type": "boolean",
|
||||
"format": "checkbox",
|
||||
"title": "edt_dev_spec_candyGamma_title",
|
||||
"default": true,
|
||||
"propertyOrder": 10
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 12
|
||||
},
|
||||
"lightIds": {
|
||||
"type": "array",
|
||||
|
@ -112,20 +151,23 @@
|
|||
"useEntertainmentAPI": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 11
|
||||
"propertyOrder": 13
|
||||
},
|
||||
"groupId": {
|
||||
"type": "number",
|
||||
"format": "stepper",
|
||||
"step": 1,
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_groupId_title",
|
||||
"default": 0,
|
||||
"default": "",
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useEntertainmentAPI": true
|
||||
}
|
||||
},
|
||||
"propertyOrder": 12
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 14
|
||||
},
|
||||
"brightnessFactor": {
|
||||
"type": "number",
|
||||
|
@ -136,7 +178,12 @@
|
|||
"minimum": 0.5,
|
||||
"maximum": 10.0,
|
||||
"access": "advanced",
|
||||
"propertyOrder": 13
|
||||
"options": {
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 15
|
||||
},
|
||||
"handshakeTimeoutMin": {
|
||||
"type": "number",
|
||||
|
@ -154,7 +201,7 @@
|
|||
"useEntertainmentAPI": true
|
||||
}
|
||||
},
|
||||
"propertyOrder": 14
|
||||
"propertyOrder": 16
|
||||
},
|
||||
"handshakeTimeoutMax": {
|
||||
"type": "number",
|
||||
|
@ -172,7 +219,7 @@
|
|||
"useEntertainmentAPI": true
|
||||
}
|
||||
},
|
||||
"propertyOrder": 15
|
||||
"propertyOrder": 17
|
||||
},
|
||||
"verbose": {
|
||||
"type": "boolean",
|
||||
|
@ -180,7 +227,7 @@
|
|||
"title": "edt_dev_spec_verbose_title",
|
||||
"default": false,
|
||||
"access": "expert",
|
||||
"propertyOrder": 16
|
||||
"propertyOrder": 18
|
||||
},
|
||||
"transitiontime": {
|
||||
"type": "number",
|
||||
|
@ -195,24 +242,29 @@
|
|||
"useEntertainmentAPI": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 17
|
||||
"propertyOrder": 19
|
||||
},
|
||||
"blackLightsTimeout": {
|
||||
"type": "number",
|
||||
"title": "edt_dev_spec_blackLightsTimeout_title",
|
||||
"default": 5000,
|
||||
"options": {
|
||||
"hidden": true
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 18
|
||||
"propertyOrder": 20
|
||||
},
|
||||
"brightnessThreshold": {
|
||||
"type": "number",
|
||||
"title": "edt_dev_spec_brightnessThreshold_title",
|
||||
"default": 0.0001,
|
||||
"options": {
|
||||
"hidden": true
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 19
|
||||
"propertyOrder": 21
|
||||
},
|
||||
"brightnessMin": {
|
||||
"type": "number",
|
||||
|
@ -223,9 +275,11 @@
|
|||
"maximum": 1.0,
|
||||
"access": "advanced",
|
||||
"options": {
|
||||
"hidden": true
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 20
|
||||
"propertyOrder": 22
|
||||
},
|
||||
"brightnessMax": {
|
||||
"type": "number",
|
||||
|
@ -236,9 +290,11 @@
|
|||
"maximum": 1.0,
|
||||
"access": "advanced",
|
||||
"options": {
|
||||
"hidden": true
|
||||
"dependencies": {
|
||||
"useAPIv2": false
|
||||
}
|
||||
},
|
||||
"propertyOrder": 21
|
||||
"propertyOrder": 23
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
|
|
|
@ -182,6 +182,7 @@ bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddr
|
|||
}
|
||||
else
|
||||
{
|
||||
QObject::disconnect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, nullptr, nullptr);
|
||||
Error(log, "Resolved mDNS hostname [%s] timed out", QSTRING_CSTR(hostname));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ void Logger::deleteInstance(const QString & name, const QString & subName)
|
|||
|
||||
if (name.isEmpty())
|
||||
{
|
||||
for (auto *logger : qAsConst(LoggerMap)) {
|
||||
for (auto *logger : std::as_const(LoggerMap)) {
|
||||
delete logger;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// stdlib includes
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
@ -58,13 +59,13 @@ QPair<bool, bool> QJsonSchemaChecker::validate(const QJsonObject& value, bool ig
|
|||
QJsonObject QJsonSchemaChecker::getAutoCorrectedConfig(const QJsonObject& value, bool ignoreRequired)
|
||||
{
|
||||
_ignoreRequired = ignoreRequired;
|
||||
QStringList sequence = QStringList() << "remove" << "modify" << "create";
|
||||
const QStringList sequence = QStringList() << "remove" << "modify" << "create";
|
||||
_error = false;
|
||||
_schemaError = false;
|
||||
_messages.clear();
|
||||
_autoCorrected = value;
|
||||
|
||||
for (const QString& correct : qAsConst(sequence))
|
||||
for (const QString& correct : sequence)
|
||||
{
|
||||
_correct = correct;
|
||||
_currentPath.clear();
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICMjCCAdigAwIBAgIUO7FSLbaxikuXAljzVaurLXWmFw4wCgYIKoZIzj0EAwIw
|
||||
OTELMAkGA1UEBhMCTkwxFDASBgNVBAoMC1BoaWxpcHMgSHVlMRQwEgYDVQQDDAty
|
||||
b290LWJyaWRnZTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMzgwMTE5MDMxNDA3WjA5
|
||||
MQswCQYDVQQGEwJOTDEUMBIGA1UECgwLUGhpbGlwcyBIdWUxFDASBgNVBAMMC3Jv
|
||||
b3QtYnJpZGdlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjNw2tx2AplOf9x86
|
||||
aTdvEcL1FU65QDxziKvBpW9XXSIcibAeQiKxegpq8Exbr9v6LBnYbna2VcaK0G22
|
||||
jOKkTqOBuTCBtjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNV
|
||||
HQ4EFgQUZ2ONTFrDT6o8ItRnKfqWKnHFGmQwdAYDVR0jBG0wa4AUZ2ONTFrDT6o8
|
||||
ItRnKfqWKnHFGmShPaQ7MDkxCzAJBgNVBAYTAk5MMRQwEgYDVQQKDAtQaGlsaXBz
|
||||
IEh1ZTEUMBIGA1UEAwwLcm9vdC1icmlkZ2WCFDuxUi22sYpLlwJY81Wrqy11phcO
|
||||
MAoGCCqGSM49BAMCA0gAMEUCIEBYYEOsa07TH7E5MJnGw557lVkORgit2Rm1h3B2
|
||||
sFgDAiEA1Fj/C3AN5psFMjo0//mrQebo0eKd3aWRx+pQY08mk48=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-aml)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-dispmanx)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-framebuffer)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-osx)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-qt)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-remote)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
|
||||
|
|
|
@ -57,9 +57,9 @@ void showHelp(Option & option){
|
|||
|
||||
int getInstaneIdbyName(const QJsonObject & reply, const QString & name){
|
||||
if(reply.contains("instance")){
|
||||
QJsonArray list = reply.value("instance").toArray();
|
||||
const QJsonArray list = reply.value("instance").toArray();
|
||||
|
||||
for ( const auto &entry : qAsConst(list) ) {
|
||||
for ( const auto &entry : list ) {
|
||||
const QJsonObject obj = entry.toObject();
|
||||
if(obj["friendly_name"] == name && obj["running"].toBool())
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-v4l2)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-x11)
|
||||
|
||||
find_package(X11 REQUIRED)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(hyperion-xcb)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)
|
||||
|
|
|
@ -160,7 +160,7 @@ if (APPLE)
|
|||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/osxbundle/Info.plist.in
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "Hyperion"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${HYPERION_VERSION}
|
||||
MACOSX_BUNDLE_COPYRIGHT "Copyright(c) 2014-2022 Hyperion Project"
|
||||
MACOSX_BUNDLE_COPYRIGHT "Copyright(c) 2014-2023 Hyperion Project"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "com.hyperion-project.${PROJECT_NAME}"
|
||||
MACOSX_BUNDLE_ICON_FILE "Hyperion.icns"
|
||||
MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${HYPERION_VERSION}"
|
||||
|
|
|
@ -268,7 +268,7 @@ SuspendHandlerLinux::SuspendHandlerLinux()
|
|||
QDBusConnection systemBus = QDBusConnection::systemBus();
|
||||
if (!systemBus.isConnected())
|
||||
{
|
||||
Error(Logger::getInstance("DAEMON"), "Suspend/resume handler - System bus is not connected");
|
||||
Info(Logger::getInstance("DAEMON"), "The suspend/resume feature is not supported by your system configuration");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -288,7 +288,7 @@ SuspendHandlerLinux::SuspendHandlerLinux()
|
|||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
if (!sessionBus.isConnected())
|
||||
{
|
||||
Error(Logger::getInstance("DAEMON"), "Lock/unlock handler- Session bus is not connected");
|
||||
Info(Logger::getInstance("DAEMON"), "The lock/unlock feature is not supported by your system configuration");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -15,4 +15,5 @@ void CreateConsole()
|
|||
freopen_s(&fDummy, "CONOUT$", "w", stderr);
|
||||
freopen_s(&fDummy, "CONIN$", "r", stdin);
|
||||
SetConsoleTitle(TEXT("Hyperion"));
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
}
|
||||
|
|
|
@ -268,9 +268,9 @@ int main(int argc, char** argv)
|
|||
if (directory.exists() && destDir.exists())
|
||||
{
|
||||
std::cout << "Extract to folder: " << destDir.absolutePath().toStdString() << std::endl;
|
||||
QStringList filenames = directory.entryList(QStringList() << "*", QDir::Files, QDir::Name | QDir::IgnoreCase);
|
||||
const QStringList filenames = directory.entryList(QStringList() << "*", QDir::Files, QDir::Name | QDir::IgnoreCase);
|
||||
QString destFileName;
|
||||
for (const QString & filename : qAsConst(filenames))
|
||||
for (const QString & filename : filenames)
|
||||
{
|
||||
destFileName = destDir.dirName()+"/"+filename;
|
||||
if (QFile::exists(destFileName))
|
||||
|
|
|
@ -24,7 +24,7 @@ int main()
|
|||
return -1;
|
||||
}
|
||||
|
||||
const LedString ledString = hyperion::createLedString(config["leds"].toArray(), hyperion::createColorOrder(config["device"].toObject()));
|
||||
const LedString ledString = LedString::createLedString(config["leds"].toArray(), hyperion::createColorOrder(config["device"].toObject()));
|
||||
|
||||
const ColorRgb testColor = {64, 123, 12};
|
||||
|
||||
|
|
Loading…
Reference in New Issue