Merge pull request #523 from Paulchen-Panther/BugFixes

Massive overhaul and bugfixes
This commit is contained in:
Rick164 2019-02-06 12:23:38 +01:00 committed by GitHub
commit f83c79973b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
314 changed files with 13032 additions and 7822 deletions

1
.gitignore vendored
View File

@ -6,7 +6,6 @@ CMakeFiles/
__/ __/
# Ignoring autogenerated files # Ignoring autogenerated files
*.cmake
Makefile Makefile
qrc_*.cpp qrc_*.cpp
*.qrc.depends *.qrc.depends

6
.gitmodules vendored
View File

@ -1,7 +1,7 @@
[submodule "dependencies/external/protobuf"]
path = dependencies/external/protobuf
url = https://github.com/hyperion-project/protobuf.git
[submodule "dependencies/external/rpi_ws281x"] [submodule "dependencies/external/rpi_ws281x"]
path = dependencies/external/rpi_ws281x path = dependencies/external/rpi_ws281x
url = https://github.com/hyperion-project/rpi_ws281x.git url = https://github.com/hyperion-project/rpi_ws281x.git
branch = master branch = master
[submodule "dependencies/external/flatbuffers"]
path = dependencies/external/flatbuffers
url = https://github.com/google/flatbuffers

View File

@ -5,19 +5,27 @@ cache:
notifications: notifications:
email: false email: false
language: cpp language: cpp
services:
- docker
matrix: matrix:
include: include:
- os: linux - os: linux
dist: trusty dist: trusty
sudo: required env:
- DOCKER_TAG=ubuntu1604
- DOCKER_NAME="Ubuntu 16.04"
- os: linux
dist: trusty
env:
- DOCKER_TAG=cross-qemu-rpistretch
- DOCKER_NAME="Raspberry Pi"
- os: osx - os: osx
osx_image: xcode7.3 osx_image: xcode8.3
env: env:
- HOMEBREW_CACHE=$HOME/brew-cache - HOMEBREW_CACHE=$HOME/brew-cache
before_install: before_install:
- ./.travis/travis_install.sh - ./.travis/travis_install.sh
script: script:
- ./.travis/travis_build.sh - ./.travis/travis_build.sh
- ./test/testrunner.sh
after_success: after_success:
- ./.travis/travis_deploy.sh - ./.travis/travis_deploy.sh

View File

@ -5,6 +5,7 @@
PLATFORM=x86 PLATFORM=x86
BUILD_TYPE=Debug BUILD_TYPE=Debug
PACKAGES=""
# Detect number of processor cores # Detect number of processor cores
# default is 4 jobs # default is 4 jobs
@ -16,32 +17,48 @@ elif [[ "$TRAVIS_OS_NAME" == 'linux' ]]
then then
JOBS=$(nproc) JOBS=$(nproc)
fi fi
echo "compile jobs: ${JOBS:=4}"
# compile prepare # Determine cmake build type; tag builds are Release, else Debug
mkdir build || exit 1
cd build
# Compile hyperion for tags
[ -n "${TRAVIS_TAG:-}" ] && BUILD_TYPE=Release [ -n "${TRAVIS_TAG:-}" ] && BUILD_TYPE=Release
# Compile hyperion for cron - take default settings # Determine package creation; True for cron and tag builds
[ "${TRAVIS_EVENT_TYPE:-}" == 'cron' ] || [ -n "${TRAVIS_TAG:-}" ] && PACKAGES=package
# Compile for PR (no tag and no cron) # Determie -dev appends to platform;
[ "${TRAVIS_EVENT_TYPE:-}" != 'cron' -a -z "${TRAVIS_TAG:-}" ] && PLATFORM=${PLATFORM}-dev [ "${TRAVIS_EVENT_TYPE:-}" != 'cron' -a -z "${TRAVIS_TAG:-}" ] && PLATFORM=${PLATFORM}-dev
cmake -DPLATFORM=$PLATFORM -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=/usr .. || exit 2 # Build the package on osx
if [[ "$TRAVIS_OS_NAME" == 'linux' ]] if [[ "$TRAVIS_OS_NAME" == 'osx' || "$TRAVIS_OS_NAME" == 'darwin' ]]
then then
# activate dispmanx and osx mocks # compile prepare
cmake -DENABLE_OSX=ON -DENABLE_DISPMANX=ON .. || exit 5 mkdir build || exit 1
cd build
cmake -DPLATFORM=$PLATFORM -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=/usr .. || exit 2
make -j ${JOBS} || exit 3
fi fi
echo "compile jobs: ${JOBS:=4}" # Build the package with docker
make -j ${JOBS} || exit 3
# Build the package on Linux
if [[ $TRAVIS_OS_NAME == 'linux' ]] if [[ $TRAVIS_OS_NAME == 'linux' ]]
then then
make -j ${JOBS} package || exit 4 echo "Compile Hyperion with DOCKER_TAG = ${DOCKER_TAG} and friendly name DOCKER_NAME = ${DOCKER_NAME}"
fi # take ownership of deploy dir
mkdir $TRAVIS_BUILD_DIR/deploy
# run docker
docker run --rm \
-v "${TRAVIS_BUILD_DIR}/deploy:/deploy" \
-v "${TRAVIS_BUILD_DIR}:/source:ro" \
hyperionorg/hyperion-ci:$DOCKER_TAG \
/bin/bash -c "mkdir build && cp -r /source/. /build &&
cd /build && mkdir build && cd build &&
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .. || exit 2 &&
make -j $(nproc) ${PACKAGES} || exit 3 &&
echo '---> Copy binaries and packages to host folder: ${TRAVIS_BUILD_DIR}/deploy' &&
cp -v /build/build/bin/h* /deploy/ 2>/dev/null || : &&
cp -v /build/build/Hyperion-* /deploy/ 2>/dev/null || : &&
exit 0;
exit 1 " || { echo "---> Hyperion compilation failed! Abort"; exit 4; }
# overwrite file owner to current user
sudo chown -fR $(stat -c "%U:%G" $TRAVIS_BUILD_DIR/deploy) $TRAVIS_BUILD_DIR/deploy
fi

View File

@ -1,10 +1,13 @@
#!/bin/bash #!/bin/bash
# sf_upload <deploylist> <sf_dir> # sf_upload <FILES> <sf_dir>
sf_upload() sf_upload()
{ {
echo "Uploading following files: ${1}
to dir /hyperion-project/${2}"
/usr/bin/expect <<-EOD /usr/bin/expect <<-EOD
spawn scp $1 hyperionsf37@frs.sourceforge.net:/home/frs/project/hyperion-project/dev/$2 spawn scp $1hyperionsf37@frs.sourceforge.net:/home/frs/project/hyperion-project/$2
expect "*(yes/no)*" expect "*(yes/no)*"
send "yes\r" send "yes\r"
expect "*password:*" expect "*password:*"
@ -13,18 +16,49 @@ sf_upload()
EOD EOD
} }
deploylist="hyperion-2.0.0-Linux-x86.tar.gz" # append current Date to filename (just packages no binaries)
appendDate()
{
D=$(date +%Y-%m-%d)
for F in $TRAVIS_BUILD_DIR/deploy/Hy*
do
mv "$F" "${F%.*}-$D.${F##*.}"
done
}
# append friendly name (just packages no binaries)
appendName()
{
for F in $TRAVIS_BUILD_DIR/deploy/Hy*
do
mv "$F" "${F%.*}-($DOCKER_NAME).${F##*.}"
done
}
# get all files to deploy (just packages no binaries)
getFiles()
{
FILES=""
for f in $TRAVIS_BUILD_DIR/deploy/Hy*;
do FILES+="${f} ";
done;
}
if [[ $TRAVIS_OS_NAME == 'linux' ]]; then if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
cd $TRAVIS_BUILD_DIR/build
if [[ -n $TRAVIS_TAG ]]; then if [[ -n $TRAVIS_TAG ]]; then
echo "tag upload" echo "tag upload"
sf_upload $deploylist release appendName
appendDate
getFiles
sf_upload $FILES release
elif [[ $TRAVIS_EVENT_TYPE == 'cron' ]]; then elif [[ $TRAVIS_EVENT_TYPE == 'cron' ]]; then
echo "cron upload" echo "cron upload"
sf_upload $deploylist alpha appendName
appendDate
getFiles
sf_upload $FILES dev/alpha
else else
echo "PR can't be uploaded for security reasons" echo "Direct pushed no upload, PRs not possible"
sf_upload $deploylist pr #sf_upload $FILES pr
fi fi
fi fi

View File

@ -7,19 +7,19 @@
if [[ $TRAVIS_OS_NAME == 'osx' || $TRAVIS_OS_NAME == 'darwin' ]] if [[ $TRAVIS_OS_NAME == 'osx' || $TRAVIS_OS_NAME == 'darwin' ]]
then then
echo "Install OSX deps" echo "Install OSX deps"
time brew update brew update
time brew install qt5 || true brew install qt5 || true
time brew install python3 || true brew upgrade python3 || true
time brew install libusb || true brew upgrade libusb || true
time brew install cmake || true brew upgrade cmake || true
time brew install doxygen || true brew install doxygen || true
# install linux deps for hyperion compile # install linux deps for hyperion compile
elif [[ $TRAVIS_OS_NAME == 'linux' ]] elif [[ $TRAVIS_OS_NAME == 'linux' ]]
then then
echo "Install linux deps" echo "Install linux deps"
sudo apt-get -qq update #sudo apt-get -qq update
sudo apt-get install -qq -y qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev doxygen expect #sudo apt-get install -qq -y qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev doxygen expect
else else
echo "Unsupported platform: $TRAVIS_OS_NAME" echo "Unsupported platform: $TRAVIS_OS_NAME"
exit 5 exit 5

View File

@ -20,9 +20,10 @@ SET ( DEFAULT_AMLOGIC OFF )
SET ( DEFAULT_DISPMANX OFF ) SET ( DEFAULT_DISPMANX OFF )
SET ( DEFAULT_OSX OFF ) SET ( DEFAULT_OSX OFF )
SET ( DEFAULT_X11 OFF ) SET ( DEFAULT_X11 OFF )
SET ( DEFAULT_QT ON )
SET ( DEFAULT_WS281XPWM OFF ) SET ( DEFAULT_WS281XPWM OFF )
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON ) SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF ) SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF )
SET ( DEFAULT_TESTS OFF ) SET ( DEFAULT_TESTS OFF )
IF ( ${CMAKE_SYSTEM} MATCHES "Linux" ) IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
@ -47,7 +48,7 @@ endif()
if ( NOT DEFINED PLATFORM ) if ( NOT DEFINED PLATFORM )
if ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86" ) if ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86" )
SET( PLATFORM "x86") SET( PLATFORM "x11")
elseif ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64") elseif ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64")
SET( PLATFORM "rpi") SET( PLATFORM "rpi")
FILE( READ /proc/cpuinfo SYSTEM_CPUINFO ) FILE( READ /proc/cpuinfo SYSTEM_CPUINFO )
@ -61,7 +62,7 @@ if ( NOT DEFINED PLATFORM )
if ( PLATFORM ) if ( PLATFORM )
message( STATUS "PLATFORM is not defined, evaluated platform: ${PLATFORM}") message( STATUS "PLATFORM is not defined, evaluated platform: ${PLATFORM}")
else() else()
message( FATAL_ERROR "PLATFORM is not defined and could not be evaluated. Set -DPLATFORM=<rpi|amlogic|amlogic64|x86|x86-dev|osx|osx-dev>") message( FATAL_ERROR "PLATFORM is not defined and could not be evaluated. Set -DPLATFORM=<rpi|amlogic|amlogic64|x11|x11-dev|osx|osx-dev>")
endif() endif()
endif() endif()
@ -95,9 +96,9 @@ elseif ( "${PLATFORM}" STREQUAL "amlogic" )
SET ( DEFAULT_AMLOGIC ON ) SET ( DEFAULT_AMLOGIC ON )
elseif ( "${PLATFORM}" STREQUAL "amlogic64" ) elseif ( "${PLATFORM}" STREQUAL "amlogic64" )
SET ( DEFAULT_AMLOGIC ON ) SET ( DEFAULT_AMLOGIC ON )
elseif ( "${PLATFORM}" MATCHES "x86" ) elseif ( "${PLATFORM}" MATCHES "x11" )
SET ( DEFAULT_X11 ON ) SET ( DEFAULT_X11 ON )
if ( "${PLATFORM}" STREQUAL "x86-dev" ) if ( "${PLATFORM}" STREQUAL "x11-dev" )
SET ( DEFAULT_AMLOGIC ON) SET ( DEFAULT_AMLOGIC ON)
SET ( DEFAULT_WS281XPWM ON ) SET ( DEFAULT_WS281XPWM ON )
endif() endif()
@ -151,7 +152,8 @@ message(STATUS "ENABLE_USB_HID = ${ENABLE_USB_HID}")
option(ENABLE_X11 "Enable the X11 grabber" ${DEFAULT_X11}) option(ENABLE_X11 "Enable the X11 grabber" ${DEFAULT_X11})
message(STATUS "ENABLE_X11 = ${ENABLE_X11}") message(STATUS "ENABLE_X11 = ${ENABLE_X11}")
SET(ENABLE_QT5 ON) option(ENABLE_QT "Enable the qt grabber" ${DEFAULT_QT})
message(STATUS "ENABLE_QT = ${ENABLE_QT}")
option(ENABLE_TESTS "Compile additional test applications" ${DEFAULT_TESTS}) option(ENABLE_TESTS "Compile additional test applications" ${DEFAULT_TESTS})
message(STATUS "ENABLE_TESTS = ${ENABLE_TESTS}") message(STATUS "ENABLE_TESTS = ${ENABLE_TESTS}")
@ -159,9 +161,8 @@ message(STATUS "ENABLE_TESTS = ${ENABLE_TESTS}")
option(ENABLE_PROFILER "enable profiler capabilities - not for release code" OFF) option(ENABLE_PROFILER "enable profiler capabilities - not for release code" OFF)
message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}") message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}")
SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf )
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto ) SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf )
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
# check all json files # check all json files
FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json ) FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json )
@ -230,6 +231,9 @@ CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
endif()
if(COMPILER_SUPPORTS_CXX11) if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X) elseif(COMPILER_SUPPORTS_CXX0X)
@ -246,7 +250,7 @@ if (UNIX AND NOT APPLE)
endif () endif ()
# add QT5 dependency # add QT5 dependency
SET(QT_MIN_VERSION "5.2.0") SET(QT_MIN_VERSION "5.5.0")
find_package(Qt5 COMPONENTS Core Gui Network SerialPort REQUIRED) find_package(Qt5 COMPONENTS Core Gui Network SerialPort REQUIRED)
message( STATUS "Found Qt Version: ${Qt5Core_VERSION}" ) message( STATUS "Found Qt Version: ${Qt5Core_VERSION}" )
IF ( "${Qt5Core_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" ) IF ( "${Qt5Core_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" )
@ -276,6 +280,9 @@ if (ENABLE_TESTS)
add_subdirectory(test) add_subdirectory(test)
endif () endif ()
# Add resources directory
add_subdirectory(resources)
# Add the doxygen generation directory # Add the doxygen generation directory
add_subdirectory(doc) add_subdirectory(doc)

View File

@ -1,4 +1,18 @@
# Install the required tools and dependencies # 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 compilation for Raspberry Pi (Raspbian stretch)
To compile Hyperion for Ubuntu 16.04 (x64) or higher just execute the following command
```
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh
```
To compile Hyperion for Raspberry Pi
```
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -t cross-qemu-rpistretch
```
The compiled binaries and packages will be available at the deploy folder next to the script
Note: call the script with `./docker-compile.sh -h` for more options
# The usual way
## Debian/Ubuntu/Win10LinuxSubsystem ## Debian/Ubuntu/Win10LinuxSubsystem
@ -6,24 +20,13 @@
sudo apt-get update sudo apt-get update
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev
``` ```
### Ubuntu 14.04 specific
You need a newer version of cmake (minimum 3.0.0). Install it from the ppa or website
```
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:george-edison55/cmake-3.x
sudo apt-get update && sudo apt-get upgrade
```
**on RPI you need the videocore IV headers** **on RPI you need the videocore IV headers**
``` ```
sudo apt-get install libraspberrypi-dev sudo apt-get install libraspberrypi-dev
``` ```
**OSMC**
libraspberrypi-dev is not available, use this instead
```
sudo apt-get install rbp-userland-dev-osmc
```
**ATTENTION Win10LinuxSubsystem** we do not (/we can't) support using hyperion in linux subsystem of MS Windows 10, albeit some users tested it with success. Keep in mind to disable **ATTENTION Win10LinuxSubsystem** we do not (/we can't) support using hyperion in linux subsystem of MS Windows 10, albeit some users tested it with success. Keep in mind to disable
all linux specific led and grabber hardware via cmake. Because we use QT as framework in hyperion, serialport leds and network driven devices could work. all linux specific led and grabber hardware via cmake. Because we use QT as framework in hyperion, serialport leds and network driven devices could work.
@ -71,24 +74,16 @@ sudo make install/strip
sudo make uninstall sudo make uninstall
# ... or run it from compile directory # ... or run it from compile directory
bin/hyperiond bin/hyperiond
# webui is located on localhost:8090 # webui is located on localhost:8090 or 8091
``` ```
### Download ### Download
Create hyperion directory and checkout the code from github Creates hyperion directory and checkout the code from github
You might want to add `--depth 1` to the `git` command if you only want to compile the current source and have no need for the entire git repository
``` ```
export HYPERION_DIR="hyperion" export HYPERION_DIR="hyperion"
git clone --recursive https://github.com/hyperion-project/hyperion.ng.git "$HYPERION_DIR" git clone --recursive --depth 1 https://github.com/hyperion-project/hyperion.ng.git "$HYPERION_DIR"
```
**Note:** If you forget the --recursive in above statement or you are updating an existing clone you need to clone the protobuf submodule by runnning the follwing two statements:
```
git submodule init
git submodule update
``` ```
### Preparations ### Preparations
@ -110,7 +105,7 @@ cmake -DCMAKE_BUILD_TYPE=Release ..
*Developers on x86* linux should use: *Developers on x86* linux should use:
``` ```
cmake -DPLATFORM=x86-dev -DCMAKE_BUILD_TYPE=Release .. cmake -DPLATFORM=x11-dev -DCMAKE_BUILD_TYPE=Release ..
``` ```
To use framebuffer instead of dispmanx (for example on the *cubox-i*): To use framebuffer instead of dispmanx (for example on the *cubox-i*):

View File

@ -12,7 +12,7 @@
sudo apt-get update sudo apt-get update
sudo apt-get upgrade sudo apt-get upgrade
#TO-DO verify what is really required #TO-DO verify what is really required
#blacklist: protobuf-compiler lib32z1 lib32ncurses5 lib32bz2-1.0 zlib1g-dev #blacklist: lib32z1 lib32ncurses5 lib32bz2-1.0 zlib1g-dev
sudo apt-get -qq -y install git rsync cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev sudo apt-get -qq -y install git rsync cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev
echo 'PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin' >> .bashrc echo 'PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin' >> .bashrc
@ -58,12 +58,12 @@ git clone --depth 1 git://github.com/raspberrypi/tools.git "$RASCROSS_DIR/tools"
# get the Hyperion sources # get the Hyperion sources
git clone --recursive https://github.com/hyperion-project/hyperion.ng.git "$HYPERION_DIR" git clone --recursive https://github.com/hyperion-project/hyperion.ng.git "$HYPERION_DIR"
# do a native build (to build the protobuf compiler for the native platform) # do a native build (to build the flatbuffers compiler for the native platform)
mkdir -p "$NATIVE_BUILD_DIR" mkdir -p "$NATIVE_BUILD_DIR"
cmake -DENABLE_DISPMANX=OFF --build "$NATIVE_BUILD_DIR" "$HYPERION_DIR" cmake -DENABLE_DISPMANX=OFF --build "$NATIVE_BUILD_DIR" "$HYPERION_DIR"
# do the cross build # do the cross build
# specify the protoc export file to import the protobuf compiler from the native build # specify the protoc export file to import the flatbuffers compiler from the native build
mkdir -p "$TARGET_BUILD_DIR" mkdir -p "$TARGET_BUILD_DIR"
cmake -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" -DIMPORT_PROTOC=$NATIVE_BUILD_DIR/protoc_export.cmake --build "$TARGET_BUILD_DIR" "$HYPERION_DIR" cmake -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" -DIMPORT_PROTOC=$NATIVE_BUILD_DIR/protoc_export.cmake --build "$TARGET_BUILD_DIR" "$HYPERION_DIR"

View File

@ -18,6 +18,9 @@
// Define to enable the x11 grabber // Define to enable the x11 grabber
#cmakedefine ENABLE_X11 #cmakedefine ENABLE_X11
// Define to enable the qt grabber
#cmakedefine ENABLE_QT
// Define to enable the spi-device // Define to enable the spi-device
#cmakedefine ENABLE_SPIDEV #cmakedefine ENABLE_SPIDEV
@ -42,5 +45,3 @@
#define HYPERION_VERSION "${HYPERION_VERSION_MAJOR}.${HYPERION_VERSION_MINOR}.${HYPERION_VERSION_PATCH}" #define HYPERION_VERSION "${HYPERION_VERSION_MAJOR}.${HYPERION_VERSION_MINOR}.${HYPERION_VERSION_PATCH}"
#define HYPERION_JSON_VERSION "1.0.0" #define HYPERION_JSON_VERSION "1.0.0"

View File

@ -32,7 +32,7 @@ If you need further support please open a topic at the our new forum!
[Hyperion webpage/forum](https://www.hyperion-project.org). [Hyperion webpage/forum](https://www.hyperion-project.org).
## Requirements ## Requirements
* Debian 8, Ubuntu 14.04 or higher. Windows is not supported currently. * Debian 9, Ubuntu 16.04 or higher. Windows is not supported currently.
## Building ## Building
See [Compilehowto](CompileHowto.md) and [CrossCompileHowto](CrossCompileHowto.txt). See [Compilehowto](CompileHowto.md) and [CrossCompileHowto](CrossCompileHowto.txt).

View File

@ -176,6 +176,9 @@ table label{margin:0}
.checklist{list-style-type:none;padding-left:0px} .checklist{list-style-type:none;padding-left:0px}
.checklist li::before{content: "\f00c";font: normal normal normal 14px/1 FontAwesome;margin-right:5px;color:green;font-size:19px} .checklist li::before{content: "\f00c";font: normal normal normal 14px/1 FontAwesome;margin-right:5px;color:green;font-size:19px}
/* bgwhite */
.bg-w{background-color: white;}
/*Modal icons*/ /*Modal icons*/
[class*="modal-icon"]{ [class*="modal-icon"]{
padding:30px; padding:30px;
@ -993,4 +996,4 @@ input[type="radio"] .styled:checked + label::before {
input[type="checkbox"] .styled:checked + label::after, input[type="checkbox"] .styled:checked + label::after,
input[type="radio"] .styled:checked + label::after { input[type="radio"] .styled:checked + label::after {
color: #fff; color: #fff;
} }

View File

@ -512,7 +512,7 @@
"edt_conf_fw_json_expl": "Jeden z cílů na jeden řádek. Obsahuje IP:PORT (Příklad: 127.0.0.1:19446)", "edt_conf_fw_json_expl": "Jeden z cílů na jeden řádek. Obsahuje IP:PORT (Příklad: 127.0.0.1:19446)",
"edt_conf_fw_json_itemtitle": "Json cíl", "edt_conf_fw_json_itemtitle": "Json cíl",
"edt_conf_fw_proto_title": "Seznam proto klientů", "edt_conf_fw_proto_title": "Seznam proto klientů",
"edt_conf_fw_proto_expl": "Jeden cíl na každý řádek. Obsahuje IP:PORT (Příklad: 127.0.0.1:19447)", "edt_conf_fw_proto_expl": "Jeden cíl na každý řádek. Obsahuje IP:PORT (Příklad: 127.0.0.1:19401)",
"edt_conf_fw_proto_itemtitle": "Proto cíl", "edt_conf_fw_proto_itemtitle": "Proto cíl",
"edt_conf_js_heading_title": "JSON Server", "edt_conf_js_heading_title": "JSON Server",
"edt_conf_ps_heading_title": "PROTO Server", "edt_conf_ps_heading_title": "PROTO Server",
@ -753,4 +753,4 @@
"edt_conf_enum_SECAM": "SECAM", "edt_conf_enum_SECAM": "SECAM",
"general_speech_it": "Italština", "general_speech_it": "Italština",
"general_speech_cs": "Czech" "general_speech_cs": "Czech"
} }

View File

@ -20,6 +20,7 @@
"general_comp_FORWARDER" : "Weiterleitung", "general_comp_FORWARDER" : "Weiterleitung",
"general_comp_UDPLISTENER" : "UDP Listener", "general_comp_UDPLISTENER" : "UDP Listener",
"general_comp_BOBLIGHTSERVER" : "Boblight Server", "general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
"general_comp_GRABBER" : "Plattform Aufnahme", "general_comp_GRABBER" : "Plattform Aufnahme",
"general_comp_V4L" : "USB Aufnahme", "general_comp_V4L" : "USB Aufnahme",
"general_comp_LEDDEVICE" : "LED Hardware", "general_comp_LEDDEVICE" : "LED Hardware",
@ -27,6 +28,7 @@
"general_col_green" : "grün", "general_col_green" : "grün",
"general_col_blue" : "blau", "general_col_blue" : "blau",
"general_button_savesettings" : "Einstellungen speichern", "general_button_savesettings" : "Einstellungen speichern",
"general_btn_yes" : "Ja",
"general_btn_ok" : "OK", "general_btn_ok" : "OK",
"general_btn_cancel" : "Abbrechen", "general_btn_cancel" : "Abbrechen",
"general_btn_continue" : "Fortfahren", "general_btn_continue" : "Fortfahren",
@ -46,7 +48,7 @@
"dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:", "dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:",
"dashboard_infobox_label_platform" : "Plattform:", "dashboard_infobox_label_platform" : "Plattform:",
"dashboard_infobox_label_instance" : "Instanz:", "dashboard_infobox_label_instance" : "Instanz:",
"dashboard_infobox_label_ports" : "Ports (json|proto):", "dashboard_infobox_label_ports" : "Port flatbuf:",
"dashboard_infobox_message_updatewarning" : "Eine aktuellere Version von Hyperion ist verfügbar! (V$1)", "dashboard_infobox_message_updatewarning" : "Eine aktuellere Version von Hyperion ist verfügbar! (V$1)",
"dashboard_infobox_message_updatesuccess" : "Du nutzt die aktuellste Version von Hyperion.", "dashboard_infobox_message_updatesuccess" : "Du nutzt die aktuellste Version von Hyperion.",
"dashboard_infobox_label_statush" : "Hyperion Status:", "dashboard_infobox_label_statush" : "Hyperion Status:",
@ -162,9 +164,9 @@
"conf_colors_smoothing_intro" : "Glätte den Farbverlauf und Helligkeitsänderungen um nicht von schnellen Übergängen abgelenkt zu werden.", "conf_colors_smoothing_intro" : "Glätte den Farbverlauf und Helligkeitsänderungen um nicht von schnellen Übergängen abgelenkt zu werden.",
"conf_colors_blackborder_intro" : "Ignoriere schwarze Balken, jeder Modus nutzt einen anderen Algorithmus um diese zu erkennen. Erhöhe die Schwelle, sollte es nicht funktionieren.", "conf_colors_blackborder_intro" : "Ignoriere schwarze Balken, jeder Modus nutzt einen anderen Algorithmus um diese zu erkennen. Erhöhe die Schwelle, sollte es nicht funktionieren.",
"conf_network_json_intro" : "Der JSON-RPC-Port dieser Hyperion-Instanz, wird genutzt zur Fernsteuerung.", "conf_network_json_intro" : "Der JSON-RPC-Port dieser Hyperion-Instanz, wird genutzt zur Fernsteuerung.",
"conf_network_proto_intro" : "Der PROTO-Port dieser Hyperion-Instanz, wird genutzt für \"Bildstreams\" (HyperionScreenCap, Kodi Adddon, ...)",
"conf_network_bobl_intro" : "Boblight Empfänger", "conf_network_bobl_intro" : "Boblight Empfänger",
"conf_network_udpl_intro" : "UDP Empfänger", "conf_network_udpl_intro" : "UDP Empfänger",
"conf_network_fbs_intro" : "Google Flatbuffers Empfänger. Wird genutzt für schnellen Bildempfang.",
"conf_network_forw_intro" : "Leite alles an eine zweite Hyperion Instanz weiter, diese kann dann mit einer anderen LED Steuerung genutzt werden", "conf_network_forw_intro" : "Leite alles an eine zweite Hyperion Instanz weiter, diese kann dann mit einer anderen LED Steuerung genutzt werden",
"conf_logging_label_intro" : "Überprüfe die Meldungen im Prokotoll um zu erfahren was Hyperion gerade beschäftigt. Je nach eingestellter Protokoll-Stufe siehst du mehr oder weniger Informationen.", "conf_logging_label_intro" : "Überprüfe die Meldungen im Prokotoll um zu erfahren was Hyperion gerade beschäftigt. Je nach eingestellter Protokoll-Stufe siehst du mehr oder weniger Informationen.",
"conf_logging_btn_pbupload" : "Bericht für Supportanfrage hochladen", "conf_logging_btn_pbupload" : "Bericht für Supportanfrage hochladen",
@ -283,6 +285,7 @@
"InfoDialog_nowrite_text" : "Hyperion hat keinen Schreibzugriff auf die aktuell geladene Konfiguration. Bitte korrigiere die Dateizugriffsrechte um fortzufahren.", "InfoDialog_nowrite_text" : "Hyperion hat keinen Schreibzugriff auf die aktuell geladene Konfiguration. Bitte korrigiere die Dateizugriffsrechte um fortzufahren.",
"InfoDialog_nowrite_foottext" : "Die Webkonfiguration wird automatisch wieder freigegeben, sobald das Problem behoben wurde!", "InfoDialog_nowrite_foottext" : "Die Webkonfiguration wird automatisch wieder freigegeben, sobald das Problem behoben wurde!",
"infoDialog_wizrgb_text" : "Deine RGB Byte Reihenfolge ist bereits richtig eingestellt.", "infoDialog_wizrgb_text" : "Deine RGB Byte Reihenfolge ist bereits richtig eingestellt.",
"infoDialog_writeimage_error_text": "Die ausgewählte Datei \"$1\" ist keine Bilddatei oder ist beschädigt! Bitte wähle eine andere Bilddatei aus.",
"infoDialog_writeconf_error_text" : "Das speichern der Konfiguration ist fehlgeschlagen.", "infoDialog_writeconf_error_text" : "Das speichern der Konfiguration ist fehlgeschlagen.",
"infoDialog_import_jsonerror_text" : "Die ausgewählte Konfigurations-Datei \"$1\" ist keine .json Datei oder ist beschädigt! Fehlermeldung: ($2)", "infoDialog_import_jsonerror_text" : "Die ausgewählte Konfigurations-Datei \"$1\" ist keine .json Datei oder ist beschädigt! Fehlermeldung: ($2)",
"infoDialog_import_hyperror_text" : "Die ausgewählte Konfigurations-Datei \"$1\" kann nicht importiert werden. Sie ist nicht kompatibel mit Hyperion 2.0 und höher!", "infoDialog_import_hyperror_text" : "Die ausgewählte Konfigurations-Datei \"$1\" kann nicht importiert werden. Sie ist nicht kompatibel mit Hyperion 2.0 und höher!",
@ -341,11 +344,12 @@
"wiz_cc_morethanone" : "Du hast mehr als 1 Profil, bitte wähle das zu kalibrierende Profil", "wiz_cc_morethanone" : "Du hast mehr als 1 Profil, bitte wähle das zu kalibrierende Profil",
"wiz_cc_btn_stop" : "Stoppe Video", "wiz_cc_btn_stop" : "Stoppe Video",
"wiz_cc_summary" : "Im folgenden eine Zusammenfassung deiner Einstellungen. Während du ein Video abspielst, kannst du hier weiter ausprobieren. Wenn du fertig bist, klicke auf speichern.", "wiz_cc_summary" : "Im folgenden eine Zusammenfassung deiner Einstellungen. Während du ein Video abspielst, kannst du hier weiter ausprobieren. Wenn du fertig bist, klicke auf speichern.",
"edt_dev_auth_key_title" : "Aurora API Schlüssel",
"edt_dev_enum_subtract_minimum" : "Subtrahiere minimum", "edt_dev_enum_subtract_minimum" : "Subtrahiere minimum",
"edt_dev_enum_sub_min_warm_adjust" : "Minimale Anpassung: warm", "edt_dev_enum_sub_min_warm_adjust" : "Minimale Anpassung: warm",
"edt_dev_enum_white_off" : "Weiß ist aus", "edt_dev_enum_white_off" : "Weiß ist aus",
"edt_dev_general_heading_title" : "Allgemeine Einstellungen", "edt_dev_general_heading_title" : "Allgemeine Einstellungen",
"edt_dev_general_ledCount_title" : "Anzahl Hardware LEDs", "edt_dev_general_hardwareLedCount_title" : "Anzahl Hardware LEDs",
"edt_dev_general_colorOrder_title" : "RGB Byte Reihenfolge", "edt_dev_general_colorOrder_title" : "RGB Byte Reihenfolge",
"edt_dev_general_rewriteTime_title" : "Aktualisierungszeit", "edt_dev_general_rewriteTime_title" : "Aktualisierungszeit",
"edt_dev_spec_header_title" : "Spezifische Einstellungen", "edt_dev_spec_header_title" : "Spezifische Einstellungen",
@ -415,6 +419,7 @@
"edt_conf_enum_PAL" : "PAL", "edt_conf_enum_PAL" : "PAL",
"edt_conf_enum_NTSC" : "NTSC", "edt_conf_enum_NTSC" : "NTSC",
"edt_conf_enum_SECAM" : "SECAM", "edt_conf_enum_SECAM" : "SECAM",
"edt_conf_enum_NO_CHANGE" : "Auto",
"edt_conf_enum_logsilent" : "Stille", "edt_conf_enum_logsilent" : "Stille",
"edt_conf_enum_logwarn" : "Warnung", "edt_conf_enum_logwarn" : "Warnung",
"edt_conf_enum_logverbose" : "Ausführlich", "edt_conf_enum_logverbose" : "Ausführlich",
@ -480,19 +485,11 @@
"edt_conf_smooth_continuousOutput_expl" : "Aktualisiere die LEDs, auch wenn das Bild sich nicht geändert hat.", "edt_conf_smooth_continuousOutput_expl" : "Aktualisiere die LEDs, auch wenn das Bild sich nicht geändert hat.",
"edt_conf_v4l2_heading_title" : "USB Aufnahme", "edt_conf_v4l2_heading_title" : "USB Aufnahme",
"edt_conf_v4l2_device_title" : "Gerät", "edt_conf_v4l2_device_title" : "Gerät",
"edt_conf_v4l2_device_expl" : "Der Pfad zum USB Aufnahmegerät.", "edt_conf_v4l2_device_expl" : "Der Pfad zum USB (v4l) Aufnahmegerät. Wähle 'auto' für automatische Erkennung. Beispiel: '/dev/video0'",
"edt_conf_v4l2_input_title" : "Eingang",
"edt_conf_v4l2_input_expl" : "Der Eingang des Pfades.",
"edt_conf_v4l2_standard_title" : "Videoformat", "edt_conf_v4l2_standard_title" : "Videoformat",
"edt_conf_v4l2_standard_expl" : "Wähle das passende Videoformat deiner Region.", "edt_conf_v4l2_standard_expl" : "Wähle das passende Videoformat deiner Region. Auf 'Auto' wird der gewählte Modus vom v4l interface beibehalten.",
"edt_conf_v4l2_width_title" : "Breite", "edt_conf_v4l2_sizeDecimation_title" : "Bildverkleinerung Faktor",
"edt_conf_v4l2_width_expl" : "Die Breite des Bildes. (-1 = Automatische Breitenbestimmung)", "edt_conf_v4l2_sizeDecimation_expl" : "Der Faktor der Bildverkleinerung ausgehend von der ursprünglichen Größe, 1 bedeutet keine Änderung (originales Bild).",
"edt_conf_v4l2_height_title" : "Höhe",
"edt_conf_v4l2_height_expl" : "Die Höhes des Bildes. (-1 = Automatische Höhenbestimmung)",
"edt_conf_v4l2_frameDecimation_title" : "Bildverkleinerung",
"edt_conf_v4l2_frameDecimation_expl" : "Der Faktor der Bildverkleinerung",
"edt_conf_v4l2_sizeDecimation_title" : "Größenänderung",
"edt_conf_v4l2_sizeDecimation_expl" : "Der Faktor der Größenänderung",
"edt_conf_v4l2_cropLeft_title" : "Entferne links", "edt_conf_v4l2_cropLeft_title" : "Entferne links",
"edt_conf_v4l2_cropLeft_expl" : "Anzahl der Pixel auf der linken Seite die vom Bild entfernt werden.", "edt_conf_v4l2_cropLeft_expl" : "Anzahl der Pixel auf der linken Seite die vom Bild entfernt werden.",
"edt_conf_v4l2_cropRight_title" : "Entferne rechts", "edt_conf_v4l2_cropRight_title" : "Entferne rechts",
@ -502,7 +499,7 @@
"edt_conf_v4l2_cropBottom_title" : "Entferne unten", "edt_conf_v4l2_cropBottom_title" : "Entferne unten",
"edt_conf_v4l2_cropBottom_expl" : "Anzahl der Pixel auf der unteren Seite die vom Bild entfernt werden.", "edt_conf_v4l2_cropBottom_expl" : "Anzahl der Pixel auf der unteren Seite die vom Bild entfernt werden.",
"edt_conf_v4l2_signalDetection_title" : "Signal Erkennung", "edt_conf_v4l2_signalDetection_title" : "Signal Erkennung",
"edt_conf_v4l2_signalDetection_expl" : "Wenn aktiviert, wird die USB Aufnahme temporär bei \"kein Signal\" abgeschalten.", "edt_conf_v4l2_signalDetection_expl" : "Wenn aktiviert, wird die USB Aufnahme temporär bei \"kein Signal\" abgeschalten. Das Bild muss dazu 4 Sekunden lang unter die Schwellwerte fallen.",
"edt_conf_v4l2_redSignalThreshold_title" : "Rote Signalschwelle", "edt_conf_v4l2_redSignalThreshold_title" : "Rote Signalschwelle",
"edt_conf_v4l2_redSignalThreshold_expl" : "Je höher die rote Schwelle je eher wird abgeschalten bei entsprechendem rot-Anteil.", "edt_conf_v4l2_redSignalThreshold_expl" : "Je höher die rote Schwelle je eher wird abgeschalten bei entsprechendem rot-Anteil.",
"edt_conf_v4l2_greenSignalThreshold_title" : "Grüne Signalschwelle", "edt_conf_v4l2_greenSignalThreshold_title" : "Grüne Signalschwelle",
@ -517,21 +514,22 @@
"edt_conf_v4l2_sDVOffsetMax_expl" : "Signal Erkennungs-Bereich vertikal maximum (0.0-1.0)", "edt_conf_v4l2_sDVOffsetMax_expl" : "Signal Erkennungs-Bereich vertikal maximum (0.0-1.0)",
"edt_conf_v4l2_sDHOffsetMax_title" : "Signal Erkennung HMax", "edt_conf_v4l2_sDHOffsetMax_title" : "Signal Erkennung HMax",
"edt_conf_v4l2_sDHOffsetMax_expl" : "Signal Erkennungs-Bereich horizontal maximum (0.0-1.0)", "edt_conf_v4l2_sDHOffsetMax_expl" : "Signal Erkennungs-Bereich horizontal maximum (0.0-1.0)",
"edt_conf_instCapture_heading_title" : "Instance Aufnahme",
"edt_conf_instC_systemEnable_title" : "Aktiviere Plattform Aufnahme",
"edt_conf_instC_systemEnable_expl" : "Aktiviert die Plattform Aufnahme für diese LED Hardware Instanz",
"edt_conf_instC_v4lEnable_title" : "Aktiviere USB Aufnahme",
"edt_conf_instC_v4lEnable_expl" : "Aktiviert die USB Aufnahme für diese LED Hardware Instanz",
"edt_conf_fg_heading_title" : "Plattform Aufnahme", "edt_conf_fg_heading_title" : "Plattform Aufnahme",
"edt_conf_fg_type_title" : "Typ", "edt_conf_fg_type_title" : "Typ",
"edt_conf_fg_type_expl" : "Art der Plattform Aufnahme, standard ist 'auto'", "edt_conf_fg_type_expl" : "Art der Plattform Aufnahme, standard ist 'auto'",
"edt_conf_fg_frequency_Hz_title" : "Aufnahmefrequenz", "edt_conf_fg_frequency_Hz_title" : "Aufnahmefrequenz",
"edt_conf_fg_frequency_Hz_expl" : "Wie schnell neue Bilder aufgenommen werden.", "edt_conf_fg_frequency_Hz_expl" : "Wie schnell neue Bilder aufgenommen werden.",
"edt_conf_fg_horizontalPixelDecimation_title" : "Horizontale Pixelreduzierung",
"edt_conf_fg_horizontalPixelDecimation_expl" : "Horizontale Pixelreduzierung (Faktor)",
"edt_conf_fg_useXGetImage_title" : "Nutze XGetImage",
"edt_conf_fg_useXGetImage_expl" : "XGetImage für aktuelle X11 desktops",
"edt_conf_fg_width_title" : "Breite", "edt_conf_fg_width_title" : "Breite",
"edt_conf_fg_width_expl" : "Verkleinere Bild auf dieser Breite, da das Rohmaterial viel Leistung benötigen würde.", "edt_conf_fg_width_expl" : "Verkleinere Bild auf dieser Breite, da das Rohmaterial viel Leistung benötigen würde.",
"edt_conf_fg_height_title" : "Höhe", "edt_conf_fg_height_title" : "Höhe",
"edt_conf_fg_height_expl" : "Verkleinere Bild auf dieser Höhe, da das Rohmaterial viel Leistung benötigen würde.", "edt_conf_fg_height_expl" : "Verkleinere Bild auf dieser Höhe, da das Rohmaterial viel Leistung benötigen würde.",
"edt_conf_fg_verticalPixelDecimation_title" : "Vertikale Pixelreduzierung", "edt_conf_fg_pixelDecimation_title" : "Bildverkleinerung Faktor",
"edt_conf_fg_verticalPixelDecimation_expl" : "Vertikale Pixelreduzierung (Faktor)", "edt_conf_fg_pixelDecimation_expl" : "Bildverkleinerung (Faktor) ausgehend von der original Größe. 1 für unveränderte/originale Größe.",
"edt_conf_fg_device_title" : "Device", "edt_conf_fg_device_title" : "Device",
"edt_conf_fg_display_title" : "Display", "edt_conf_fg_display_title" : "Display",
"edt_conf_fg_display_expl" : "Gebe an von welchem Desktop aufgenommen werden soll. (Multi Monitor Setup)", "edt_conf_fg_display_expl" : "Gebe an von welchem Desktop aufgenommen werden soll. (Multi Monitor Setup)",
@ -563,16 +561,18 @@
"edt_conf_fw_json_expl" : "Ein Json Ziel pro Zeile. Bestehend aus IP:PORT (Beispiel: 127.0.0.1:19446)", "edt_conf_fw_json_expl" : "Ein Json Ziel pro Zeile. Bestehend aus IP:PORT (Beispiel: 127.0.0.1:19446)",
"edt_conf_fw_json_itemtitle" : "Json Ziel", "edt_conf_fw_json_itemtitle" : "Json Ziel",
"edt_conf_fw_proto_title" : "Liste von Proto zielen", "edt_conf_fw_proto_title" : "Liste von Proto zielen",
"edt_conf_fw_proto_expl" : "Ein Proto Ziel pro Zeile. Bestehend aus IP:PORT (Beispiel: 127.0.0.1:19447)", "edt_conf_fw_proto_expl" : "Ein Proto Ziel pro Zeile. Bestehend aus IP:PORT (Beispiel: 127.0.0.1:19401)",
"edt_conf_fw_proto_itemtitle" : "Proto Ziel", "edt_conf_fw_proto_itemtitle" : "Proto Ziel",
"edt_conf_js_heading_title" : "JSON Server", "edt_conf_js_heading_title" : "JSON Server",
"edt_conf_ps_heading_title" : "PROTO Server", "edt_conf_fbs_heading_title" : "Flatbuffers Server",
"edt_conf_fbs_timeout_title" : "Zeitüberschreitung",
"edt_conf_fbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
"edt_conf_bobls_heading_title" : "Boblight Server", "edt_conf_bobls_heading_title" : "Boblight Server",
"edt_conf_udpl_heading_title" : "UDP Listener", "edt_conf_udpl_heading_title" : "UDP Listener",
"edt_conf_udpl_address_title" : "Adresse", "edt_conf_udpl_address_title" : "Adresse",
"edt_conf_udpl_address_expl" : "Die Adresse auf der UDP Pakete akzeptiert werden.", "edt_conf_udpl_address_expl" : "Die Adresse auf der UDP Pakete akzeptiert werden.",
"edt_conf_udpl_timeout_title" : "Zeitüberschreitung", "edt_conf_udpl_timeout_title" : "Zeitüberschreitung",
"edt_conf_udpl_timeout_expl" : "Wenn für die angegeben Zeit keine UDP Pakete empfangen werden, wird die Komponente (vorübergehend) deaktiviert", "edt_conf_udpl_timeout_expl" : "Wenn für die angegebene Zeit keine UDP Pakete empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
"edt_conf_udpl_shared_title" : "Gemeinsam genutzt", "edt_conf_udpl_shared_title" : "Gemeinsam genutzt",
"edt_conf_udpl_shared_expl" : "Wird gemeinsam über alle Hyperion Instanzen genutzt.", "edt_conf_udpl_shared_expl" : "Wird gemeinsam über alle Hyperion Instanzen genutzt.",
"edt_conf_webc_heading_title" : "Web Konfiguration", "edt_conf_webc_heading_title" : "Web Konfiguration",
@ -593,9 +593,14 @@
"edt_eff_smooth_updateFrequency" : "Glättung: Aktualisierungsfrequenz", "edt_eff_smooth_updateFrequency" : "Glättung: Aktualisierungsfrequenz",
"edt_eff_candle_header" : "Kerze", "edt_eff_candle_header" : "Kerze",
"edt_eff_candle_header_desc" : "Flackerndes Kerzenlicht", "edt_eff_candle_header_desc" : "Flackerndes Kerzenlicht",
"edt_eff_waves_header" : "Wellen",
"edt_eff_waves_header_desc" : "Gestalte Wellen aus Farbe! Mische dazu deine lieblings Farben und wähle einen Mittelpunkt.",
"edt_eff_gif_header" : "GIF's",
"edt_eff_gif_header_desc" : "Dieser Effekt spielt .gif Dateien ab. Bietet die Möglichkeit kleine GIF-Videos abzuspielen.",
"edt_eff_police_header" : "Polizei", "edt_eff_police_header" : "Polizei",
"edt_eff_police_header_desc" : "Lights like a police car in action", "edt_eff_police_header_desc" : "Lights like a police car in action",
"edt_eff_fade_header" : "Farbübergang", "edt_eff_fade_header" : "Farbübergang",
"edt_eff_fade_header_desc" : "Farbübergange für alle LED's",
"edt_eff_rainbowmood_header" : "Regenbogen", "edt_eff_rainbowmood_header" : "Regenbogen",
"edt_eff_rainbowmood_header_desc" : "Alle LEDs Regenbogen Farbübergang", "edt_eff_rainbowmood_header_desc" : "Alle LEDs Regenbogen Farbübergang",
"edt_eff_knightrider_header" : "Knight Rider", "edt_eff_knightrider_header" : "Knight Rider",
@ -603,18 +608,24 @@
"edt_eff_lightclock_header" : "Lichtuhr", "edt_eff_lightclock_header" : "Lichtuhr",
"edt_eff_lightclock_header_desc" : "Eine echte Uhr als Licht! Passe die Farben von Stunden, Minuten, Sekunden deinen Vorstellungen an. Optional können 3/6/9/12 Uhr Markierungen aktiviert werden. Sollte die Uhr eine falsche Zeit anzeigen, überprüfe die Uhrzeit deines Systems.", "edt_eff_lightclock_header_desc" : "Eine echte Uhr als Licht! Passe die Farben von Stunden, Minuten, Sekunden deinen Vorstellungen an. Optional können 3/6/9/12 Uhr Markierungen aktiviert werden. Sollte die Uhr eine falsche Zeit anzeigen, überprüfe die Uhrzeit deines Systems.",
"edt_eff_pacman_header" : "Pac-Man", "edt_eff_pacman_header" : "Pac-Man",
"edt_eff_pacman_header_desc" : "Klein gefräßig und gelb, wer wird überleben?",
"edt_eff_moodblobs_header" : "Stimmungskugeln", "edt_eff_moodblobs_header" : "Stimmungskugeln",
"edt_eff_moodblobs_header_desc" : "Entspannt den Abend beginnen mit langsam bewegenden Farbkugeln die ebenso sanft ihre Farbe verändern.",
"edt_eff_swirl_header" : "Farbwirbel", "edt_eff_swirl_header" : "Farbwirbel",
"edt_eff_swirl_header_desc" : "Ein Wirbel mit frei wählbaren Farben. Die Farben werden gleichmäßig auf 360° aufgeteilt, dazwischen werden Farbübergänge berechnet. Zusätzlich kann ein zweiter Wirbel über den Ersten gelegt werden (Transparenz beachten!). Tipp: Eine Widerholung der selben Farbe erhöht deren \"größe\" und verringert den Bereich des Farbübergangs zu benachbarten Farben.", "edt_eff_swirl_header_desc" : "Ein Wirbel mit frei wählbaren Farben. Die Farben werden gleichmäßig auf 360° aufgeteilt, dazwischen werden Farbübergänge berechnet. Zusätzlich kann ein zweiter Wirbel über den Ersten gelegt werden (Transparenz beachten!). Tipp: Eine Widerholung der selben Farbe erhöht deren \"größe\" und verringert den Bereich des Farbübergangs zu benachbarten Farben.",
"edt_eff_random_header" : "Zufällig", "edt_eff_random_header" : "Zufällig",
"edt_eff_runningdots_header" : "Rennende Punkte", "edt_eff_random_header_desc" : "Pixel-Farb-Mix",
"edt_eff_systemshutdown_header" : "Herunterfahren", "edt_eff_systemshutdown_header" : "Herunterfahren",
"edt_eff_systemshutdown_header_desc" : "Eine kurze Animation gefolgt von einem möglicherweise echten Herunterfahren des Systems",
"edt_eff_snake_header" : "Schlange", "edt_eff_snake_header" : "Schlange",
"edt_eff_snake_header_desc" : "Wo ist das Futter?",
"edt_eff_sparks_header" : "Funken", "edt_eff_sparks_header" : "Funken",
"edt_eff_sparks_header_desc" : "Ein Sternenfunkeln, wahlweise in festgelegter Farbe oder zufällig. Passe Helligkeit, Sättigung und Geschwindigkeit an.", "edt_eff_sparks_header_desc" : "Ein Sternenfunkeln, wahlweise in festgelegter Farbe oder zufällig. Passe Helligkeit, Sättigung und Geschwindigkeit an.",
"edt_eff_traces_header" : "Farbspuren", "edt_eff_traces_header" : "Farbspuren",
"edt_eff_x-mas_header" : "Weihnachten", "edt_eff_x-mas_header" : "Weihnachten",
"edt_eff_trails_header" : "Spuren", "edt_eff_x-mas_header_desc" : "Ein Hauch von Weihnachten",
"edt_eff_trails_header" : "Sternschnuppen",
"edt_eff_trails_header_desc" : "In verschiedenen Farben, wünsch dir was!",
"edt_eff_flag_header" : "Flaggen", "edt_eff_flag_header" : "Flaggen",
"edt_eff_flag_header_desc" : "Verpasse deinen LEDs die Farben deines Landes. Du kannst mehr als eine Flagge auswählen, je nach Intervall werden diese dann abwechselnd angezeigt.", "edt_eff_flag_header_desc" : "Verpasse deinen LEDs die Farben deines Landes. Du kannst mehr als eine Flagge auswählen, je nach Intervall werden diese dann abwechselnd angezeigt.",
"edt_eff_enum_all" : "Alle", "edt_eff_enum_all" : "Alle",
@ -679,6 +690,7 @@
"edt_eff_customColor" : "Benutzerdefinierte Farbe", "edt_eff_customColor" : "Benutzerdefinierte Farbe",
"edt_eff_randomCenter" : "Zufälliger Mittelpunkt", "edt_eff_randomCenter" : "Zufälliger Mittelpunkt",
"edt_eff_enableSecondSwirl":"Zweiter Wirbel", "edt_eff_enableSecondSwirl":"Zweiter Wirbel",
"edt_eff_reverseRandomTime":"Richtungswechsel alle",
"edt_append_ns" : "ns", "edt_append_ns" : "ns",
"edt_append_ms" : "ms", "edt_append_ms" : "ms",
"edt_append_s" : "s", "edt_append_s" : "s",

View File

@ -20,6 +20,7 @@
"general_comp_FORWARDER" : "Forwarder", "general_comp_FORWARDER" : "Forwarder",
"general_comp_UDPLISTENER" : "UDP Listener", "general_comp_UDPLISTENER" : "UDP Listener",
"general_comp_BOBLIGHTSERVER" : "Boblight Server", "general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
"general_comp_GRABBER" : "Platform Capture", "general_comp_GRABBER" : "Platform Capture",
"general_comp_V4L" : "USB Capture", "general_comp_V4L" : "USB Capture",
"general_comp_LEDDEVICE" : "LED device", "general_comp_LEDDEVICE" : "LED device",
@ -27,6 +28,7 @@
"general_col_green" : "green", "general_col_green" : "green",
"general_col_blue" : "blue", "general_col_blue" : "blue",
"general_button_savesettings" : "Save settings", "general_button_savesettings" : "Save settings",
"general_btn_yes" : "Yes",
"general_btn_ok" : "OK", "general_btn_ok" : "OK",
"general_btn_cancel" : "Cancel", "general_btn_cancel" : "Cancel",
"general_btn_continue" : "Continue", "general_btn_continue" : "Continue",
@ -46,7 +48,7 @@
"dashboard_infobox_label_latesthyp" : "Latest Hyperion version:", "dashboard_infobox_label_latesthyp" : "Latest Hyperion version:",
"dashboard_infobox_label_platform" : "Platform:", "dashboard_infobox_label_platform" : "Platform:",
"dashboard_infobox_label_instance" : "Instance:", "dashboard_infobox_label_instance" : "Instance:",
"dashboard_infobox_label_ports" : "Ports (json|proto):", "dashboard_infobox_label_ports" : "Port flatbuf:",
"dashboard_infobox_message_updatewarning" : "A newer version of Hyperion is available! ($1)", "dashboard_infobox_message_updatewarning" : "A newer version of Hyperion is available! ($1)",
"dashboard_infobox_message_updatesuccess" : "You run the latest version of Hyperion.", "dashboard_infobox_message_updatesuccess" : "You run the latest version of Hyperion.",
"dashboard_infobox_label_statush" : "Hyperion status:", "dashboard_infobox_label_statush" : "Hyperion status:",
@ -162,9 +164,9 @@
"conf_colors_smoothing_intro" : "Smoothing flattens color/brightness changes to reduce annoying distraction.", "conf_colors_smoothing_intro" : "Smoothing flattens color/brightness changes to reduce annoying distraction.",
"conf_colors_blackborder_intro" : "Skip black bars wherever they are. Each mode use another detection algorithm which is tuned for special situations. Higher the threshold if it doesn't work for you.", "conf_colors_blackborder_intro" : "Skip black bars wherever they are. Each mode use another detection algorithm which is tuned for special situations. Higher the threshold if it doesn't work for you.",
"conf_network_json_intro" : "The JSON-RPC-Port of this Hyperion instance, used for remote control.", "conf_network_json_intro" : "The JSON-RPC-Port of this Hyperion instance, used for remote control.",
"conf_network_proto_intro" : "The PROTO-Port of this Hyperion instance, used for picture streams (HyperionScreenCap, Kodi Adddon, ...)",
"conf_network_bobl_intro" : "Receiver for Boblight", "conf_network_bobl_intro" : "Receiver for Boblight",
"conf_network_udpl_intro" : "Receiver for UDP", "conf_network_udpl_intro" : "Receiver for UDP",
"conf_network_fbs_intro" : "Google Flatbuffers Receiver. Used for fast image transmission.",
"conf_network_forw_intro" : "Forward all input to a second Hyperion instance which could be driven with another led controller", "conf_network_forw_intro" : "Forward all input to a second Hyperion instance which could be driven with another led controller",
"conf_logging_label_intro" : "Area to check log messages, depending on loglevel setting you see more or less information.", "conf_logging_label_intro" : "Area to check log messages, depending on loglevel setting you see more or less information.",
"conf_logging_btn_pbupload" : "Upload report for support request", "conf_logging_btn_pbupload" : "Upload report for support request",
@ -283,6 +285,7 @@
"InfoDialog_nowrite_text" : "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.", "InfoDialog_nowrite_text" : "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.",
"InfoDialog_nowrite_foottext" : "The WebUI will be unlocked automatically after you solved the problem!", "InfoDialog_nowrite_foottext" : "The WebUI will be unlocked automatically after you solved the problem!",
"infoDialog_wizrgb_text" : "Your RGB Byte Order is already well adjusted.", "infoDialog_wizrgb_text" : "Your RGB Byte Order is already well adjusted.",
"infoDialog_writeimage_error_text": "The selected file \"$1\" is no image file or it's corrupted! Please select another image file.",
"infoDialog_writeconf_error_text" : "Saving your configuration failed.", "infoDialog_writeconf_error_text" : "Saving your configuration failed.",
"infoDialog_import_jsonerror_text" : "The selected configuration file \"$1\" is no .json file or it's corrupted. Error message: ($2)", "infoDialog_import_jsonerror_text" : "The selected configuration file \"$1\" is no .json file or it's corrupted. Error message: ($2)",
"infoDialog_import_hyperror_text" : "The selected configuration file \"$1\" can't be imported. It's not compatible with Hyperion 2.0 and higher!", "infoDialog_import_hyperror_text" : "The selected configuration file \"$1\" can't be imported. It's not compatible with Hyperion 2.0 and higher!",
@ -341,12 +344,13 @@
"wiz_cc_morethanone" : "You have more than one profile, please choose the profile you want to calibrate.", "wiz_cc_morethanone" : "You have more than one profile, please choose the profile you want to calibrate.",
"wiz_cc_btn_stop" : "Stop video", "wiz_cc_btn_stop" : "Stop video",
"wiz_cc_summary" : "A conclusion of your settings. During video playback, you could change or test values again. If you are done, click on save.", "wiz_cc_summary" : "A conclusion of your settings. During video playback, you could change or test values again. If you are done, click on save.",
"edt_dev_auth_key_title" : "Aurora API Key",
"edt_dev_enum_subtract_minimum" : "Substract minimum", "edt_dev_enum_subtract_minimum" : "Substract minimum",
"edt_dev_enum_sub_min_warm_adjust" : "Min warm adjust", "edt_dev_enum_sub_min_warm_adjust" : "Min warm adjust",
"edt_dev_enum_white_off" : "White off", "edt_dev_enum_white_off" : "White off",
"edt_dev_general_heading_title" : "General Settings", "edt_dev_general_heading_title" : "General Settings",
"edt_dev_general_name_title" : "Configuration name", "edt_dev_general_name_title" : "Configuration name",
"edt_dev_general_ledCount_title" : "Count of all hardware LEDs", "edt_dev_general_hardwareLedCount_title" : "Hardware LED count",
"edt_dev_general_colorOrder_title" : "RGB byte order", "edt_dev_general_colorOrder_title" : "RGB byte order",
"edt_dev_general_rewriteTime_title" : "Refresh time", "edt_dev_general_rewriteTime_title" : "Refresh time",
"edt_dev_spec_header_title" : "Specific Settings", "edt_dev_spec_header_title" : "Specific Settings",
@ -416,6 +420,7 @@
"edt_conf_enum_PAL" : "PAL", "edt_conf_enum_PAL" : "PAL",
"edt_conf_enum_NTSC" : "NTSC", "edt_conf_enum_NTSC" : "NTSC",
"edt_conf_enum_SECAM" : "SECAM", "edt_conf_enum_SECAM" : "SECAM",
"edt_conf_enum_NO_CHANGE" : "Auto",
"edt_conf_enum_logsilent" : "Silent", "edt_conf_enum_logsilent" : "Silent",
"edt_conf_enum_logwarn" : "Warning", "edt_conf_enum_logwarn" : "Warning",
"edt_conf_enum_logverbose" : "Verbose", "edt_conf_enum_logverbose" : "Verbose",
@ -481,19 +486,11 @@
"edt_conf_smooth_continuousOutput_expl" : "Update the leds even there is no changed picture.", "edt_conf_smooth_continuousOutput_expl" : "Update the leds even there is no changed picture.",
"edt_conf_v4l2_heading_title" : "USB Capture", "edt_conf_v4l2_heading_title" : "USB Capture",
"edt_conf_v4l2_device_title" : "Device", "edt_conf_v4l2_device_title" : "Device",
"edt_conf_v4l2_device_expl" : "The path to the usb capture.", "edt_conf_v4l2_device_expl" : "The path to the usb capture interface. Set to 'auto' for auto detection. Example: '/dev/video0'",
"edt_conf_v4l2_input_title" : "Input",
"edt_conf_v4l2_input_expl" : "Input of this path.",
"edt_conf_v4l2_standard_title" : "Video standard", "edt_conf_v4l2_standard_title" : "Video standard",
"edt_conf_v4l2_standard_expl" : "Select the video standard for your region.", "edt_conf_v4l2_standard_expl" : "Select the video standard for your region. 'Auto' keeps the chosen one from v4l interface",
"edt_conf_v4l2_width_title" : "Width",
"edt_conf_v4l2_width_expl" : "The width of the picture. (-1 = auto width)",
"edt_conf_v4l2_height_title" : "Height",
"edt_conf_v4l2_height_expl" : "The height of the picture. (-1 = auto height)",
"edt_conf_v4l2_frameDecimation_title" : "Frame decimation",
"edt_conf_v4l2_frameDecimation_expl" : "The factor of frame decimation",
"edt_conf_v4l2_sizeDecimation_title" : "Size decimation", "edt_conf_v4l2_sizeDecimation_title" : "Size decimation",
"edt_conf_v4l2_sizeDecimation_expl" : "The factor of size decimation", "edt_conf_v4l2_sizeDecimation_expl" : "The factor of size decimation. 1 means no decimation (keep original size)",
"edt_conf_v4l2_cropLeft_title" : "Crop left", "edt_conf_v4l2_cropLeft_title" : "Crop left",
"edt_conf_v4l2_cropLeft_expl" : "Count of pixels on the left side that are removed from the picture.", "edt_conf_v4l2_cropLeft_expl" : "Count of pixels on the left side that are removed from the picture.",
"edt_conf_v4l2_cropRight_title" : "Crop right", "edt_conf_v4l2_cropRight_title" : "Crop right",
@ -503,7 +500,7 @@
"edt_conf_v4l2_cropBottom_title" : "Crop bottom", "edt_conf_v4l2_cropBottom_title" : "Crop bottom",
"edt_conf_v4l2_cropBottom_expl" : "Count of pixels on the bottom side that are removed from the picture.", "edt_conf_v4l2_cropBottom_expl" : "Count of pixels on the bottom side that are removed from the picture.",
"edt_conf_v4l2_signalDetection_title" : "Signal detection", "edt_conf_v4l2_signalDetection_title" : "Signal detection",
"edt_conf_v4l2_signalDetection_expl" : "If enabled, usb capture will be temporarily disabled when no signal was found.", "edt_conf_v4l2_signalDetection_expl" : "If enabled, usb capture will be temporarily disabled when no signal was found. This will happen when the picture fall below the threshold value for a period of 4 seconds.",
"edt_conf_v4l2_redSignalThreshold_title" : "Red signal threshold", "edt_conf_v4l2_redSignalThreshold_title" : "Red signal threshold",
"edt_conf_v4l2_redSignalThreshold_expl" : "Darkens low red values (recognized as black)", "edt_conf_v4l2_redSignalThreshold_expl" : "Darkens low red values (recognized as black)",
"edt_conf_v4l2_greenSignalThreshold_title" : "Green signal threshold", "edt_conf_v4l2_greenSignalThreshold_title" : "Green signal threshold",
@ -518,21 +515,22 @@
"edt_conf_v4l2_sDVOffsetMax_expl" : "Signal detection area vertical maximum (0.0-1.0)", "edt_conf_v4l2_sDVOffsetMax_expl" : "Signal detection area vertical maximum (0.0-1.0)",
"edt_conf_v4l2_sDHOffsetMax_title" : "Signal Detection HMax", "edt_conf_v4l2_sDHOffsetMax_title" : "Signal Detection HMax",
"edt_conf_v4l2_sDHOffsetMax_expl" : "Signal detection area horizontal maximum (0.0-1.0)", "edt_conf_v4l2_sDHOffsetMax_expl" : "Signal detection area horizontal maximum (0.0-1.0)",
"edt_conf_instCapture_heading_title" : "Instance Capture",
"edt_conf_instC_systemEnable_title" : "Enable platform capture",
"edt_conf_instC_systemEnable_expl" : "Enables the platform capture for this led hardware instance",
"edt_conf_instC_v4lEnable_title" : "Enable USB capture",
"edt_conf_instC_v4lEnable_expl" : "Enables the USB capture for this led hardware instance",
"edt_conf_fg_heading_title" : "Platform Capture", "edt_conf_fg_heading_title" : "Platform Capture",
"edt_conf_fg_type_title" : "Type", "edt_conf_fg_type_title" : "Type",
"edt_conf_fg_type_expl" : "Type of platform capture, default is 'auto'", "edt_conf_fg_type_expl" : "Type of platform capture, default is 'auto'",
"edt_conf_fg_frequency_Hz_title" : "Capture frequency", "edt_conf_fg_frequency_Hz_title" : "Capture frequency",
"edt_conf_fg_frequency_Hz_expl" : "How fast new pictures are captured", "edt_conf_fg_frequency_Hz_expl" : "How fast new pictures are captured",
"edt_conf_fg_horizontalPixelDecimation_title" : "Horizontal pixel decimation",
"edt_conf_fg_horizontalPixelDecimation_expl" : "Horizontal pixel decimation (factor)",
"edt_conf_fg_width_title" : "Width", "edt_conf_fg_width_title" : "Width",
"edt_conf_fg_width_expl" : "Shrink picture to this width, as raw picture needs a lot of cpu time.", "edt_conf_fg_width_expl" : "Shrink picture to this width, as raw picture needs a lot of cpu time.",
"edt_conf_fg_height_title" : "Height", "edt_conf_fg_height_title" : "Height",
"edt_conf_fg_height_expl" : "Shrink picture to this height, as raw picture needs a lot of cpu time.", "edt_conf_fg_height_expl" : "Shrink picture to this height, as raw picture needs a lot of cpu time.",
"edt_conf_fg_useXGetImage_title" : "Use XGetImage", "edt_conf_fg_pixelDecimation_title" : "Picture decimation",
"edt_conf_fg_useXGetImage_expl" : "XGetImage for newer X11 desktops", "edt_conf_fg_pixelDecimation_expl" : "Reduce picture size (factor) based on original size. A factor of 1 means no change",
"edt_conf_fg_verticalPixelDecimation_title" : "Vertical pixel decimation",
"edt_conf_fg_verticalPixelDecimation_expl" : "Vertical pixel decimation (factor)",
"edt_conf_fg_device_title" : "Device", "edt_conf_fg_device_title" : "Device",
"edt_conf_fg_display_title" : "Display", "edt_conf_fg_display_title" : "Display",
"edt_conf_fg_display_expl" : "Select which desktop should be captured (multi monitor setup)", "edt_conf_fg_display_expl" : "Select which desktop should be captured (multi monitor setup)",
@ -564,10 +562,12 @@
"edt_conf_fw_json_expl" : "One json target per line. Contains IP:PORT (Example: 127.0.0.1:19446)", "edt_conf_fw_json_expl" : "One json target per line. Contains IP:PORT (Example: 127.0.0.1:19446)",
"edt_conf_fw_json_itemtitle" : "Json target", "edt_conf_fw_json_itemtitle" : "Json target",
"edt_conf_fw_proto_title" : "List of proto clients", "edt_conf_fw_proto_title" : "List of proto clients",
"edt_conf_fw_proto_expl" : "One proto target per line. Contains IP:PORT (Example: 127.0.0.1:19447)", "edt_conf_fw_proto_expl" : "One proto target per line. Contains IP:PORT (Example: 127.0.0.1:19401)",
"edt_conf_fw_proto_itemtitle" : "Proto target", "edt_conf_fw_proto_itemtitle" : "Proto target",
"edt_conf_js_heading_title" : "JSON Server", "edt_conf_js_heading_title" : "JSON Server",
"edt_conf_ps_heading_title" : "PROTO Server", "edt_conf_fbs_heading_title" : "Flatbuffers Server",
"edt_conf_fbs_timeout_title" : "Timeout",
"edt_conf_fbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.",
"edt_conf_bobls_heading_title" : "Boblight Server", "edt_conf_bobls_heading_title" : "Boblight Server",
"edt_conf_udpl_heading_title" : "UDP Listener", "edt_conf_udpl_heading_title" : "UDP Listener",
"edt_conf_udpl_address_title" : "Address", "edt_conf_udpl_address_title" : "Address",
@ -592,6 +592,10 @@
"edt_eff_smooth_custom" : "Enable smoothing", "edt_eff_smooth_custom" : "Enable smoothing",
"edt_eff_smooth_time_ms" : "Smoothing time", "edt_eff_smooth_time_ms" : "Smoothing time",
"edt_eff_smooth_updateFrequency" : "Smoothing update frequency", "edt_eff_smooth_updateFrequency" : "Smoothing update frequency",
"edt_eff_waves_header" : "Waves",
"edt_eff_waves_header_desc" : "Waves of color! Choose your colors, rotation time, direction reverse and more.",
"edt_eff_gif_header" : "GIF's",
"edt_eff_gif_header_desc" : "This effect plays .gif files, provide a simple video like loop as effect.",
"edt_eff_candle_header" : "Candle", "edt_eff_candle_header" : "Candle",
"edt_eff_candle_header_desc" : "Shimmering candles", "edt_eff_candle_header_desc" : "Shimmering candles",
"edt_eff_police_header" : "Police", "edt_eff_police_header" : "Police",
@ -605,20 +609,27 @@
"edt_eff_lightclock_header" : "Light Clock", "edt_eff_lightclock_header" : "Light Clock",
"edt_eff_lightclock_header_desc" : "A real clock as light! Adjsut the colors of hours, minute, seconds. A optional 3/6/9/12 o'clock marker is also available. In case the clock is wrong, you need to check your system clock.", "edt_eff_lightclock_header_desc" : "A real clock as light! Adjsut the colors of hours, minute, seconds. A optional 3/6/9/12 o'clock marker is also available. In case the clock is wrong, you need to check your system clock.",
"edt_eff_pacman_header" : "Pac-Man", "edt_eff_pacman_header" : "Pac-Man",
"edt_eff_pacman_header_desc" : "Small hungry and yellow. Who will survive?",
"edt_eff_moodblobs_header" : "Mood Blobs", "edt_eff_moodblobs_header" : "Mood Blobs",
"edt_eff_moodblobs_header_desc" : "Relax at the evening with slow moving and color changing blobs.",
"edt_eff_swirl_header" : "Color Swirl", "edt_eff_swirl_header" : "Color Swirl",
"edt_eff_swirl_header_desc" : "A swirl with custom colors. Colors are even spread to 360°, in between colors shifts will be calcualted. Additional you can add a second swirl on top, be aware that you need partly transparency! Hint: A reapeat of the same color results in a \"hugher\" color area and a reduced color shift area.", "edt_eff_swirl_header_desc" : "A swirl with custom colors. Colors are even spread to 360°, in between colors shifts will be calcualted. Additional you can add a second swirl on top, be aware that you need partly transparency! Hint: A reapeat of the same color results in a \"hugher\" color area and a reduced color shift area.",
"edt_eff_random_header" : "Random", "edt_eff_random_header" : "Random",
"edt_eff_runningdots_header" : "Running Dots", "edt_eff_random_header_desc" : "Pixel Dot, dot, dot...",
"edt_eff_systemshutdown_header" : "System Shutdown", "edt_eff_systemshutdown_header" : "System Shutdown",
"edt_eff_systemshutdown_header_desc" : "A short animation with probably a real system shutdown",
"edt_eff_snake_header" : "Snake", "edt_eff_snake_header" : "Snake",
"edt_eff_snake_header_desc" : "Where is something to eat?",
"edt_eff_sparks_header" : "Sparks", "edt_eff_sparks_header" : "Sparks",
"edt_eff_sparks_header_desc" : "Star-Sparking, choose between a static color or random. You could also adjust brightness, staturation and speed.", "edt_eff_sparks_header_desc" : "Star-Sparking, choose between a static color or random. You could also adjust brightness, staturation and speed.",
"edt_eff_traces_header" : "Color Traces", "edt_eff_traces_header" : "Color Traces",
"edt_eff_traces_header_desc" : "Requires redesign",
"edt_eff_x-mas_header" : "X-Mas", "edt_eff_x-mas_header" : "X-Mas",
"edt_eff_trails_header" : "Trails", "edt_eff_x-mas_header_desc" : "Touch of christmas",
"edt_eff_trails_header" : "Falling stars",
"edt_eff_trails_header_desc" : "Colored stars that fall from top to bottom",
"edt_eff_flag_header" : "Flags", "edt_eff_flag_header" : "Flags",
"edt_eff_flag_header_desc" : "Let your leds shine bright in the colors of your country. You could select more then one flag, they will change based on interval time.", "edt_eff_flag_header_desc" : "Let your leds shine bright in the colors of your country. You could select more than one flag, they will change based on interval time.",
"edt_eff_enum_all" : "All", "edt_eff_enum_all" : "All",
"edt_eff_enum_all-together" : "All together", "edt_eff_enum_all-together" : "All together",
"edt_eff_enum_list" : "LED List", "edt_eff_enum_list" : "LED List",
@ -630,6 +641,8 @@
"edt_eff_colorcount" : "Color length", "edt_eff_colorcount" : "Color length",
"edt_eff_rotationtime" : "Rotation time", "edt_eff_rotationtime" : "Rotation time",
"edt_eff_sleeptime" : "Sleep time", "edt_eff_sleeptime" : "Sleep time",
"edt_eff_image" : "Image file",
"edt_eff_fps" : "Frames per seconds",
"edt_eff_reversedirection" : "Reverse direction", "edt_eff_reversedirection" : "Reverse direction",
"edt_eff_fadeintime" : "Fade in time", "edt_eff_fadeintime" : "Fade in time",
"edt_eff_fadeouttime" : "Fade out time", "edt_eff_fadeouttime" : "Fade out time",
@ -681,6 +694,7 @@
"edt_eff_customColor" : "Custom Color", "edt_eff_customColor" : "Custom Color",
"edt_eff_randomCenter" : "Random Center", "edt_eff_randomCenter" : "Random Center",
"edt_eff_enableSecondSwirl":"Second Swirl", "edt_eff_enableSecondSwirl":"Second Swirl",
"edt_eff_reverseRandomTime":"Reverse every",
"edt_append_ns" : "ns", "edt_append_ns" : "ns",
"edt_append_ms" : "ms", "edt_append_ms" : "ms",
"edt_append_s" : "s", "edt_append_s" : "s",

View File

@ -512,7 +512,7 @@
"edt_conf_fw_json_expl": "Una destinazione json per riga. Contiene IP:PORTA:(Esempio: 127.0.0.1:19446)", "edt_conf_fw_json_expl": "Una destinazione json per riga. Contiene IP:PORTA:(Esempio: 127.0.0.1:19446)",
"edt_conf_fw_json_itemtitle": "Destinatario json", "edt_conf_fw_json_itemtitle": "Destinatario json",
"edt_conf_fw_proto_title": "Lista dei client proto", "edt_conf_fw_proto_title": "Lista dei client proto",
"edt_conf_fw_proto_expl": "Una destinazione proto per riga. Contiene IP:PORTA:(Esempio: 127.0.0.1:19447)", "edt_conf_fw_proto_expl": "Una destinazione proto per riga. Contiene IP:PORTA:(Esempio: 127.0.0.1:19401)",
"edt_conf_fw_proto_itemtitle": "Destinatario proto", "edt_conf_fw_proto_itemtitle": "Destinatario proto",
"edt_conf_js_heading_title": "Server JSON", "edt_conf_js_heading_title": "Server JSON",
"edt_conf_ps_heading_title": "Server PROTO", "edt_conf_ps_heading_title": "Server PROTO",
@ -753,4 +753,4 @@
"edt_conf_enum_SECAM": "SECAM", "edt_conf_enum_SECAM": "SECAM",
"general_speech_it": "Italiano", "general_speech_it": "Italiano",
"general_speech_cs": "Czech" "general_speech_cs": "Czech"
} }

View File

@ -1,10 +1,10 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"brindosch" "brindosch, paulchen-panther"
], ],
"project" : "Hyperion WebUI string docu", "project" : "Hyperion WebUI string docu",
"last-updated": "2016-11-30" "last-updated": "2019-01-02"
}, },
"edt_msg_error_notset" : " When a property is not set", "edt_msg_error_notset" : " When a property is not set",
"edt_msg_error_notempty" : "When a string must not be empty", "edt_msg_error_notempty" : "When a string must not be empty",
@ -40,8 +40,14 @@
"edt_msg_button_add_row_title" : "Title on Add Row buttons. $1 = This key takes one variable: The title of object to add", "edt_msg_button_add_row_title" : "Title on Add Row buttons. $1 = This key takes one variable: The title of object to add",
"edt_msg_button_move_down_title" : "Title on Move Down buttons", "edt_msg_button_move_down_title" : "Title on Move Down buttons",
"edt_msg_button_move_up_title" : "Title on Move Up buttons", "edt_msg_button_move_up_title" : "Title on Move Up buttons",
"edt_msg_button_delete_row_titlet" : "Title on Delete Row buttons. $1 = This key takes one variable: The title of object to delete", "edt_msg_button_delete_row_title" : "Title on Delete Row buttons. $1 = This key takes one variable: The title of object to delete",
"edt_msg_button_delete_row_title_short" : "Title on Delete Row buttons, short version (no parameter with the object title)", "edt_msg_button_delete_row_title_short" : "Title on Delete Row buttons, short version (no parameter with the object title)",
"edt_msg_button_collapse" : "Title on Collapse buttons", "edt_msg_button_collapse" : "Title on Collapse buttons",
"edt_msg_button_expand" : "Title on Expand buttons" "edt_msg_button_expand" : "Title on Expand buttons",
} "edt_msg_error_date" : "When a date is in incorrect format. $1 = This key takes one variable: The valid format",
"edt_msg_error_time" : "When a time is in incorrect format. $1 = This key takes one variable: The valid format",
"edt_msg_error_datetime_local" : "When a datetime-local is in incorrect format. $1 = This key takes one variable: The valid format",
"edt_msg_error_invalid_epoch" : "When a integer date is less than 1 January 1970",
"edt_msg_flatpickr_toggle_button" : "Title on Flatpickr toggle buttons",
"edt_msg_flatpickr_clear_button" : "Title on Flatpickr clear buttons"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -31,6 +31,9 @@
<script src="js/lib/bootstrap-colorpicker.min.js"></script> <script src="js/lib/bootstrap-colorpicker.min.js"></script>
<link href="css/bootstrap-colorpicker.min.css" rel="stylesheet"> <link href="css/bootstrap-colorpicker.min.css" rel="stylesheet">
<!-- BS Notfiy -->
<script src="js/lib/bootstrap-notify.min.js"></script>
<!-- JSONEditor --> <!-- JSONEditor -->
<script src="js/lib/jsoneditor.js"></script> <script src="js/lib/jsoneditor.js"></script>
@ -176,7 +179,10 @@
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li> <a class="inactive mnava" href="#conf_webconfig" id="load_webconfig"><i class="fa fa-wrench fa-fw"></i><span data-i18n="main_menu_webconfig_token">Webconfiguration</span></a> </li> <li> <a class="inactive mnava" href="#conf_webconfig" id="load_webconfig"><i class="fa fa-wrench fa-fw"></i><span data-i18n="main_menu_webconfig_token">Webconfiguration</span></a> </li>
<li> <a class="inactive mnava" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li> <li> <a class="inactive mnava" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li>
<li> <a class="inactive mnava" href="#update"><i class="fa fa-download fa-fw"></i><span data-i18n="main_menu_update_token">Update</span></a> </li>
<!-- Update is disabled
<li> <a class="inactive mnava" href="#update"><i class="fa fa-download fa-fw"></i><span data-i18n="main_menu_update_token">Update</span></a> </li>
-->
<li> <a class="inactive mnava" href="#about"><i class="fa fa-info-circle fa-fw"></i><span data-i18n="main_menu_about_token">Update</span></a> </li> <li> <a class="inactive mnava" href="#about"><i class="fa fa-info-circle fa-fw"></i><span data-i18n="main_menu_about_token">Update</span></a> </li>
</ul> </ul>
</li> </li>

View File

@ -1,6 +1,6 @@
$(document).ready( function() { $(document).ready( function() {
performTranslation(); performTranslation();
function newsCont(t,e,l) function newsCont(t,e,l)
{ {
var h = '<div style="padding-left:9px;border-left:6px solid #0088cc;">'; var h = '<div style="padding-left:9px;border-left:6px solid #0088cc;">';
@ -10,7 +10,7 @@ $(document).ready( function() {
h += '</div><hr/>'; h += '</div><hr/>';
$('#dash_news').append(h); $('#dash_news').append(h);
} }
function createNews(d) function createNews(d)
{ {
for(var i = 0; i<d.length; i++) for(var i = 0; i<d.length; i++)
@ -21,11 +21,11 @@ $(document).ready( function() {
title = d[i].title.rendered; title = d[i].title.rendered;
excerpt = d[i].excerpt.rendered; excerpt = d[i].excerpt.rendered;
link = d[i].link+'?pk_campaign=WebUI&pk_kwd=news_'+d[i].slug; link = d[i].link+'?pk_campaign=WebUI&pk_kwd=news_'+d[i].slug;
newsCont(title,excerpt,link); newsCont(title,excerpt,link);
} }
} }
function getNews() function getNews()
{ {
var h = '<span style="color:red;font-weight:bold">'+$.i18n('dashboard_newsbox_noconn')+'</span>'; var h = '<span style="color:red;font-weight:bold">'+$.i18n('dashboard_newsbox_noconn')+'</span>';
@ -45,30 +45,40 @@ $(document).ready( function() {
$('#dash_news').html(h); $('#dash_news').html(h);
}); });
} }
//getNews(); //getNews();
function updateComponents() function updateComponents()
{ {
var components = serverInfo.components; var components = comps;
components_html = ""; components_html = "";
for ( idx=0; idx<components.length;idx++) for ( idx=0; idx<components.length;idx++)
{ {
components_html += '<tr><td>'+$.i18n('general_comp_'+components[idx].name)+'</td><td><i class="fa fa-circle component-'+(components[idx].enabled?"on":"off")+'"></i></td></tr>'; if(components[idx].name != "ALL")
components_html += '<tr><td>'+$.i18n('general_comp_'+components[idx].name)+'</td><td><i class="fa fa-circle component-'+(components[idx].enabled?"on":"off")+'"></i></td></tr>';
} }
$("#tab_components").html(components_html); $("#tab_components").html(components_html);
//info //info
$('#dash_statush').html(serverInfo.hyperion.off? '<span style="color:red">'+$.i18n('general_btn_off')+'</span>':'<span style="color:green">'+$.i18n('general_btn_on')+'</span>'); hyperion_enabled = true;
$('#btn_hsc').html(serverInfo.hyperion.off? '<button class="btn btn-sm btn-success" onClick="requestSetComponentState(\'ALL\',true)">'+$.i18n('dashboard_infobox_label_enableh')+'</button>' : '<button class="btn btn-sm btn-danger" onClick="requestSetComponentState(\'ALL\',false)">'+$.i18n('dashboard_infobox_label_disableh')+'</button>');
components.forEach( function(obj) {
if (obj.name == "ALL")
{
hyperion_enabled = obj.enabled
}
});
$('#dash_statush').html(hyperion_enabled ? '<span style="color:green">'+$.i18n('general_btn_on')+'</span>' : '<span style="color:red">'+$.i18n('general_btn_off')+'</span>');
$('#btn_hsc').html(hyperion_enabled ? '<button class="btn btn-sm btn-danger" onClick="requestSetComponentState(\'ALL\',false)">'+$.i18n('dashboard_infobox_label_disableh')+'</button>' : '<button class="btn btn-sm btn-success" onClick="requestSetComponentState(\'ALL\',true)">'+$.i18n('dashboard_infobox_label_enableh')+'</button>');
} }
// add more info // add more info
$('#dash_leddevice').html(serverInfo.ledDevices.active); $('#dash_leddevice').html(serverInfo.ledDevices.active);
$('#dash_currv').html(currentVersion); $('#dash_currv').html(currentVersion);
$('#dash_instance').html(serverConfig.general.name); $('#dash_instance').html(serverConfig.general.name);
$('#dash_ports').html(jsonPort+' | '+serverConfig.protoServer.port); $('#dash_ports').html(serverConfig.flatbufServer.port);
$.get( "https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/version.json", function( data ) { $.get( "https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/version.json", function( data ) {
parsedUpdateJSON = JSON.parse(data); parsedUpdateJSON = JSON.parse(data);
latestVersion = parsedUpdateJSON[0].versionnr; latestVersion = parsedUpdateJSON[0].versionnr;
@ -76,13 +86,13 @@ $(document).ready( function() {
var cleanCurrentVersion = currentVersion.replace(/\./g, ''); var cleanCurrentVersion = currentVersion.replace(/\./g, '');
// $('#dash_latev').html(latestVersion); // $('#dash_latev').html(latestVersion);
// if ( cleanCurrentVersion < cleanLatestVersion ) // if ( cleanCurrentVersion < cleanLatestVersion )
// $('#versioninforesult').html('<div class="bs-callout bs-callout-warning" style="margin:0px">'+$.i18n('dashboard_infobox_message_updatewarning', latestVersion)+'</div>'); // $('#versioninforesult').html('<div class="bs-callout bs-callout-warning" style="margin:0px">'+$.i18n('dashboard_infobox_message_updatewarning', latestVersion)+'</div>');
// else // else
$('#versioninforesult').html('<div class="bs-callout bs-callout-success" style="margin:0px">'+$.i18n('dashboard_infobox_message_updatesuccess')+'</div>'); $('#versioninforesult').html('<div class="bs-callout bs-callout-success" style="margin:0px">'+$.i18n('dashboard_infobox_message_updatesuccess')+'</div>');
}); });
//determine platform //determine platform
var grabbers = serverInfo.grabbers.available; var grabbers = serverInfo.grabbers.available;
var html = ""; var html = "";
@ -97,16 +107,16 @@ $(document).ready( function() {
html += 'Amlogic'; html += 'Amlogic';
else else
html += 'Framebuffer'; html += 'Framebuffer';
$('#dash_platform').html(html); $('#dash_platform').html(html);
//interval update //interval update
updateComponents(); updateComponents();
$(hyperion).on("cmd-serverinfo",updateComponents); $(hyperion).on("components-updated",updateComponents);
if(showOptHelp) if(showOptHelp)
createHintH("intro", $.i18n('dashboard_label_intro'), "dash_intro"); createHintH("intro", $.i18n('dashboard_label_intro'), "dash_intro");
removeOverlay(); removeOverlay();
}); });

View File

@ -121,7 +121,10 @@ $(document).ready( function() {
} }
//interval update //interval update
$(hyperion).on("cmd-serverinfo",updateEffectlist); $(hyperion).on("cmd-effects-update", function(event){
serverInfo.effects = event.response.data.effects
updateEffectlist();
});
removeOverlay(); removeOverlay();
}); });

View File

@ -2,6 +2,7 @@ $(document).ready( function() {
performTranslation(); performTranslation();
var oldDelList = []; var oldDelList = [];
var effectName = ""; var effectName = "";
var imageData = "";
var effects_editor = null; var effects_editor = null;
var effectPy = ""; var effectPy = "";
var testrun; var testrun;
@ -31,9 +32,29 @@ $(document).ready( function() {
function triggerTestEffect() { function triggerTestEffect() {
testrun = true; testrun = true;
var args = effects_editor.getEditor('root.args'); var args = effects_editor.getEditor('root.args');
requestTestEffect(effectName, ":/effects/" + effectPy.slice(1), JSON.stringify(args.getValue())); requestTestEffect(effectName, ":/effects/" + effectPy.slice(1), JSON.stringify(args.getValue()), imageData);
}; };
// Specify upload handler for image files
JSONEditor.defaults.options.upload = function(type, file, cbs) {
var fileReader = new FileReader();
//check file
if (!file.type.startsWith('image')) {
imageData = "";
cbs.failure('File upload error');
// TODO clear file dialog.
showInfoDialog('error', "", $.i18n('infoDialog_writeimage_error_text', file.name));
return;
}
fileReader.onload = function () {
imageData = this.result.split(',')[1];
cbs.success(file.name);
};
fileReader.readAsDataURL(file);
};
$("#effectslist").off().on("change", function(event) { $("#effectslist").off().on("change", function(event) {
if(effects_editor != null) if(effects_editor != null)
@ -48,6 +69,7 @@ $(document).ready( function() {
effectPy = ':'; effectPy = ':';
effectPy += effects[idx].schemaContent.script; effectPy += effects[idx].schemaContent.script;
imageData = "";
$("#name-input").trigger("change"); $("#name-input").trigger("change");
$("#eff_desc").html(createEffHint($.i18n(effects[idx].schemaContent.title),$.i18n(effects[idx].schemaContent.title+'_desc'))); $("#eff_desc").html(createEffHint($.i18n(effects[idx].schemaContent.title),$.i18n(effects[idx].schemaContent.title+'_desc')));
@ -70,6 +92,7 @@ $(document).ready( function() {
}); });
}); });
// disable or enable control elements
$("#name-input").on('change keyup', function(event) { $("#name-input").on('change keyup', function(event) {
effectName = $(this).val(); effectName = $(this).val();
if ($(this).val() == '') { if ($(this).val() == '') {
@ -81,8 +104,9 @@ $(document).ready( function() {
} }
}); });
// Save Effect
$('#btn_write').off().on('click',function() { $('#btn_write').off().on('click',function() {
requestWriteEffect(effectName,effectPy,JSON.stringify(effects_editor.getValue())); requestWriteEffect(effectName,effectPy,JSON.stringify(effects_editor.getValue()),imageData);
$(hyperion).one("cmd-create-effect", function(event) { $(hyperion).one("cmd-create-effect", function(event) {
if (event.response.success) if (event.response.success)
showInfoDialog('success', "", $.i18n('infoDialog_effconf_created_text', effectName)); showInfoDialog('success', "", $.i18n('infoDialog_effconf_created_text', effectName));
@ -93,21 +117,25 @@ $(document).ready( function() {
}); });
// Start test
$('#btn_start_test').off().on('click',function() { $('#btn_start_test').off().on('click',function() {
triggerTestEffect(); triggerTestEffect();
}); });
// Stop test
$('#btn_stop_test').off().on('click',function() { $('#btn_stop_test').off().on('click',function() {
requestPriorityClear(); requestPriorityClear();
testrun = false; testrun = false;
}); });
// Continuous test
$('#btn_cont_test').off().on('click',function() { $('#btn_cont_test').off().on('click',function() {
toggleClass('#btn_cont_test', "btn-success", "btn-danger"); toggleClass('#btn_cont_test', "btn-success", "btn-danger");
}); });
// Delete Effect
$('#btn_delete').off().on('click',function() { $('#btn_delete').off().on('click',function() {
var name = $("#effectsdellist").val(); var name = $("#effectsdellist").val().split("_")[1];
requestDeleteEffect(name); requestDeleteEffect(name);
$(hyperion).one("cmd-delete-effect", function(event) { $(hyperion).one("cmd-delete-effect", function(event) {
if (event.response.success) if (event.response.success)
@ -115,11 +143,13 @@ $(document).ready( function() {
}); });
}); });
// disable or enable Delete Effect Button
$('#effectsdellist').off().on('change', function(){ $('#effectsdellist').off().on('change', function(){
$(this).val() == null ? $('#btn_edit, #btn_delete').prop('disabled',true) : ""; $(this).val() == null ? $('#btn_edit, #btn_delete').prop('disabled',true) : "";
$(this).val().startsWith("int_") ? $('#btn_delete').prop('disabled',true) : $('#btn_delete').prop('disabled',false); $(this).val().startsWith("int_") ? $('#btn_delete').prop('disabled',true) : $('#btn_delete').prop('disabled',false);
}); });
// Load Effect
$('#btn_edit').off().on('click', function(){ $('#btn_edit').off().on('click', function(){
var name = $("#effectsdellist").val().replace("ext_",""); var name = $("#effectsdellist").val().replace("ext_","");
@ -155,15 +185,18 @@ $(document).ready( function() {
//create basic effect list //create basic effect list
var effects = serverSchema.properties.effectSchemas.internal var effects = serverSchema.properties.effectSchemas.internal
for(var idx=0; idx<effects.length; idx++) for(var idx=0; idx<effects.length; idx++)
{ {
$("#effectslist").append(createSelOpt(effects[idx].schemaContent.script, $.i18n(effects[idx].schemaContent.title))); $("#effectslist").append(createSelOpt(effects[idx].schemaContent.script, $.i18n(effects[idx].schemaContent.title)));
} }
$("#effectslist").trigger("change"); $("#effectslist").trigger("change");
updateDelEffectlist(); updateDelEffectlist();
//interval update //interval update
$(hyperion).on("cmd-serverinfo",updateDelEffectlist); $(hyperion).on("cmd-effects-update", function(event){
serverInfo.effects = event.response.data.effects
updateDelEffectlist();
});
removeOverlay(); removeOverlay();
}); });

View File

@ -2,7 +2,8 @@ $(document).ready( function() {
performTranslation(); performTranslation();
var conf_editor_v4l2 = null; var conf_editor_v4l2 = null;
var conf_editor_fg = null; var conf_editor_fg = null;
var conf_editor_instCapt = null;
function hideEl(el) function hideEl(el)
{ {
for(var i = 0; i<el.length; i++) for(var i = 0; i<el.length; i++)
@ -10,14 +11,19 @@ $(document).ready( function() {
$('[data-schemapath*="root.framegrabber.'+el[i]+'"]').toggle(false); $('[data-schemapath*="root.framegrabber.'+el[i]+'"]').toggle(false);
} }
} }
if(showOptHelp) if(showOptHelp)
{ {
//fg
$('#conf_cont').append(createRow('conf_cont_instCapt'))
$('#conf_cont_instCapt').append(createOptPanel('fa-camera', $.i18n("edt_conf_instCapture_heading_title"), 'editor_container_instCapt', 'btn_submit_instCapt'));
$('#conf_cont_instCapt').append(createHelpTable(schema.instCapture.properties, $.i18n("edt_conf_instCapture_heading_title")));
//fg //fg
$('#conf_cont').append(createRow('conf_cont_fg')) $('#conf_cont').append(createRow('conf_cont_fg'))
$('#conf_cont_fg').append(createOptPanel('fa-camera', $.i18n("edt_conf_fg_heading_title"), 'editor_container_fg', 'btn_submit_fg')); $('#conf_cont_fg').append(createOptPanel('fa-camera', $.i18n("edt_conf_fg_heading_title"), 'editor_container_fg', 'btn_submit_fg'));
$('#conf_cont_fg').append(createHelpTable(schema.framegrabber.properties, $.i18n("edt_conf_fg_heading_title"))); $('#conf_cont_fg').append(createHelpTable(schema.framegrabber.properties, $.i18n("edt_conf_fg_heading_title")));
//v4l //v4l
$('#conf_cont').append(createRow('conf_cont_v4l')) $('#conf_cont').append(createRow('conf_cont_v4l'))
$('#conf_cont_v4l').append(createOptPanel('fa-camera', $.i18n("edt_conf_v4l2_heading_title"), 'editor_container_v4l2', 'btn_submit_v4l2')); $('#conf_cont_v4l').append(createOptPanel('fa-camera', $.i18n("edt_conf_v4l2_heading_title"), 'editor_container_v4l2', 'btn_submit_v4l2'));
@ -26,10 +32,24 @@ $(document).ready( function() {
else else
{ {
$('#conf_cont').addClass('row'); $('#conf_cont').addClass('row');
$('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_instCapture_heading_title"), 'editor_container_instCapt', 'btn_submit_instCapt'));
$('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_fg_heading_title"), 'editor_container_fg', 'btn_submit_fg')); $('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_fg_heading_title"), 'editor_container_fg', 'btn_submit_fg'));
$('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_v4l2_heading_title"), 'editor_container_v4l2', 'btn_submit_v4l2')); $('#conf_cont').append(createOptPanel('fa-camera', $.i18n("edt_conf_v4l2_heading_title"), 'editor_container_v4l2', 'btn_submit_v4l2'));
} }
//instCapt
conf_editor_instCapt = createJsonEditor('editor_container_instCapt', {
instCapture: schema.instCapture
}, true, true);
conf_editor_instCapt.on('change',function() {
conf_editor_instCapt.validate().length ? $('#btn_submit_instCapt').attr('disabled', true) : $('#btn_submit_instCapt').attr('disabled', false);
});
$('#btn_submit_instCapt').off().on('click',function() {
requestWriteConfig(conf_editor_instCapt.getValue());
});
//fg //fg
conf_editor_fg = createJsonEditor('editor_container_fg', { conf_editor_fg = createJsonEditor('editor_container_fg', {
framegrabber: schema.framegrabber framegrabber: schema.framegrabber
@ -38,11 +58,11 @@ $(document).ready( function() {
conf_editor_fg.on('change',function() { conf_editor_fg.on('change',function() {
conf_editor_fg.validate().length ? $('#btn_submit_fg').attr('disabled', true) : $('#btn_submit_fg').attr('disabled', false); conf_editor_fg.validate().length ? $('#btn_submit_fg').attr('disabled', true) : $('#btn_submit_fg').attr('disabled', false);
}); });
$('#btn_submit_fg').off().on('click',function() { $('#btn_submit_fg').off().on('click',function() {
requestWriteConfig(conf_editor_fg.getValue()); requestWriteConfig(conf_editor_fg.getValue());
}); });
//vl4 //vl4
conf_editor_v4l2 = createJsonEditor('editor_container_v4l2', { conf_editor_v4l2 = createJsonEditor('editor_container_v4l2', {
grabberV4L2 : schema.grabberV4L2 grabberV4L2 : schema.grabberV4L2
@ -51,32 +71,31 @@ $(document).ready( function() {
conf_editor_v4l2.on('change',function() { conf_editor_v4l2.on('change',function() {
conf_editor_v4l2.validate().length ? $('#btn_submit_v4l2').attr('disabled', true) : $('#btn_submit_v4l2').attr('disabled', false); conf_editor_v4l2.validate().length ? $('#btn_submit_v4l2').attr('disabled', true) : $('#btn_submit_v4l2').attr('disabled', false);
}); });
$('#btn_submit_v4l2').off().on('click',function() { $('#btn_submit_v4l2').off().on('click',function() {
requestWriteConfig(conf_editor_v4l2.getValue()); requestWriteConfig(conf_editor_v4l2.getValue());
}); });
//create introduction //create introduction
if(showOptHelp) if(showOptHelp)
{ {
createHint("intro", $.i18n('conf_grabber_fg_intro'), "editor_container_fg"); createHint("intro", $.i18n('conf_grabber_fg_intro'), "editor_container_fg");
createHint("intro", $.i18n('conf_grabber_v4l_intro'), "editor_container_v4l2"); createHint("intro", $.i18n('conf_grabber_v4l_intro'), "editor_container_v4l2");
} }
//hide specific options //hide specific options
conf_editor_fg.on('ready',function() { conf_editor_fg.on('ready',function() {
var grabbers = serverInfo.grabbers.available; var grabbers = serverInfo.grabbers.available;
if(grabbers.indexOf('dispmanx') > -1) if(grabbers.indexOf('dispmanx') > -1)
hideEl(["device","verticalPixelDecimation","horizontalPixelDecimation","useXGetImage"]); hideEl(["device","pixelDecimation"]);
else if(grabbers.indexOf('x11') > -1) else if(grabbers.indexOf('x11') > -1)
hideEl(["device","width","height"]); hideEl(["device","width","height"]);
else if(grabbers.indexOf('osx') > -1 ) else if(grabbers.indexOf('osx') > -1 )
hideEl(["device","verticalPixelDecimation","horizontalPixelDecimation","useXGetImage"]); hideEl(["device","pixelDecimation"]);
else if(grabbers.indexOf('amlogic') > -1) else if(grabbers.indexOf('amlogic') > -1)
hideEl(["verticalPixelDecimation","horizontalPixelDecimation","useXGetImage"]); hideEl(["pixelDecimation"]);
}); });
removeOverlay(); removeOverlay();
}); });

View File

@ -1,6 +1,4 @@
$(document).ready( function() { $(document).ready( function() {
var uiLock = false;
var prevSess = 0;
loadContentTo("#container_connection_lost","connection_lost"); loadContentTo("#container_connection_lost","connection_lost");
loadContentTo("#container_restart","restart"); loadContentTo("#container_restart","restart");
@ -8,70 +6,52 @@ $(document).ready( function() {
$(hyperion).on("cmd-serverinfo",function(event){ $(hyperion).on("cmd-serverinfo",function(event){
serverInfo = event.response.info; serverInfo = event.response.info;
// comps
comps = event.response.info.components
$(hyperion).trigger("ready"); $(hyperion).trigger("ready");
if (serverInfo.hyperion.config_modified)
$("#hyperion_reload_notify").fadeIn("fast");
else
$("#hyperion_reload_notify").fadeOut("fast");
if (serverInfo.hyperion.off) comps.forEach( function(obj) {
$("#hyperion_disabled_notify").fadeIn("fast"); if (obj.name == "ALL")
else
$("#hyperion_disabled_notify").fadeOut("fast");
if (!serverInfo.hyperion.config_writeable)
{
showInfoDialog('uilock',$.i18n('InfoDialog_nowrite_title'),$.i18n('InfoDialog_nowrite_text'));
$('#wrapper').toggle(false);
uiLock = true;
}
else if (uiLock)
{
$("#modal_dialog").modal('hide');
$('#wrapper').toggle(true);
uiLock = false;
}
var sess = serverInfo.hyperion.sessions;
if (sess.length != prevSess)
{
wSess = [];
prevSess = sess.length;
for(var i = 0; i<sess.length; i++)
{ {
if(sess[i].type == "_hyperiond-http._tcp.") if(obj.enabled)
{ $("#hyperion_disabled_notify").fadeOut("fast");
wSess.push(sess[i]); else
} $("#hyperion_disabled_notify").fadeIn("fast");
} }
});
if (wSess.length > 1)
$('#btn_instanceswitch').toggle(true);
else
$('#btn_instanceswitch').toggle(false);
}
if (serverInfo.hyperion.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
updateSessions();
}); // end cmd-serverinfo }); // end cmd-serverinfo
$(hyperion).one("cmd-sysinfo", function(event) { $(hyperion).on("cmd-sessions-update", function(event) {
serverInfo.sessions = event.response.data;
updateSessions();
});
$(hyperion).on("cmd-sysinfo", function(event) {
requestServerInfo(); requestServerInfo();
sysInfo = event.response.info; sysInfo = event.response.info;
currentVersion = sysInfo.hyperion.version; currentVersion = sysInfo.hyperion.version;
}); });
$(hyperion).one("cmd-config-getschema", function(event) { $(hyperion).one("cmd-config-getschema", function(event) {
serverSchema = event.response.result; serverSchema = event.response.info;
requestServerConfig(); requestServerConfig();
schema = serverSchema.properties; schema = serverSchema.properties;
}); });
$(hyperion).one("cmd-config-getconfig", function(event) { $(hyperion).on("cmd-config-getconfig", function(event) {
serverConfig = event.response.result; serverConfig = event.response.info;
requestSysInfo(); requestSysInfo();
showOptHelp = serverConfig.general.showOptHelp; showOptHelp = serverConfig.general.showOptHelp;
}); });
@ -82,15 +62,44 @@ $(document).ready( function() {
$(hyperion).on("open",function(event){ $(hyperion).on("open",function(event){
requestServerConfigSchema(); requestServerConfigSchema();
}); });
$(hyperion).one("ready", function(event) { $(hyperion).one("ready", function(event) {
loadContent(); loadContent();
}); });
$("#btn_hyperion_reload").on("click", function(){ $(hyperion).on("cmd-adjustment-update", function(event) {
initRestart(); serverInfo.adjustment = event.response.data
}); });
$(hyperion).on("cmd-videomode-update", function(event) {
serverInfo.videomode = event.response.data.videomode
});
$(hyperion).on("cmd-components-update", function(event) {
let obj = event.response.data
// notfication in index
if (obj.name == "ALL")
{
if(obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
}
comps.forEach((entry, index) => {
if (entry.name === obj.name){
comps[index] = obj;
}
});
// notify the update
$(hyperion).trigger("components-updated");
});
$(hyperion).on("cmd-effects-update", function(event){
serverInfo.effects = event.response.data.effects
});
$(".mnava").bind('click.menu', function(e){ $(".mnava").bind('click.menu', function(e){
loadContent(e); loadContent(e);
window.scrollTo(0, 0); window.scrollTo(0, 0);
@ -105,4 +114,3 @@ $(function(){
$(this).toggleClass('active inactive'); $(this).toggleClass('active inactive');
}); });
}); });

View File

@ -473,7 +473,7 @@ $(document).ready(function() {
devRPiSPI = ['apa102', 'apa104', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'ws2812spi']; devRPiSPI = ['apa102', 'apa104', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'ws2812spi'];
devRPiPWM = ['ws281x']; devRPiPWM = ['ws281x'];
devRPiGPIO = ['piblaster']; devRPiGPIO = ['piblaster'];
devNET = ['atmoorb', 'fadecandy', 'philipshue', 'tinkerforge', 'tpm2net', 'udpe131', 'udpartnet', 'udph801', 'udpraw']; devNET = ['atmoorb', 'fadecandy', 'philipshue', 'aurora', 'tinkerforge', 'tpm2net', 'udpe131', 'udpartnet', 'udph801', 'udpraw'];
devUSB = ['adalight', 'dmx', 'atmo', 'hyperionusbasp', 'lightpack', 'multilightpack', 'paintpack', 'rawhid', 'sedu', 'tpm2', 'karate']; devUSB = ['adalight', 'dmx', 'atmo', 'hyperionusbasp', 'lightpack', 'multilightpack', 'paintpack', 'rawhid', 'sedu', 'tpm2', 'karate'];
var optArr = [[]]; var optArr = [[]];

View File

@ -1,24 +1,26 @@
$(document).ready( function() { $(document).ready( function() {
performTranslation(); performTranslation();
var conf_editor_net = null;
var conf_editor_json = null; var conf_editor_json = null;
var conf_editor_proto = null; var conf_editor_proto = null;
var conf_editor_fbs = null;
var conf_editor_bobl = null; var conf_editor_bobl = null;
var conf_editor_udpl = null; var conf_editor_udpl = null;
var conf_editor_forw = null; var conf_editor_forw = null;
if(showOptHelp) if(showOptHelp)
{ {
//jsonserver //jsonserver
$('#conf_cont').append(createRow('conf_cont_json')) $('#conf_cont').append(createRow('conf_cont_json'))
$('#conf_cont_json').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver')); $('#conf_cont_json').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver'));
$('#conf_cont_json').append(createHelpTable(schema.jsonServer.properties, $.i18n("edt_conf_js_heading_title"))); $('#conf_cont_json').append(createHelpTable(schema.jsonServer.properties, $.i18n("edt_conf_js_heading_title")));
//protoserver //flatbufserver
$('#conf_cont').append(createRow('conf_cont_proto')) $('#conf_cont').append(createRow('conf_cont_flatbuf'))
$('#conf_cont_proto').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); $('#conf_cont_flatbuf').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
$('#conf_cont_proto').append(createHelpTable(schema.protoServer.properties, $.i18n("edt_conf_ps_heading_title"))); $('#conf_cont_flatbuf').append(createHelpTable(schema.flatbufServer.properties, $.i18n("edt_conf_fbs_heading_title")));
//boblight //boblight
$('#conf_cont').append(createRow('conf_cont_bobl')) $('#conf_cont').append(createRow('conf_cont_bobl'))
$('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); $('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver'));
@ -41,10 +43,10 @@ $(document).ready( function() {
{ {
$('#conf_cont').addClass('row'); $('#conf_cont').addClass('row');
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver'));
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver'));
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener'));
if(storedAccess != 'default') if(storedAccess != 'default')
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fw_heading_title"), 'editor_container_forwarder', 'btn_submit_forwarder')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fw_heading_title"), 'editor_container_forwarder', 'btn_submit_forwarder'));
} }
@ -61,19 +63,19 @@ $(document).ready( function() {
requestWriteConfig(conf_editor_json.getValue()); requestWriteConfig(conf_editor_json.getValue());
}); });
//proto //flatbuffer
conf_editor_proto = createJsonEditor('editor_container_protoserver', { conf_editor_fbs = createJsonEditor('editor_container_fbserver', {
protoServer : schema.protoServer flatbufServer : schema.flatbufServer
}, true, true); }, true, true);
conf_editor_proto.on('change',function() { conf_editor_fbs.on('change',function() {
conf_editor_proto.validate().length ? $('#btn_submit_protoserver').attr('disabled', true) : $('#btn_submit_protoserver').attr('disabled', false); conf_editor_fbs.validate().length ? $('#btn_submit_fbserver').attr('disabled', true) : $('#btn_submit_fbserver').attr('disabled', false);
}); });
$('#btn_submit_protoserver').off().on('click',function() { $('#btn_submit_fbserver').off().on('click',function() {
requestWriteConfig(conf_editor_proto.getValue()); requestWriteConfig(conf_editor_fbs.getValue());
}); });
//boblight //boblight
conf_editor_bobl = createJsonEditor('editor_container_boblightserver', { conf_editor_bobl = createJsonEditor('editor_container_boblightserver', {
boblightServer : schema.boblightServer boblightServer : schema.boblightServer
@ -82,11 +84,11 @@ $(document).ready( function() {
conf_editor_bobl.on('change',function() { conf_editor_bobl.on('change',function() {
conf_editor_bobl.validate().length ? $('#btn_submit_boblightserver').attr('disabled', true) : $('#btn_submit_boblightserver').attr('disabled', false); conf_editor_bobl.validate().length ? $('#btn_submit_boblightserver').attr('disabled', true) : $('#btn_submit_boblightserver').attr('disabled', false);
}); });
$('#btn_submit_boblightserver').off().on('click',function() { $('#btn_submit_boblightserver').off().on('click',function() {
requestWriteConfig(conf_editor_bobl.getValue()); requestWriteConfig(conf_editor_bobl.getValue());
}); });
//udplistener //udplistener
conf_editor_udpl = createJsonEditor('editor_container_udplistener', { conf_editor_udpl = createJsonEditor('editor_container_udplistener', {
udpListener : schema.udpListener udpListener : schema.udpListener
@ -95,11 +97,11 @@ $(document).ready( function() {
conf_editor_udpl.on('change',function() { conf_editor_udpl.on('change',function() {
conf_editor_udpl.validate().length ? $('#btn_submit_udplistener').attr('disabled', true) : $('#btn_submit_udplistener').attr('disabled', false); conf_editor_udpl.validate().length ? $('#btn_submit_udplistener').attr('disabled', true) : $('#btn_submit_udplistener').attr('disabled', false);
}); });
$('#btn_submit_udplistener').off().on('click',function() { $('#btn_submit_udplistener').off().on('click',function() {
requestWriteConfig(conf_editor_udpl.getValue()); requestWriteConfig(conf_editor_udpl.getValue());
}); });
if(storedAccess != 'default') if(storedAccess != 'default')
{ {
//forwarder //forwarder
@ -115,17 +117,16 @@ $(document).ready( function() {
requestWriteConfig(conf_editor_forw.getValue()); requestWriteConfig(conf_editor_forw.getValue());
}); });
} }
//create introduction //create introduction
if(showOptHelp) if(showOptHelp)
{ {
createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver"); createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver");
createHint("intro", $.i18n('conf_network_proto_intro'), "editor_container_protoserver"); createHint("intro", $.i18n('conf_network_fbs_intro'), "editor_container_fbserver");
createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver"); createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver");
createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener"); createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener");
createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder"); createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder");
} }
removeOverlay(); removeOverlay();
}); });

View File

@ -86,22 +86,6 @@ $(document).ready(function() {
requestSetColor(rgb.r, rgb.g, rgb.b,duration); requestSetColor(rgb.r, rgb.g, rgb.b,duration);
} }
function updateRemote()
{
if ($('#componentsbutton').length == 0)
{
$(hyperion).off("cmd-serverinfo",updateRemote);
}
else
{
updateInputSelect();
updateLedMapping();
updateVideoMode();
updateComponents();
updateEffectlist();
}
}
function updateInputSelect() function updateInputSelect()
{ {
$('.sstbody').html(""); $('.sstbody').html("");
@ -123,6 +107,7 @@ $(document).ready(function() {
var priority = prios[i].priority; var priority = prios[i].priority;
var compId = prios[i].componentId; var compId = prios[i].componentId;
var duration = prios[i].duration_ms/1000; var duration = prios[i].duration_ms/1000;
var value = "0,0,0";
var btn_type = "default"; var btn_type = "default";
var btn_text = $.i18n('remote_input_setsource_btn'); var btn_text = $.i18n('remote_input_setsource_btn');
var btn_state = "enabled"; var btn_state = "enabled";
@ -145,13 +130,16 @@ $(document).ready(function() {
if(ip) if(ip)
origin += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_ip')+' '+ip+'</span>'; origin += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_ip')+' '+ip+'</span>';
if("value" in prios[i])
value = prios[i].value.RGB;
switch (compId) switch (compId)
{ {
case "EFFECT": case "EFFECT":
owner = $.i18n('remote_effects_label_effects')+' '+owner; owner = $.i18n('remote_effects_label_effects')+' '+owner;
break; break;
case "COLOR": case "COLOR":
owner = $.i18n('remote_color_label_color')+' '+'<div style="width:18px; height:18px; border-radius:20px; margin-bottom:-4px; border:1px grey solid; background-color: rgb('+prios[i].value.RGB+'); display:inline-block" title="RGB: ('+prios[i].value.RGB+')"></div>'; owner = $.i18n('remote_color_label_color')+' '+'<div style="width:18px; height:18px; border-radius:20px; margin-bottom:-4px; border:1px grey solid; background-color: rgb('+value+'); display:inline-block" title="RGB: ('+value+')"></div>';
break; break;
case "GRABBER": case "GRABBER":
owner = $.i18n('general_comp_GRABBER')+': ('+owner+')'; owner = $.i18n('general_comp_GRABBER')+': ('+owner+')';
@ -165,6 +153,9 @@ $(document).ready(function() {
case "UDPLISTENER": case "UDPLISTENER":
owner = $.i18n('general_comp_UDPLISTENER'); owner = $.i18n('general_comp_UDPLISTENER');
break; break;
case "FLATBUFSERVER":
owner = $.i18n('general_comp_FLATBUFSERVER');
break;
} }
if(duration && compId != "GRABBER" && compId != "PROTOSERVER") if(duration && compId != "GRABBER" && compId != "PROTOSERVER")
@ -195,7 +186,7 @@ $(document).ready(function() {
function updateLedMapping() function updateLedMapping()
{ {
mapping = serverInfo.ledMAppingType; mapping = serverInfo.imageToLedMappingType;
$('#mappingsbutton').html(""); $('#mappingsbutton').html("");
for(var ix = 0; ix < mappingList.length; ix++) for(var ix = 0; ix < mappingList.length; ix++)
@ -211,16 +202,27 @@ $(document).ready(function() {
function updateComponents() function updateComponents()
{ {
components = serverInfo.components; components = comps;
var hyperionEnabled = true;
components.forEach( function(obj) {
if (obj.name == "ALL")
{
hyperionEnabled = obj.enabled
}
});
// create buttons // create buttons
$('#componentsbutton').html(""); $('#componentsbutton').html("");
for ( idx=0; idx<components.length;idx++) for ( idx=0; idx<components.length;idx++)
{ {
if(components[idx].name == "ALL")
continue
enable_style = (components[idx].enabled? "btn-success" : "btn-danger"); enable_style = (components[idx].enabled? "btn-success" : "btn-danger");
enable_icon = (components[idx].enabled? "fa-play" : "fa-stop"); enable_icon = (components[idx].enabled? "fa-play" : "fa-stop");
comp_name = components[idx].name; comp_name = components[idx].name;
comp_btn_id = "comp_btn_"+comp_name; comp_btn_id = "comp_btn_"+comp_name;
comp_goff = serverInfo.hyperion.off? "disabled" : "enabled"; comp_goff = hyperionEnabled? "enabled" : "disabled";
// create btn if not there // create btn if not there
if ($("#"+comp_btn_id).length == 0) if ($("#"+comp_btn_id).length == 0)
@ -266,7 +268,7 @@ $(document).ready(function() {
function updateVideoMode() function updateVideoMode()
{ {
videoModes = ["2D","3DSBS","3DTAB"]; videoModes = ["2D","3DSBS","3DTAB"];
currVideoMode = serverInfo.grabbers.videomode; currVideoMode = serverInfo.videomode;
$('#videomodebtns').html(""); $('#videomodebtns').html("");
for(var ix = 0; ix < videoModes.length; ix++) for(var ix = 0; ix < videoModes.length; ix++)
@ -327,10 +329,34 @@ $(document).ready(function() {
}); });
//force first update //force first update
updateRemote(); updateComponents();
updateInputSelect();
updateLedMapping();
updateVideoMode();
updateEffectlist();
// interval updates // interval updates
$(hyperion).on("cmd-serverinfo",updateRemote); $(hyperion).on("components-updated",updateComponents);
$(hyperion).on("cmd-priorities-update", function(event){
serverInfo.priorities = event.response.data.priorities
serverInfo.priorities_autoselect = event.response.data.priorities_autoselect
updateInputSelect()
});
$(hyperion).on("cmd-imageToLedMapping-update", function(event){
serverInfo.imageToLedMappingType = event.response.data.imageToLedMappingType
updateLedMapping()
});
$(hyperion).on("cmd-videomode-update", function(event){
serverInfo.videomode = event.response.data.videomode
updateVideoMode()
});
$(hyperion).on("cmd-effects-update", function(event){
serverInfo.effects = event.response.data.effects
updateEffectlist();
});
removeOverlay(); removeOverlay();
}); });

View File

@ -22,6 +22,11 @@ var loggingHandlerInstalled = false;
var watchdog = 0; var watchdog = 0;
var debugMessagesActive = true; var debugMessagesActive = true;
var wSess = []; var wSess = [];
var plugins_installed = {};
var plugins_available = {};
//comps serverinfo
comps = [];
function initRestart() function initRestart()
{ {
@ -59,6 +64,7 @@ function connectionLostDetection(type)
setInterval(connectionLostDetection, 3000); setInterval(connectionLostDetection, 3000);
// init websocket to hyperion and bind socket events to jquery events of $(hyperion) object // init websocket to hyperion and bind socket events to jquery events of $(hyperion) object
function initWebSocket() function initWebSocket()
{ {
if ("WebSocket" in window) if ("WebSocket" in window)
@ -66,8 +72,8 @@ function initWebSocket()
if (websocket == null) if (websocket == null)
{ {
jsonPort = (document.location.port == '') ? '80' : document.location.port; jsonPort = (document.location.port == '') ? '80' : document.location.port;
websocket = new WebSocket('ws://'+document.location.hostname+":"+document.location.port); websocket = new WebSocket('ws://'+document.location.hostname+":"+jsonPort);
console.log(jsonPort)
websocket.onopen = function (event) { websocket.onopen = function (event) {
$(hyperion).trigger({type:"open"}); $(hyperion).trigger({type:"open"});
@ -108,7 +114,7 @@ function initWebSocket()
response = JSON.parse(event.data); response = JSON.parse(event.data);
success = response.success; success = response.success;
cmd = response.command; cmd = response.command;
if (success) if (success || typeof(success) == "undefined")
{ {
$(hyperion).trigger({type:"cmd-"+cmd, response:response}); $(hyperion).trigger({type:"cmd-"+cmd, response:response});
} }
@ -161,7 +167,7 @@ function sendToHyperion(command, subcommand, msg)
// also used for watchdog // also used for watchdog
function requestServerInfo() function requestServerInfo()
{ {
sendToHyperion("serverinfo"); sendToHyperion("serverinfo","",'"subscribe":["components-update","sessions-update","priorities-update", "imageToLedMapping-update", "adjustment-update", "videomode-update", "effects-update", "settings-update"]');
} }
function requestSysInfo() function requestSysInfo()
@ -218,7 +224,7 @@ function requestPriorityClear(prio)
function requestClearAll() function requestClearAll()
{ {
sendToHyperion("clearall"); requestPriorityClear(-1)
} }
function requestPlayEffect(effectName, duration) function requestPlayEffect(effectName, duration)
@ -264,15 +270,15 @@ function requestWriteConfig(config, full)
sendToHyperion("config","setconfig", '"config":'+JSON.stringify(serverConfig)); sendToHyperion("config","setconfig", '"config":'+JSON.stringify(serverConfig));
} }
function requestWriteEffect(effectName,effectPy,effectArgs) function requestWriteEffect(effectName,effectPy,effectArgs,data)
{ {
var cutArgs = effectArgs.slice(1, -1); var cutArgs = effectArgs.slice(1, -1);
sendToHyperion("create-effect", "", '"name":"'+effectName+'", "script":"'+effectPy+'", '+cutArgs); sendToHyperion("create-effect", "", '"name":"'+effectName+'", "script":"'+effectPy+'", '+cutArgs+',"imageData":"'+data+'"');
} }
function requestTestEffect(effectName,effectPy,effectArgs) function requestTestEffect(effectName,effectPy,effectArgs,data)
{ {
sendToHyperion("effect", "", '"effect":{"name":"'+effectName+'", "args":'+effectArgs+'}, "priority":'+webPrio+', "origin":"'+webOrigin+'", "pythonScript":"'+effectPy+'"'); sendToHyperion("effect", "", '"effect":{"name":"'+effectName+'", "args":'+effectArgs+'}, "priority":'+webPrio+', "origin":"'+webOrigin+'", "pythonScript":"'+effectPy+'", "imageData":"'+data+'"');
} }
function requestDeleteEffect(effectName) function requestDeleteEffect(effectName)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5982,24 +5982,8 @@ JSONEditor.defaults.editors.upload = JSONEditor.AbstractEditor.extend({
if(!this.preview_value) return; if(!this.preview_value) return;
var self = this; var self = this;
var mime = this.preview_value.match(/^data:([^;,]+)[;,]/);
if(mime) mime = mime[1];
if(!mime) mime = 'unknown';
var file = this.uploader.files[0]; var file = this.uploader.files[0];
this.preview.innerHTML = '<strong>Type:</strong> '+mime+', <strong>Size:</strong> '+file.size+' bytes';
if(mime.substr(0,5)==="image") {
this.preview.innerHTML += '<br>';
var img = document.createElement('img');
img.style.maxWidth = '100%';
img.style.maxHeight = '100px';
img.src = this.preview_value;
this.preview.appendChild(img);
}
this.preview.innerHTML += '<br>';
var uploadButton = this.getButton('Upload', 'upload', 'Upload'); var uploadButton = this.getButton('Upload', 'upload', 'Upload');
this.preview.appendChild(uploadButton); this.preview.appendChild(uploadButton);
uploadButton.addEventListener('click',function(event) { uploadButton.addEventListener('click',function(event) {
@ -6036,6 +6020,11 @@ JSONEditor.defaults.editors.upload = JSONEditor.AbstractEditor.extend({
} }
}); });
}); });
if(this.jsoneditor.options.auto_upload || this.schema.options.auto_upload) {
uploadButton.dispatchEvent(new MouseEvent('click'));
this.preview.removeChild(uploadButton);
}
}, },
enable: function() { enable: function() {
if(this.uploader) this.uploader.disabled = false; if(this.uploader) this.uploader.disabled = false;
@ -6825,10 +6814,7 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
}, },
getButton: function(text, icon, title) { getButton: function(text, icon, title) {
var el = this._super(text, icon, title); var el = this._super(text, icon, title);
if(icon.className.includes("fa-times")) el.className += 'btn btn-default';
el.className += 'btn btn-sm btn-danger';
else
el.className += 'btn btn-sm btn-primary';
return el; return el;
}, },
getTable: function() { getTable: function() {

View File

@ -7,7 +7,7 @@ function removeOverlay()
function reload() function reload()
{ {
location.reload(); location.reload();
} }
function storageComp() function storageComp()
@ -48,6 +48,27 @@ function debugMessage(msg)
} }
} }
function updateSessions()
{
var sess = serverInfo.sessions;
if (sess.length)
{
wSess = [];
for(var i = 0; i<sess.length; i++)
{
if(sess[i].type == "_hyperiond-http._tcp.")
{
wSess.push(sess[i]);
}
}
if (wSess.length > 1)
$('#btn_instanceswitch').toggle(true);
else
$('#btn_instanceswitch').toggle(false);
}
}
function validateDuration(d) function validateDuration(d)
{ {
if(typeof d === "undefined" || d < 0) if(typeof d === "undefined" || d < 0)
@ -70,12 +91,12 @@ function getHashtag()
} }
} }
function loadContent(event) function loadContent(event, forceRefresh)
{ {
var tag; var tag;
if(typeof event != "undefined") if(typeof event != "undefined")
{ {
tag = event.currentTarget.hash; tag = event.currentTarget.hash;
tag = tag.substr(tag.indexOf("#") + 1); tag = tag.substr(tag.indexOf("#") + 1);
setStorage('lasthashtag', tag, true); setStorage('lasthashtag', tag, true);
@ -83,7 +104,7 @@ function loadContent(event)
else else
tag = getHashtag(); tag = getHashtag();
if(prevTag != tag) if(forceRefresh || prevTag != tag)
{ {
prevTag = tag; prevTag = tag;
$("#page-content").off(); $("#page-content").off();
@ -130,7 +151,7 @@ function setClassByBool(obj,enable,class1,class2)
} }
function showInfoDialog(type,header,message) function showInfoDialog(type,header,message)
{ {
if (type=="success"){ if (type=="success"){
$('#id_body').html('<i style="margin-bottom:20px" class="fa fa-check modal-icon-check">'); $('#id_body').html('<i style="margin-bottom:20px" class="fa fa-check modal-icon-check">');
if(header == "") if(header == "")
@ -143,12 +164,12 @@ function showInfoDialog(type,header,message)
$('#id_body').append('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('infoDialog_general_warning_title')+'</h4>'); $('#id_body').append('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('infoDialog_general_warning_title')+'</h4>');
$('#id_footer').html('<button type="button" class="btn btn-warning" data-dismiss="modal">'+$.i18n('general_btn_ok')+'</button>'); $('#id_footer').html('<button type="button" class="btn btn-warning" data-dismiss="modal">'+$.i18n('general_btn_ok')+'</button>');
} }
else if (type=="error"){ else if (type=="error"){
$('#id_body').html('<i style="margin-bottom:20px" class="fa fa-warning modal-icon-error">'); $('#id_body').html('<i style="margin-bottom:20px" class="fa fa-warning modal-icon-error">');
if(header == "") if(header == "")
$('#id_body').append('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('infoDialog_general_error_title')+'</h4>'); $('#id_body').append('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('infoDialog_general_error_title')+'</h4>');
$('#id_footer').html('<button type="button" class="btn btn-danger" data-dismiss="modal">'+$.i18n('general_btn_ok')+'</button>'); $('#id_footer').html('<button type="button" class="btn btn-danger" data-dismiss="modal">'+$.i18n('general_btn_ok')+'</button>');
} }
else if (type == "select"){ else if (type == "select"){
$('#id_body').html('<img style="margin-bottom:20px" src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!">'); $('#id_body').html('<img style="margin-bottom:20px" src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!">');
$('#id_footer').html('<button type="button" id="id_btn_saveset" class="btn btn-primary" data-dismiss="modal"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saveandreload')+'</button>'); $('#id_footer').html('<button type="button" id="id_btn_saveset" class="btn btn-primary" data-dismiss="modal"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saveandreload')+'</button>');
@ -178,10 +199,10 @@ function showInfoDialog(type,header,message)
$('#id_body').append('<h4 style="font-weight:bold;text-transform:uppercase;">'+header+'</h4>'); $('#id_body').append('<h4 style="font-weight:bold;text-transform:uppercase;">'+header+'</h4>');
$('#id_body').append(message); $('#id_body').append(message);
if(type == "select" || type == "iswitch") if(type == "select" || type == "iswitch")
$('#id_body').append('<select id="id_select" class="form-control" style="margin-top:10px;width:auto;"></select>'); $('#id_body').append('<select id="id_select" class="form-control" style="margin-top:10px;width:auto;"></select>');
$("#modal_dialog").modal({ $("#modal_dialog").modal({
backdrop : "static", backdrop : "static",
keyboard: false, keyboard: false,
@ -193,14 +214,14 @@ function createHintH(type, text, container)
{ {
if(type = "intro") if(type = "intro")
tclass = "introd"; tclass = "introd";
$('#'+container).prepend('<div class="'+tclass+'"><h4 style="font-size:16px">'+text+'</h4><hr/></div>'); $('#'+container).prepend('<div class="'+tclass+'"><h4 style="font-size:16px">'+text+'</h4><hr/></div>');
} }
function createHint(type, text, container, buttonid, buttontxt) function createHint(type, text, container, buttonid, buttontxt)
{ {
var fe, tclass; var fe, tclass;
if(type == "intro") if(type == "intro")
{ {
fe = ''; fe = '';
@ -212,21 +233,21 @@ function createHint(type, text, container, buttonid, buttontxt)
tclass = "info-hint"; tclass = "info-hint";
} }
else if(type == "wizard") else if(type == "wizard")
{ {
fe = '<div style="font-size:25px;text-align:center"><i class="fa fa-magic"></i></div><div style="text-align:center;font-size:13px">Information</div>'; fe = '<div style="font-size:25px;text-align:center"><i class="fa fa-magic"></i></div><div style="text-align:center;font-size:13px">Information</div>';
tclass = "wizard-hint"; tclass = "wizard-hint";
} }
else if(type == "warning") else if(type == "warning")
{ {
fe = '<div style="font-size:25px;text-align:center"><i class="fa fa-info"></i></div><div style="text-align:center;font-size:13px">Information</div>'; fe = '<div style="font-size:25px;text-align:center"><i class="fa fa-info"></i></div><div style="text-align:center;font-size:13px">Information</div>';
tclass = "warning-hint"; tclass = "warning-hint";
} }
if(buttonid) if(buttonid)
buttonid = '<p><button id="'+buttonid+'" class="btn btn-wizard" style="margin-top:15px;">'+text+'</button></p>'; buttonid = '<p><button id="'+buttonid+'" class="btn btn-wizard" style="margin-top:15px;">'+text+'</button></p>';
else else
buttonid = ""; buttonid = "";
if(type == "intro") if(type == "intro")
$('#'+container).prepend('<div class="bs-callout bs-callout-primary" style="margin-top:0px"><h4>'+$.i18n("conf_helptable_expl")+'</h4>'+text+'</div>'); $('#'+container).prepend('<div class="bs-callout bs-callout-primary" style="margin-top:0px"><h4>'+$.i18n("conf_helptable_expl")+'</h4>'+text+'</div>');
else if(type == "wizard") else if(type == "wizard")
@ -247,8 +268,8 @@ function valValue(id,value,min,max)
{ {
if(typeof max === 'undefined' || max == "") if(typeof max === 'undefined' || max == "")
max = 999999; max = 999999;
if(Number(value) > Number(max)) if(Number(value) > Number(max))
{ {
$('#'+id).val(max); $('#'+id).val(max);
showInfoDialog("warning","",$.i18n('edt_msg_error_maximum_incl',max)); showInfoDialog("warning","",$.i18n('edt_msg_error_maximum_incl',max));
@ -260,7 +281,7 @@ function valValue(id,value,min,max)
showInfoDialog("warning","",$.i18n('edt_msg_error_minimum_incl',min)); showInfoDialog("warning","",$.i18n('edt_msg_error_minimum_incl',min));
return min; return min;
} }
return value; return value;
} }
function readImg(input,cb) function readImg(input,cb)
@ -294,12 +315,10 @@ function createJsonEditor(container,schema,setconfig,usePanel,arrayre)
{ {
$('#'+container).off(); $('#'+container).off();
$('#'+container).html(""); $('#'+container).html("");
//JSONEditor.plugins.selectize.enable = true;
if (typeof arrayre === 'undefined') if (typeof arrayre === 'undefined')
arrayre = true; arrayre = true;
var editor = new JSONEditor(document.getElementById(container), var editor = new JSONEditor(document.getElementById(container),
{ {
theme: 'bootstrap3', theme: 'bootstrap3',
@ -338,18 +357,18 @@ function createJsonEditor(container,schema,setconfig,usePanel,arrayre)
} }
function buildWL(link,linkt,cl) function buildWL(link,linkt,cl)
{ {
var baseLink = "https://docs.hyperion-project.org/"; var baseLink = "https://docs.hyperion-project.org/";
var lang; var lang;
if(typeof linkt == "undefined") if(typeof linkt == "undefined")
linkt = "Placeholder"; linkt = "Placeholder";
if(storedLang == "de" || navigator.locale == "de") if(storedLang == "de" || navigator.locale == "de")
lang = "de"; lang = "de";
else else
lang = "en"; lang = "en";
if(cl === true) if(cl === true)
{ {
linkt = $.i18n(linkt); linkt = $.i18n(linkt);
@ -366,7 +385,7 @@ function rgbToHex(rgb)
return "#" + return "#" +
("0" + parseInt(rgb[0],10).toString(16)).slice(-2) + ("0" + parseInt(rgb[0],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2); ("0" + parseInt(rgb[2],10).toString(16)).slice(-2);
} }
else else
debugMessage('rgbToHex: Given rgb is no array or has wrong length'); debugMessage('rgbToHex: Given rgb is no array or has wrong length');
@ -381,6 +400,57 @@ function hexToRgb(hex) {
} : null; } : null;
} }
/*
Show a notification
@param type Valid types are "info","success","warning","danger"
@param message The message to show
@param title A title (optional)
*/
function showNotification(type, message, title="")
{
if(title == "")
{
switch(type)
{
case "info":
title = $.i18n('infoDialog_general_info_title');
break;
case "success":
title = $.i18n('infoDialog_general_success_title');
break;
case "warning":
title = $.i18n('infoDialog_general_warning_title');
break;
case "danger":
title = $.i18n('infoDialog_general_error_title');
break;
}
}
$.notify({
// options
title: title,
message: message
},{
// settings
type: type,
animate: {
enter: 'animated fadeInRight',
exit: 'animated fadeOutRight'
},
mouse_over : 'pause',
template: '<div data-notify="container" class="bg-w col-xs-11 col-sm-3 bs-callout bs-callout-{0}" role="alert">' +
'<button type="button" aria-hidden="true" class="close" data-notify="dismiss">×</button>' +
'<span data-notify="icon"></span> ' +
'<h4 data-notify="title">{1}</h4> ' +
'<span data-notify="message">{2}</span>' +
'<div class="progress" data-notify="progressbar">' +
'<div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>' +
'</div>' +
'<a href="{3}" target="{4}" data-notify="url"></a>' +
'</div>'
});
}
function createCP(id, color, cb) function createCP(id, color, cb)
{ {
@ -388,7 +458,7 @@ function createCP(id, color, cb)
color = rgbToHex(color); color = rgbToHex(color);
else if(color == "undefined") else if(color == "undefined")
color = "#AA3399"; color = "#AA3399";
if(color.startsWith("#")) if(color.startsWith("#"))
{ {
$('#'+id).colorpicker({ $('#'+id).colorpicker({
@ -425,7 +495,7 @@ function createTable(hid, bid, cont, bless, tclass)
var table = document.createElement('table'); var table = document.createElement('table');
var thead = document.createElement('thead'); var thead = document.createElement('thead');
var tbody = document.createElement('tbody'); var tbody = document.createElement('tbody');
table.className = "table"; table.className = "table";
if(bless === true) if(bless === true)
table.className += " borderless"; table.className += " borderless";
@ -438,30 +508,30 @@ function createTable(hid, bid, cont, bless, tclass)
if(hid != "") if(hid != "")
table.appendChild(thead); table.appendChild(thead);
table.appendChild(tbody); table.appendChild(tbody);
$('#'+cont).append(table); $('#'+cont).append(table);
} }
// Creates a table row <tr> // Creates a table row <tr>
// @param array list :innerHTML content for <td>/<th> // @param array list :innerHTML content for <td>/<th>
// @param bool head :if null or false it's body // @param bool head :if null or false it's body
// @param bool align :if null or false no alignment // @param bool align :if null or false no alignment
// //
// @return : <tr> with <td> or <th> as child(s) // @return : <tr> with <td> or <th> as child(s)
function createTableRow(list, head, align) function createTableRow(list, head, align)
{ {
var row = document.createElement('tr'); var row = document.createElement('tr');
for(var i = 0; i < list.length; i++) for(var i = 0; i < list.length; i++)
{ {
if(head === true) if(head === true)
var el = document.createElement('th'); var el = document.createElement('th');
else else
var el = document.createElement('td'); var el = document.createElement('td');
if(align) if(align)
el.style.verticalAlign = "middle"; el.style.verticalAlign = "middle";
el.innerHTML = list[i]; el.innerHTML = list[i];
row.appendChild(el); row.appendChild(el);
} }
@ -483,7 +553,7 @@ function createOptPanel(phicon, phead, bodyid, footerid)
pfooter.className = "btn btn-primary"; pfooter.className = "btn btn-primary";
pfooter.setAttribute("id", footerid); pfooter.setAttribute("id", footerid);
pfooter.innerHTML = '<i class="fa fa-fw fa-save"></i>'+$.i18n('general_button_savesettings'); pfooter.innerHTML = '<i class="fa fa-fw fa-save"></i>'+$.i18n('general_button_savesettings');
return createPanel(phead, "", pfooter, "panel-default", bodyid); return createPanel(phead, "", pfooter, "panel-default", bodyid);
} }
@ -506,30 +576,35 @@ function createHelpTable(list, phead){
var thead = document.createElement('thead'); var thead = document.createElement('thead');
var tbody = document.createElement('tbody'); var tbody = document.createElement('tbody');
list = sortProperties(list); list = sortProperties(list);
phead = '<i class="fa fa-fw fa-info-circle"></i>'+phead+' '+$.i18n("conf_helptable_expl"); phead = '<i class="fa fa-fw fa-info-circle"></i>'+phead+' '+$.i18n("conf_helptable_expl");
table.className = 'table table-hover borderless'; table.className = 'table table-hover borderless';
thead.appendChild(createTableRow([$.i18n('conf_helptable_option'), $.i18n('conf_helptable_expl')], true, false)); thead.appendChild(createTableRow([$.i18n('conf_helptable_option'), $.i18n('conf_helptable_expl')], true, false));
for (key in list) for (key in list)
{ {
if(list[key].access != 'system') if(list[key].access != 'system')
{ {
// break one iteration (in the loop), if the schema has the entry hidden=true
if ("options" in list[key] && "hidden" in list[key].options && (list[key].options.hidden))
continue;
var text = list[key].title.replace('title', 'expl'); var text = list[key].title.replace('title', 'expl');
tbody.appendChild(createTableRow([$.i18n(list[key].title), $.i18n(text)], false, false)); tbody.appendChild(createTableRow([$.i18n(list[key].title), $.i18n(text)], false, false));
if(list[key].items && list[key].items.properties) if(list[key].items && list[key].items.properties)
{ {
var ilist = sortProperties(list[key].items.properties); var ilist = sortProperties(list[key].items.properties);
for (ikey in ilist) for (ikey in ilist)
{ {
// break one iteration (in the loop), if the schema has the entry hidden=true
if ("options" in ilist[ikey] && "hidden" in ilist[ikey].options && (ilist[ikey].options.hidden))
continue;
var itext = ilist[ikey].title.replace('title', 'expl'); var itext = ilist[ikey].title.replace('title', 'expl');
tbody.appendChild(createTableRow([$.i18n(ilist[ikey].title), $.i18n(itext)], false, false)); tbody.appendChild(createTableRow([$.i18n(ilist[ikey].title), $.i18n(itext)], false, false));
} }
} }
} }
} }
table.appendChild(thead); table.appendChild(thead);
@ -544,42 +619,42 @@ function createPanel(head, body, footer, type, bodyid){
var phead = document.createElement('div'); var phead = document.createElement('div');
var pbody = document.createElement('div'); var pbody = document.createElement('div');
var pfooter = document.createElement('div'); var pfooter = document.createElement('div');
cont.className = "col-lg-6"; cont.className = "col-lg-6";
if(typeof type == 'undefined') if(typeof type == 'undefined')
type = 'panel-default'; type = 'panel-default';
p.className = 'panel '+type; p.className = 'panel '+type;
phead.className = 'panel-heading'; phead.className = 'panel-heading';
pbody.className = 'panel-body'; pbody.className = 'panel-body';
pfooter.className = 'panel-footer'; pfooter.className = 'panel-footer';
phead.innerHTML = head; phead.innerHTML = head;
if(typeof bodyid != 'undefined') if(typeof bodyid != 'undefined')
{ {
pfooter.style.textAlign = 'right'; pfooter.style.textAlign = 'right';
pbody.setAttribute("id", bodyid) pbody.setAttribute("id", bodyid)
} }
if(typeof body != 'undefined' && body != "") if(typeof body != 'undefined' && body != "")
pbody.appendChild(body); pbody.appendChild(body);
if(typeof footer != 'undefined') if(typeof footer != 'undefined')
pfooter.appendChild(footer); pfooter.appendChild(footer);
p.appendChild(phead); p.appendChild(phead);
p.appendChild(pbody); p.appendChild(pbody);
if(typeof footer != 'undefined') if(typeof footer != 'undefined')
{ {
pfooter.style.textAlign = "right"; pfooter.style.textAlign = "right";
p.appendChild(pfooter); p.appendChild(pfooter);
} }
cont.appendChild(p); cont.appendChild(p);
return cont; return cont;
} }
@ -589,12 +664,12 @@ function createSelGroup(group)
el.setAttribute('label', group); el.setAttribute('label', group);
return el; return el;
} }
function createSelOpt(opt, title) function createSelOpt(opt, title)
{ {
var el = document.createElement('option'); var el = document.createElement('option');
el.setAttribute('value', opt); el.setAttribute('value', opt);
if (typeof title == 'undefined') if (typeof title == 'undefined')
el.innerHTML = opt; el.innerHTML = opt;
else else
el.innerHTML = title; el.innerHTML = title;

View File

@ -58,7 +58,7 @@
$('#wizp2_body').append('<div class="form-group"><label>'+$.i18n('wiz_rgb_switchevery')+'</label><div class="input-group" style="width:100px"><select id="wiz_switchtime_select" class="form-control"></select><div class="input-group-addon">'+$.i18n('edt_append_s')+'</div></div></div>'); $('#wizp2_body').append('<div class="form-group"><label>'+$.i18n('wiz_rgb_switchevery')+'</label><div class="input-group" style="width:100px"><select id="wiz_switchtime_select" class="form-control"></select><div class="input-group-addon">'+$.i18n('edt_append_s')+'</div></div></div>');
$('#wizp2_body').append('<canvas id="wiz_canv_color" width="100" height="100" style="border-radius:60px;background-color:red; display:block; margin: 10px 0;border:4px solid grey;"></canvas><label>'+$.i18n('wiz_rgb_q')+'</label>'); $('#wizp2_body').append('<canvas id="wiz_canv_color" width="100" height="100" style="border-radius:60px;background-color:red; display:block; margin: 10px 0;border:4px solid grey;"></canvas><label>'+$.i18n('wiz_rgb_q')+'</label>');
$('#wizp2_body').append('<table class="table borderless" style="width:200px"><tbody><tr><td class="ltd"><label>'+$.i18n('wiz_rgb_qrend')+'</label></td><td class="itd"><select id="wiz_r_select" class="form-control wselect"></select></td></tr><tr><td class="ltd"><label>'+$.i18n('wiz_rgb_qgend')+'</label></td><td class="itd"><select id="wiz_g_select" class="form-control wselect"></select></td></tr></tbody></table>'); $('#wizp2_body').append('<table class="table borderless" style="width:200px"><tbody><tr><td class="ltd"><label>'+$.i18n('wiz_rgb_qrend')+'</label></td><td class="itd"><select id="wiz_r_select" class="form-control wselect"></select></td></tr><tr><td class="ltd"><label>'+$.i18n('wiz_rgb_qgend')+'</label></td><td class="itd"><select id="wiz_g_select" class="form-control wselect"></select></td></tr></tbody></table>');
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saverestart')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_checkok" style="display:none" data-dismiss="modal"><i class="fa fa-fw fa-check"></i>'+$.i18n('general_btn_ok')+'</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>') $('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_save')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_checkok" style="display:none" data-dismiss="modal"><i class="fa fa-fw fa-check"></i>'+$.i18n('general_btn_ok')+'</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>')
//open modal //open modal
$("#wizard_modal").modal({ $("#wizard_modal").modal({
@ -155,7 +155,6 @@
resetWizard(); resetWizard();
serverConfig.device.colorOrder = new_rgb_order; serverConfig.device.colorOrder = new_rgb_order;
requestWriteConfig({"device" : serverConfig.device}); requestWriteConfig({"device" : serverConfig.device});
setTimeout(initRestart, 100);
}); });
} }
@ -416,7 +415,7 @@
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('wiz_cc_title')+'</h4><p>'+$.i18n('wiz_cc_intro1')+'</p><label>'+$.i18n('wiz_cc_kwebs')+'</label><input class="form-control" style="width:170px;margin:auto" id="wiz_cc_kodiip" type="text" placeholder="'+kodiAddress+'" value="'+kodiAddress+'" /><span id="kodi_status"></span><span id="multi_cali"></span>'); $('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">'+$.i18n('wiz_cc_title')+'</h4><p>'+$.i18n('wiz_cc_intro1')+'</p><label>'+$.i18n('wiz_cc_kwebs')+'</label><input class="form-control" style="width:170px;margin:auto" id="wiz_cc_kodiip" type="text" placeholder="'+kodiAddress+'" value="'+kodiAddress+'" /><span id="kodi_status"></span><span id="multi_cali"></span>');
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont" disabled="disabled"><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>'); $('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont" disabled="disabled"><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="wiz_cc_desc" style="font-weight:bold"></div><div id="editor_container_wiz"></div>'); $('#wizp2_body').html('<div id="wiz_cc_desc" style="font-weight:bold"></div><div id="editor_container_wiz"></div>');
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_back"><i class="fa fa-fw fa-chevron-left"></i>'+$.i18n('general_btn_back')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_next">'+$.i18n('general_btn_next')+'<i style="margin-left:4px;"class="fa fa-fw fa-chevron-right"></i></button><button type="button" class="btn btn-warning" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_saverestart')+'</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>') $('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_back"><i class="fa fa-fw fa-chevron-left"></i>'+$.i18n('general_btn_back')+'</button><button type="button" class="btn btn-primary" id="btn_wiz_next">'+$.i18n('general_btn_next')+'<i style="margin-left:4px;"class="fa fa-fw fa-chevron-right"></i></button><button type="button" class="btn btn-warning" 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>')
//open modal //open modal
$("#wizard_modal").modal({ $("#wizard_modal").modal({
@ -500,7 +499,6 @@
$('#btn_wiz_save').off().on('click',function() { $('#btn_wiz_save').off().on('click',function() {
requestWriteConfig(wiz_editor.getValue()); requestWriteConfig(wiz_editor.getValue());
resetWizard(); resetWizard();
setTimeout(initRestart, 200);
}); });
wiz_editor.on("change", function(e){ wiz_editor.on("change", function(e){
@ -538,7 +536,7 @@
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold">'+$.i18n('wiz_hue_desc2')+'</p></div>'); $('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold">'+$.i18n('wiz_hue_desc2')+'</p></div>');
createTable("lidsh", "lidsb", "hue_ids_t"); createTable("lidsh", "lidsb", "hue_ids_t");
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lightid_title'),$.i18n('wiz_hue_pos'),$.i18n('wiz_hue_ident')], true)); $('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lightid_title'),$.i18n('wiz_hue_pos'),$.i18n('wiz_hue_ident')], 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_saverestart')+'</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>'); $('#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>');
$('#wizp3_body').html('<span>'+$.i18n('wiz_hue_press_link')+'</span> <br /><br /><center><span id="connectionTime"></span><br /><i class="fa fa-cog fa-spin" style="font-size:100px"></i></center>'); $('#wizp3_body').html('<span>'+$.i18n('wiz_hue_press_link')+'</span> <br /><br /><center><span id="connectionTime"></span><br /><i class="fa fa-cog fa-spin" style="font-size:100px"></i></center>');
//open modal //open modal
@ -751,7 +749,7 @@
serverConfig.smoothing.enable = false; serverConfig.smoothing.enable = false;
requestWriteConfig(serverConfig, true); requestWriteConfig(serverConfig, true);
setTimeout(initRestart,200); resetWizard();
}); });
$('#btn_wiz_abort').off().on('click', resetWizard); $('#btn_wiz_abort').off().on('click', resetWizard);

View File

@ -1,5 +0,0 @@
#!/usr/bin/env python
print ("hello world");

View File

@ -0,0 +1,112 @@
#!/bin/bash -e
DOCKER="docker"
# Git repo url of Hyperion
GIT_REPO_URL="https://github.com/hyperion-project/hyperion.ng.git"
# cmake build type
BUILD_TYPE="Release"
# the image tag at hyperionorg/hyperion-ci
BUILD_TARGET="ubuntu1604"
# build packages (.deb .zip ...)
BUILD_PACKAGES=true
# packages string inserted to cmake cmd
PACKAGES=""
# get current path to this script, independent of calling
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}"
if ([ -h "${SCRIPT_PATH}" ]); then
while([ -h "${SCRIPT_PATH}" ]); do cd `dirname "$SCRIPT_PATH"`;
SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
set +e
$DOCKER ps >/dev/null 2>&1
if [ $? != 0 ]; then
DOCKER="sudo docker"
fi
# check if docker is available
if ! $DOCKER ps >/dev/null; then
echo "Error connecting to docker:"
$DOCKER ps
printHelp
exit 1
fi
set -e
# help print function
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 Ubuntu 16.04 (x64) or higher.
## Supports Raspberry Pi (armv6) cross compilation (Raspbian Stretch)
##
## Homepage: https://www.hyperion-project.org
## Forum: https://forum.hyperion-project.org
########################################################
# These are possible arguments to modify the script behaviour with their default values
#
# docker-compile.sh -h # Show this help message
# docker-compile.sh -t ubuntu1604 # The docker tag, one of ubuntu1604 | cross-qemu-rpistretch
# docker-compile.sh -b Release # cmake Release or Debug build
# docker-compile.sh -p true # If true build packages with CPack
# More informations to docker tags at: https://hub.docker.com/r/hyperionorg/hyperion-ci/"
}
while getopts t:b:p:h option
do
case "${option}"
in
t) BUILD_TARGET=${OPTARG};;
b) BUILD_TYPE=${OPTARG};;
p) BUILD_PACKAGES=${OPTARG};;
h) printHelp; exit 0;;
esac
done
# determine package creation
if [ $BUILD_PACKAGES == "true" ]; then
PACKAGES="package"
fi
echo "---> Initilize with BUILD_TARGET=${BUILD_TARGET}, BUILD_TYPE=${BUILD_TYPE}, BUILD_PACKAGES=${BUILD_PACKAGES}"
# cleanup deploy folder, create folder for ownership
sudo rm -fr $SCRIPT_PATH/deploy >/dev/null 2>&1
mkdir $SCRIPT_PATH/deploy >/dev/null 2>&1
# get Hyperion source, cleanup previous folder
echo "---> Downloading Hyperion source code from ${GIT_REPO_URL}"
sudo rm -fr $SCRIPT_PATH/hyperion >/dev/null 2>&1
git clone --recursive --depth 1 -q $GIT_REPO_URL $SCRIPT_PATH/hyperion || { echo "---> Failed to download Hyperion source code! Abort"; exit 1; }
# start compilation
# Remove container after stop
# Mount /deploy to /deploy
# Mount source dir to /source
# Target docker image
# execute inside container all commands on bash
echo "---> Startup docker..."
$DOCKER run --rm \
-v "${SCRIPT_PATH}/deploy:/deploy" \
-v "${SCRIPT_PATH}/hyperion:/source:ro" \
hyperionorg/hyperion-ci:$BUILD_TARGET \
/bin/bash -c "mkdir build && cp -r /source/. /build &&
cd /build && mkdir build && cd build &&
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .. || exit 2 &&
make -j $(nproc) ${PACKAGES} || exit 3 &&
echo '---> Copy binaries and packages to host folder: ${SCRIPT_PATH}/deploy' &&
cp -v /build/build/bin/h* /deploy/ 2>/dev/null || : &&
cp -v /build/build/Hyperion-* /deploy/ 2>/dev/null || : &&
exit 0;
exit 1 " || { echo "---> Hyperion compilation failed! Abort"; exit 4; }
# overwrite file owner to current user
sudo chown -fR $(stat -c "%U:%G" $SCRIPT_PATH/deploy) $SCRIPT_PATH/deploy
echo "---> Script finished, view folder ${SCRIPT_PATH}/deploy for compiled packages and binaries"
exit 0

View File

@ -1,165 +0,0 @@
#!/bin/bash
# Script to add a second or more hyperion instance(s) to the corresponding system service
# Make sure /sbin is on the path (for service to find sub scripts)
PATH="/sbin:$PATH"
#Check, if script is running as root
if [ $(id -u) != 0 ]; then
echo '---> Critical Error: Please run the script as root (sudo sh ./setup_hyperion_forward.sh) -> abort'
exit 1
fi
#Welcome message
echo '*******************************************************************************'
echo 'This setup script will duplicate the hyperion service'
echo 'Choose the name(s) for one or more config files - one service for each config'
echo 'Created by brindosch - hyperion-project.org - the official Hyperion source.'
echo '*******************************************************************************'
#Prompt for confirmation to proceed
while true
do
echo -n "---> Do you really want to proceed? (y or n) :"
read CONFIRM
case $CONFIRM in
y|Y|YES|yes|Yes) break ;;
n|N|no|NO|No)
echo "---> Aborting - you entered \"$CONFIRM\""
exit
;;
*) echo "-> Please enter only y or n"
esac
done
echo "---> You entered \"$CONFIRM\". We will proceed!"
echo ""
#Check which system we are on
OS_OPENELEC=`grep -m1 -c 'OpenELEC\|RasPlex\|LibreELEC' /etc/issue`
USE_SYSTEMD=`grep -m1 -c systemd /proc/1/comm`
USE_INITCTL=`which /sbin/initctl | wc -l`
USE_SERVICE=`which /usr/sbin/service | wc -l`
#Setting up the paths to service files
if [ $USE_INITCTL -eq 1 ]; then
SERVICEPATH=/etc/init
elif [ $OS_OPENELEC -eq 1 ]; then
SERVICEPATH=/storage/.config
elif [ $USE_SYSTEMD -eq 1 ]; then
SERVICEPATH=/etc/systemd/system
elif [ $USE_SERVICE -eq 1 ]; then
SERVICEPATH/etc/init.d
fi
#Setting up the default PROTO/JSON ports
JSONPORT=19444
PROTOPORT=19445
# and service count
SERVICEC=1
#Setting up the paths to config files
if [ $OS_OPENELEC -eq 1 ]; then
CONFIGPATH=/storage/.config
else CONFIGPATH=/opt/hyperion/config
fi
#Ask the user for some informations regarding the setup
echo "---> Please enter the config name(s) you want to create"
echo "---> Information: One name creates one service and two names two services etc"
echo '---> Please enter them seperated with a space in a one line row!'
echo '---> example: hyperion.philipshue_1.json hyperion.AtmoOrb_2.json hypthreeconf.json'
echo '---> In any case, add ".json" at the end of each file name'
read -p 'Config file name(s): ' FILENAMES
echo '---> Thank you, we will modify your Hyperion installation now'
sleep 2
#Processing input
set $FILENAMES
FWCOUNT=${#}
#Convert all old config file paths to make sure this script is working (default for new installs with 1.02.0 and higher)
if [ $USE_INITCTL -eq 1 ]; then
sed -i "s|/etc/hyperion.config.json|/etc/hyperion/hyperion.config.json|g" $SERVICEPATH/hyperion.conf
elif [ $OS_OPENELEC -eq 1 ]; then
sleep 0
elif [ $USE_SYSTEMD -eq 1 ]; then
sed -i "s|/etc/hyperion.config.json|/etc/hyperion/hyperion.config.json|g" $SERVICEPATH/hyperion.service
elif [ $USE_SERVICE -eq 1 ]; then
sed -i "s|/etc/hyperion.config.json|/etc/hyperion/hyperion.config.json|g" $SERVICEPATH/hyperion
fi
#Processing service files
if [ $USE_INITCTL -eq 1 ]; then
echo "---> Initctl detected, processing service files"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "Processing service ${SERVICEC}: \"hyperion_fw${SERVICEC}.conf\""
if [ -e "${SERVICEPATH}/hyperion_fw${SERVICEC}.conf" ]; then
echo "Service was already created - skipped"
echo "Input \"${1}\" was skipped"
else
echo "Create ${SERVICEPATH}/hyperion_fw${SERVICEC}.conf"
cp -s $SERVICEPATH/hyperion.conf $SERVICEPATH/hyperion_fw$SERVICEC.conf
echo "Config name changed to \"${1}\" inside \"hyperion_fw${SERVICEC}.conf\""
sed -i "s/hyperion.config.json/$1/g" $SERVICEPATH/hyperion_fw$SERVICEC.conf
initctl reload-configuration
fi
shift
SERVICEC=$((SERVICEC + 1))
done
elif [ $OS_OPENELEC -eq 1 ]; then
echo "---> OE/LE detected, processing autostart.sh"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "${SERVICEC}. processing OE autostart.sh entry \"${1}\""
OE=`grep -m1 -c ${1} $SERVICEPATH/autostart.sh`
if [ $OE -eq 0 ]; then
echo "Add config name \"${1}\" to \"autostart.sh\""
echo "/storage/hyperion/bin/hyperiond.sh /storage/.config/${1} > /storage/logfiles/hyperion_fw${SERVICEC}.log 2>&1 &" >> /storage/.config/autostart.sh
else
echo "\"${1}\" was already added - skipped"
fi
shift
SERVICEC=$((SERVICEC + 1))
done
elif [ $USE_SYSTEMD -eq 1 ]; then
echo "---> Systemd detected, processing service files"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "Processing service ${SERVICEC}: \"hyperion_fw${SERVICEC}.service\""
if [ -e "${SERVICEPATH}/hyperion_fw${SERVICEC}.service" ]; then
echo "Service was already created - skipped"
echo "Input \"${1}\" was skipped"
else
echo "Create ${SERVICEPATH}/hyperion_fw${SERVICEC}.service"
cp -s $SERVICEPATH/hyperion.service $SERVICEPATH/hyperion_fw$SERVICEC.service
echo "Config name changed to \"${1}\" inside \"hyperion_fw${SERVICEC}.service\""
sed -i "s/hyperion.config.json/$1/g" $SERVICEPATH/hyperion_fw$SERVICEC.service
systemctl -q enable hyperion_fw$SERVICEC.service
fi
shift
SERVICEC=$((SERVICEC + 1))
done
elif [ $USE_SERVICE -eq 1 ]; then
echo "---> Init.d detected, processing service files"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "Processing service ${SERVICEC}: \"hyperion_fw${SERVICEC}\""
if [ -e "${SERVICEPATH}/hyperion_fw${SERVICEC}" ]; then
echo "Service was already created - skipped"
echo "Input \"${1}\" was skipped"
else
echo "Create ${SERVICEPATH}/hyperion_fw${SERVICEC}"
cp -s $SERVICEPATH/hyperion $SERVICEPATH/hyperion_fw$SERVICEC
echo "Config name changed to \"${1}\" inside \"hyperion_fw${SERVICEC}\""
sed -i "s/hyperion.config.json/$1/g" $SERVICEPATH/hyperion_fw$SERVICEC
update-rc.d hyperion_fw$SERVICEC defaults 98 02
fi
shift
SERVICEC=$((SERVICEC + 1))
done
fi
#Service creation done
echo '*******************************************************************************'
echo 'Script done all actions - all input processed'
echo 'Now upload your configuration(s) with HyperCon at the SSH Tab'
echo 'All created Hyperion services will start with your chosen confignames'
echo 'Wiki: wiki.hyperion-project.org Webpage: www.hyperion-project.org'
echo '*******************************************************************************'

View File

@ -1,13 +1,14 @@
[Unit] [Unit]
Description=Hyperion ambient light systemd service Description=Hyperion ambient light systemd service for user %i
After=network.target After=network.target
[Service] [Service]
ExecStart=/usr/bin/hyperiond ExecStart=/usr/bin/hyperiond
WorkingDirectory=/usr/share/hyperion/bin WorkingDirectory=/usr/share/hyperion/bin
User=%i
TimeoutStopSec=5 TimeoutStopSec=5
KillMode=mixed KillMode=mixed
Restart=always Restart=on-failure
RestartSec=2 RestartSec=2
[Install] [Install]

View File

@ -9,7 +9,7 @@ Environment=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
ExecStart=./hyperiond /storage/.config/hyperion/hyperion.config.json ExecStart=./hyperiond /storage/.config/hyperion/hyperion.config.json
TimeoutStopSec=5 TimeoutStopSec=5
KillMode=mixed KillMode=mixed
Restart=always Restart=on-failure
RestartSec=2 RestartSec=2
[Install] [Install]

View File

@ -0,0 +1,23 @@
# - Find package for .deb building
# Find the .deb building executable and extract the version number
#
# OUTPUT Variables
#
# DEB_BUILDER_FOUND
# True if the deb builder package was found
# DEB_BUILDER_EXECUTABLE
# The deb builder executable location
# DEB_BUILDER_VERSION
# A string denoting the version of deb builder that has been found
find_program ( DEB_BUILDER_EXECUTABLE dpkg-deb )
if ( DEB_BUILDER_EXECUTABLE )
SET( DEB_BUILDER_FOUND TRUE )
execute_process ( COMMAND ${DEB_BUILDER_EXECUTABLE} --version OUTPUT_VARIABLE DEB_VERSION_RAW ERROR_QUIET )
if (DEB_VERSION_RAW)
string ( REGEX REPLACE "^RPM-Version ([0-9]+.[0-9]+.[0-9]+),.*" "\\1" DEB_BUILDER_VERSION ${DEB_VERSION_RAW})
else ()
set ( DEB_BUILDER_VERSION "unknown" )
endif()
endif ()

View File

@ -1,9 +1,10 @@
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 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 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 )
STRING ( STRIP "${BUILD_ID}" BUILD_ID ) STRING ( STRIP "${BUILD_ID}" BUILD_ID )
STRING ( STRIP "${VERSION_ID}" VERSION_ID ) STRING ( STRIP "${VERSION_ID}" VERSION_ID )
SET ( HYPERION_BUILD_ID "${VERSION_ID} (${BUILD_ID})" ) STRING ( STRIP "${GIT_REMOTE_PATH}" GIT_REMOTE_PATH )
SET ( HYPERION_BUILD_ID "${VERSION_ID} (${BUILD_ID}) Git Remote: ${GIT_REMOTE_PATH}" )
message ( STATUS "Current Version: ${HYPERION_BUILD_ID}" ) message ( STATUS "Current Version: ${HYPERION_BUILD_ID}" )

View File

@ -0,0 +1,23 @@
# - Find package for .rpm building
# Find the .rpm building executable and extract the version number
#
# OUTPUT Variables
#
# RPM_BUILDER_FOUND
# True if the rpm package was found
# RPM_BUILDER_EXECUTABLE
# The rpm executable location
# RPM_BUILDER_VERSION
# A string denoting the version of rpm that has been found
find_program ( RPM_BUILDER_EXECUTABLE rpm )
if ( RPM_BUILDER_EXECUTABLE )
SET( RPM_BUILDER_FOUND TRUE )
execute_process ( COMMAND ${RPM_BUILDER_EXECUTABLE} --version OUTPUT_VARIABLE RPM_VERSION_RAW ERROR_QUIET )
if (RPM_VERSION_RAW)
string ( REGEX REPLACE "^RPM-Version ([0-9]+.[0-9]+.[0-9]+),.*" "\\1" RPM_BUILDER_VERSION ${RPM_VERSION_RAW})
else ()
set ( RPM_BUILDER_VERSION "unknown" )
endif()
endif ()

View File

@ -6,6 +6,7 @@ install_file()
dest="$2" dest="$2"
if [ ! -e "$dest" ] if [ ! -e "$dest" ]
then
cp "$src" "${dest}" cp "$src" "${dest}"
return 1 return 1
else else
@ -15,10 +16,7 @@ install_file()
} }
echo "--- hyperion ambient light postinstall ---" echo "---Hyperion ambient light postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
mkdir -p /usr/share/hyperion/custom-effects
#check system #check system
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835' /proc/cpuinfo` CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835' /proc/cpuinfo`
@ -27,42 +25,54 @@ CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l`
#Check for a bootloader as Berryboot #Check for a bootloader as Berryboot
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab) BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab)
#get current system ip + add default port #get current system ip
address=$(ip -o -4 a | awk '$2 == "eth0" { gsub(/\/.*/, "", $4); print $4 }')":8099" NET_IP=`hostname -I | cut -d " " -f1`
#check if hyperion is running # search for users in system, returns first entry
HYPERION_RUNNING=false FOUND_USR=`who | grep -o '^\w*\b'` || "root"
pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true
# determine if we should use a service
ENABLE_SERVICE=0
STARTUP_MSG="echo ---> You can start Hyperion from your menu now"
if [ $CPU_RPI -eq 1 ]; then
ENABLE_SERVICE=1
STARTUP_MSG="echo ---> Hyperion has been installed as service, it will start on each system startup"
fi
start_msg="" start_msg=""
restart_msg="" restart_msg=""
SERVICE_POSTFIX=""
if grep -m1 systemd /proc/1/comm > /dev/null if grep -m1 systemd /proc/1/comm > /dev/null
then then
echo "--> init deamon: systemd" echo "---> init deamon: systemd"
# systemd # systemd
$HYPERION_RUNNING && systemctl stop hyperiond 2> /dev/null install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond@.service
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond.service && systemctl -q enable hyperiond.service # service registration just on Raspberry Pi, probably need to ask the user how we should use the service. TODO service start in user login scope eg for x11?!
start_msg="--> systemctl start hyperiond" if [ $ENABLE_SERVICE -eq 1 ]; then
systemctl start hyperiond systemctl enable hyperiond"@${FOUND_USR}".service
start_msg="--> systemctl start hyperiond for user ${FOUND_USR}"
systemctl start hyperiond"@${FOUND_USR}"
fi
elif [ -e /sbin/initctl ] elif [ -e /sbin/initctl ]
then then
echo "--> init deamon: upstart" echo "---> init deamon: upstart"
# upstart # upstart
$HYPERION_RUNNING && initctl stop hyperiond if [ $ENABLE_SERVICE -eq 1 ]; then
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
start_msg="--> initctl start hyperiond" start_msg="--> initctl start hyperiond"
initctl start hyperiond initctl start hyperiond
fi
else else
echo "--> init deamon: sysV" echo "---> init deamon: sysV"
# sysV # sysV
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null if [ $ENABLE_SERVICE -eq 1 ]; then
install_file /usr/share/hyperion/service/hyperion.init /etc/init.d/hyperiond && chmod +x /etc/init.d/hyperiond && update-rc.d hyperiond defaults 98 02 install_file /usr/share/hyperion/service/hyperion.init /etc/init.d/hyperiond && chmod +x /etc/init.d/hyperiond && update-rc.d hyperiond defaults 98 02
start_msg="--> service hyperiond start" start_msg="---> service hyperiond start"
service hyperiond start service hyperiond start
fi
fi fi
#cleanup #cleanup
@ -79,7 +89,16 @@ ln -fs $BINSP/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null
ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
ln -fs $BINSP/hyperion-qt $BINTP/hyperion-qt 2>/dev/null
# install desktop icons
echo "---> Install Hyperion desktop icons"
mkdir /usr/share/pixmaps/hyperion 2>/dev/null
cp /usr/share/hyperion/desktop/*.png /usr/share/pixmaps/hyperion 2>/dev/null
desktop-file-install /usr/share/hyperion/desktop/hyperiond.desktop 2>/dev/null
# cleanup desktop icons
rm -r /usr/share/hyperion/desktop 2>/dev/null
#Check, if dtparam=spi=on is in place #Check, if dtparam=spi=on is in place
if [ $CPU_RPI -eq 1 ]; then if [ $CPU_RPI -eq 1 ]; then
@ -100,9 +119,14 @@ if [ $CPU_RPI -eq 1 ]; then
fi fi
fi fi
echo ${start_msg}
echo "-----------------------------------------------------------------------------" echo "-----------------------------------------------------------------------------"
echo "--> Hyperion has been installed/updated!" echo "---> Hyperion has been installed/updated!"
echo "--> For configuration, visit with your browser: ${address}" echo "---> "
$STARTUP_MSG
echo "---> For configuration, visit with your browser: ${NET_IP}:8090"
echo "---> or if already used by another service try: ${NET_IP}:8091"
$REBOOTMESSAGE $REBOOTMESSAGE
echo "-----------------------------------------------------------------------------" echo "-----------------------------------------------------------------------------"
echo "Webpage: www.hyperion-project.org" echo "Webpage: www.hyperion-project.org"
@ -110,28 +134,14 @@ echo "Wiki: wiki.hyperion-project.org"
echo "Forum: forum.hyperion-project.org" echo "Forum: forum.hyperion-project.org"
echo "-----------------------------------------------------------------------------" echo "-----------------------------------------------------------------------------"
# try to open the browser for desktops. TODO: add headless detection(?)
if [ $CPU_X32X64 -eq 1]
echo "--> Will open browser with target: ${address}"
if [[ -e /usr/bin/xdg-open ]]
then
xdg-open http://"$address"
elif [[ -e /usr/bin/x-www-browser ]]
then
x-www-browser http://"$address"
elif [[ -e /usr/bin/www-browser ]]
then
www-browser http://"$address"
fi
fi
if [ -e /opt/hyperion/ ] if [ -e /opt/hyperion/ ]
then then
echo echo
echo "---------------------------------------------------------------------------------" echo "---------------------------------------------------------------------------------"
echo "- It seemd that you have an older version of hyperion installed in /opt/hyerion -" echo "- It seemd that you have an older version of hyperion installed in /opt/hyperion -"
echo "- please remove it and check your config to avoid problems -" echo "- please remove it to avoid problems -"
echo "---------------------------------------------------------------------------------" echo "---------------------------------------------------------------------------------"
fi fi
exit 0

View File

@ -1,51 +1,61 @@
#!/bin/sh #!/bin/sh
# check which init script we should use echo "---Hyperion ambient light preinst ---"
USE_SYSTEMD=`grep -m1 -c systemd /proc/1/comm`
USE_INITCTL=`which /sbin/initctl | wc -l`
USE_SERVICE=`which /usr/sbin/service | wc -l`
#check for hyperion install # search for users in system, returns first entry
if [ -d /usr/share/hyperion/bin ];then FOUND_USR=`who | grep -o '^\w*\b'` || "root"
if [ -e /etc/hyperion/hyperion.config.json ];then
file=`grep -m1 -c '"general"' /etc/hyperion/hyperion.config.json`
if [ $file -ne 1 ]; then
echo "--> It seems you are running an old version of Hyperion (1.X). Will create a backup at /usr/share/hyperion/Backup_Hyperion_1.0 and reset configuration / system service"
# Stop hyperion daemon if it is running
echo '---> Stop Hyperion, if necessary'
if [ $USE_SYSTEMD -eq 1 ]; then
service hyperion stop 2>/dev/null
elif [ $USE_INITCTL -eq 1 ]; then
/sbin/initctl stop hyperion 2>/dev/null
elif [ $USE_SERVICE -eq 1 ]; then
/usr/sbin/service hyperion stop 2>/dev/null
fi
#Backup
echo "--> Move old config(s) and files to /usr/share/hyperion/Backup_Hyperion_1.0"
mkdir /usr/share/hyperion/Backup_Hyperion_1.0
mv /usr/share/hyperion /usr/share/hyperion/Backup_Hyperion_1.0
mv /etc/hyperion/* /usr/share/hyperion/Backup_Hyperion_1.0
#Disabling and delete service files # stop running daemon before we install
if [ $USE_SYSTEMD -eq 1 ]; then if pgrep hyperiond > /dev/null 2>&1
# Delete and disable Hyperion systemd script then
echo '---> Delete and disable Hyperion systemd service' if grep -m1 systemd /proc/1/comm > /dev/null
systemctl disable hyperion.service then
rm -v /etc/systemd/system/hyperion* 2>/dev/null echo "--> stop init deamon: systemd"
elif [ $USE_INITCTL -eq 1 ]; then # systemd
echo '---> Delete and disable Hyperion initctl script' systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null
rm -v /etc/init/hyperion* 2>/dev/null
initctl reload-configuration elif [ -e /sbin/initctl ]
elif [ $USE_SERVICE -eq 1 ]; then then
# Delete and disable Hyperion init.d script echo "--> stop init deamon: upstart"
echo '---> Delete and disable Hyperion init.d script' # upstart
update-rc.d -f hyperion remove initctl stop hyperiond
rm /etc/init.d/hyperion* 2>/dev/null
fi else
echo "--> stop init deamon: sysV"
echo "--> Hyperion 1.0 installation has been moved" # sysV
fi service hyperiond stop 2>/dev/null
fi fi
fi fi
# In case we don't use a service kill all instances
killall hyperiond 2> /dev/null
# overwrite last return code
exit 0
#$USR=hyperionIS;
#addToGroup()
##{
# getent group $1 && adduser $USR $1;
#}
#check if user exists
#if id $USR >/dev/null 2>&1; then
# echo "--> hyperion user exists, skip creation";
#else
## create user
# echo "--> Create Hyperion user";
# adduser --system --group $USR;
#fi
# add user to groups if required
## secondary user groups that are required to access system things
#addToGroup(dialout);
#addToGroup(video);
#addToGroup(audio);
#addToGroup(systemd-journal);
# platform specific groups
#addToGroup(i2c);
#addToGroup(spi);
#addToGroup(gpio);

50
cmake/debian/prerm Normal file
View File

@ -0,0 +1,50 @@
#!/bin/sh
echo "---Hyperion ambient light prerm ---"
# search for users in system, returns first entry
FOUND_USR=`who | grep -o '^\w*\b'` || "root"
# stop running daemon before we delete it
HYPERION_RUNNING=false
pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true
if grep -m1 systemd /proc/1/comm > /dev/null
then
echo "---> stop init deamon: systemd"
# systemd
$HYPERION_RUNNING && systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null
# disable user specific symlink
echo "---> Disable service and remove entry"
systemctl -q disable hyperiond"@${FOUND_USR}"
rm -v /etc/systemd/system/hyperiond@.service 2>/dev/null
elif [ -e /sbin/initctl ]
then
echo "---> stop init deamon: upstart"
# upstart
$HYPERION_RUNNING && initctl stop hyperiond
echo "---> Remove upstart service"
rm -v /etc/init/hyperion* 2>/dev/null
initctl reload-configuration
else
echo "---> stop init deamon: sysV"
# sysV
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null
echo "---> Remove sysV service"
update-rc.d -f hyperion remove
rm /etc/init.d/hyperion* 2>/dev/null
fi
# In case we don't use a service kill all instances
killall hyperiond 2> /dev/null
# delete desktop icons; desktop-file-edit is a workaround to hide the entry and delete it afterwards manual.
# TODO Better way for deletion and keep the desktop in sync without logout/login or desktop dependend cmds?
echo "---> Delete Hyperion desktop icons"
desktop-file-edit --set-key=NoDisplay --set-value=true /usr/share/applications/hyperiond.desktop 2>/dev/null
rm -v /usr/share/applications/hyperion* 2>/dev/null
rm -rv /usr/share/pixmaps/hyperion 2>/dev/null
exit 0

View File

@ -0,0 +1,11 @@
[Desktop Entry]
Name=Hyperion
GenericName=Hyperion Ambient Lighting
Comment=Hyperion mimics the well known Ambilight from Philips
Icon=/usr/share/pixmaps/hyperion/hyperiond_128.png
Terminal=false
TryExec=hyperiond
Exec=hyperiond
Type=Application
StartupNotify=false
Categories=Application;

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,5 @@
#!/bin/sh
cd "$(dirname "$0")"
# Path to hyperiond!?
cd ../Resources/bin
exec ./hyperiond "$@"

View File

@ -1,38 +1,80 @@
# cmake file for generating distribution packages # cmake file for generating distribution packages
# default packages to build
IF (APPLE) IF (APPLE)
SET ( CPACK_GENERATOR "TGZ" "Bundle") # "RPM" SET ( CPACK_GENERATOR "TGZ" "Bundle")
ELSE() ELSEIF (UNIX)
SET ( CPACK_GENERATOR "DEB" "TGZ" "STGZ") # "RPM" SET ( CPACK_GENERATOR "TGZ" "STGZ")
ELSEIF (WIN32)
SET ( CPACK_GENERATOR "ZIP")
ENDIF() ENDIF()
SET ( CPACK_PACKAGE_NAME "hyperion" ) # Determine packages by found generator executables
find_package(RpmBuilder)
find_package(DebBuilder)
IF(RPM_BUILDER_FOUND)
message("CPACK: Found RPM builder")
SET ( CPACK_GENERATOR ${CPACK_GENERATOR} "RPM")
ENDIF()
IF(DEB_BUILDER_FOUND)
message("CPACK: Found DEB builder")
SET ( CPACK_GENERATOR ${CPACK_GENERATOR} "DEB")
ENDIF()
# Apply to all packages, some of these can be overwritten with generator specific content
# https://cmake.org/cmake/help/v3.5/module/CPack.html
SET ( CPACK_PACKAGE_NAME "Hyperion" )
SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an open source ambient light implementation" ) SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an open source ambient light implementation" )
SET ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" ) SET ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" )
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_VERSION_MAJOR}.${HYPERION_VERSION_MINOR}.${HYPERION_VERSION_PATCH}-${CMAKE_SYSTEM_NAME}")
SET ( CPACK_PACKAGE_CONTACT "packages@hyperion-project.org")
SET ( CPACK_PACKAGE_EXECUTABLES "hyperiond;Hyperion" )
SET ( CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources/icons/hyperion-icon-32px.png")
SET ( CPACK_PACKAGE_VERSION_MAJOR "${HYPERION_VERSION_MAJOR}")
SET ( CPACK_PACKAGE_VERSION_MINOR "${HYPERION_VERSION_MINOR}")
SET ( CPACK_PACKAGE_VERSION_PATCH "${HYPERION_VERSION_PATCH}")
SET ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" ) SET ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" )
SET ( CPACK_CREATE_DESKTOP_LINKS "hyperiond;Hyperion" )
SET ( CPACK_DEBIAN_PACKAGE_MAINTAINER "Hyperion Team")
SET ( CPACK_DEBIAN_PACKAGE_NAME "Hyperion" ) # Specific CPack Package Generators
SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst" ) # https://cmake.org/Wiki/CMake:CPackPackageGenerators
SET ( CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.hyperion-project.org" ) # .deb files for apt
SET ( CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a (>= 5.2.0), libqt5network5 (>= 5.2.0), libqt5gui5 (>= 5.2.0), libqt5serialport5 (>= 5.2.0), libavahi-core7 (>= 0.6.31), libavahi-compat-libdnssd1 (>= 0.6.31), libusb-1.0-0, libpython3.4, libc6" )
SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/prerm" )
SET ( CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a (>= 5.5.0), libqt5network5 (>= 5.5.0), libqt5gui5 (>= 5.5.0), libqt5serialport5 (>= 5.5.0), libqt5sql5 (>= 5.5.0), libqt5sql5-sqlite (>= 5.5.0), libavahi-core7 (>= 0.6.31), libavahi-compat-libdnssd1 (>= 0.6.31), libusb-1.0-0, libpython3.5, libc6" )
SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" )
SET ( CPACK_RPM_PACKAGE_NAME "Hyperion" ) # .rpm for rpm
SET ( CPACK_RPM_PACKAGE_URL "https://github.com/hyperion-project/hyperion.ng" ) # https://cmake.org/cmake/help/v3.5/module/CPackRPM.html
SET ( CPACK_RPM_PACKAGE_RELEASE 1)
SET ( CPACK_RPM_PACKAGE_LICENSE "MIT")
SET ( CPACK_RPM_PACKAGE_GROUP "Applications")
SET ( CPACK_RPM_PACKAGE_REQUIRES "qt5-qtbase >= 5.5.0, qt5-qtbase-gui >= 5.5.0, qt5-qtserialport >= 5.5.0, avahi-libs >= 0.6.31, avahi-compat-libdns_sd >= 0.6.31, libusbx, python35 >= 3.5.0")
# Notes: This is a dependency list for Fedora 27, different .rpm OSes use different names for their deps
SET ( CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/preinst" )
SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" ) SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" )
SET ( CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/prerm" )
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion") # OSX "Bundle" generator TODO Add more osx generators
SET ( CPACK_PACKAGE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Hyperion.icns ) # https://cmake.org/cmake/help/v3.10/module/CPackBundle.html
SET ( CPACK_BUNDLE_NAME "Hyperion" ) SET ( CPACK_BUNDLE_NAME "Hyperion" )
SET ( CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Hyperion.icns ) SET ( CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/osxbundle/Hyperion.icns )
SET ( CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Info.plist ) SET ( CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/cmake/osxbundle/Info.plist )
#SET ( CPACK_BUNDLE_STARTUP_COMMAND - path to a file that will be executed when the user opens the bundle. Could be a shell-script or a binary. ) SET ( CPACK_BUNDLE_STARTUP_COMMAND "${CMAKE_SOURCE_DIR}/cmake/osxbundle/launch.sh" )
SET(CPACK_PACKAGE_VERSION_MAJOR "${HYPERION_VERSION_MAJOR}") # NSIS for windows, requires NSIS TODO finish
SET(CPACK_PACKAGE_VERSION_MINOR "${HYPERION_VERSION_MINOR}") SET ( CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/installer.ico")
SET(CPACK_PACKAGE_VERSION_PATCH "${HYPERION_VERSION_PATCH}") SET ( CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/uninstaller.ico")
#SET ( CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/installer.bmp") #bmp required? If so, wrap in WIN32 check else: Use default icon instead
SET ( CPACK_NSIS_MODIFY_PATH ON)
SET ( CPACK_NSIS_DISPLAY_NAME "Hyperion Installer")
SET ( CPACK_NSIS_INSTALLED_ICON_NAME "Link to .exe")
SET ( CPACK_NSIS_HELP_LINK "https://www.hyperion-project.org")
SET ( CPACK_NSIS_URL_INFO_ABOUT "https://www.hyperion-project.org")
# define the install components
SET ( CPACK_COMPONENTS_ALL "${PLATFORM}" ) SET ( CPACK_COMPONENTS_ALL "${PLATFORM}" )
SET ( CPACK_ARCHIVE_COMPONENT_INSTALL ON ) SET ( CPACK_ARCHIVE_COMPONENT_INSTALL ON )
SET ( CPACK_DEB_COMPONENT_INSTALL ON ) SET ( CPACK_DEB_COMPONENT_INSTALL ON )

View File

@ -5,53 +5,143 @@ install_file()
src="$1" src="$1"
dest="$2" dest="$2"
if [ -e "$dest" ] && ! cmp --quiet "$src" "$dest" if [ ! -e "$dest" ]
then then
cp "$src" "${dest}.new"
else
cp "$src" "${dest}" cp "$src" "${dest}"
return 1
else
echo "--> Service file already exists, skip creation"
return 0
fi fi
} }
echo "--- hyperion ambilight postinstall ---" echo "---Hyperion ambient light postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
install_file /usr/share/hyperion/config/hyperion.config.json /etc/hyperion/hyperion.config.json
#check system
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835' /proc/cpuinfo`
CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l`
#Check for a bootloader as Berryboot
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab)
#get current system ip
NET_IP=`hostname -I | cut -d " " -f1`
# search for users in system, returns first entry
FOUND_USR=`who | grep -o '^\w*\b'` || "root"
# determine if we should use a service
ENABLE_SERVICE=0
STARTUP_MSG="echo ---> You can start Hyperion from your menu now"
if [ $CPU_RPI -eq 1 ]; then
ENABLE_SERVICE=1
STARTUP_MSG="echo ---> Hyperion has been installed as service, it will start on each system startup"
fi
start_msg=""
restart_msg=""
if grep -m1 systemd /proc/1/comm > /dev/null if grep -m1 systemd /proc/1/comm > /dev/null
then then
echo "---> init deamon: systemd"
# systemd # systemd
echo install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond@.service
systemctl stop hyperion 2> /dev/null # service registration just on Raspberry Pi, probably need to ask the user how we should use the service. TODO service start in user login scope eg for x11?!
install_file /usr/share/hyperion/service/hyperion.systemd.sh /etc/systemd/system/hyperion.service if [ $ENABLE_SERVICE -eq 1 ]; then
systemctl -q enable hyperion.service systemctl enable hyperiond"@${FOUND_USR}".service
# if [ $OS_OSMC -eq 1 ]; then start_msg="--> systemctl start hyperiond for user ${FOUND_USR}"
# echo '---> Modify systemd script for OSMC usage' systemctl start hyperiond"@${FOUND_USR}"
# # Wait until kodi is sarted (for kodi checker) fi
# sed -i '/After = mediacenter.service/d' /etc/systemd/system/hyperion.service
# sed -i '/Unit/a After = mediacenter.service' /etc/systemd/system/hyperion.service
# sed -i 's/User=osmc/User=root/g' /etc/systemd/system/hyperion.service
# sed -i 's/Group=osmc/Group=root/g' /etc/systemd/system/hyperion.service
# systemctl -q daemon-reload
# fi
systemctl start hyperion
elif [ -e /sbin/initctl ] elif [ -e /sbin/initctl ]
then then
echo "---> init deamon: upstart"
# upstart # upstart
install_file /usr/share/hyperion/service/hyperion.initctl.sh /etc/init/hyperion.conf if [ $ENABLE_SERVICE -eq 1 ]; then
initctl reload-configuration install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
initctl start hyperion start_msg="--> initctl start hyperiond"
initctl start hyperiond
fi
else else
echo "---> init deamon: sysV"
# sysV # sysV
service hyperion stop 2>/dev/null if [ $ENABLE_SERVICE -eq 1 ]; then
install_file /usr/share/hyperion/service/hyperion.init.sh /etc/init.d/hyperion install_file /usr/share/hyperion/service/hyperion.init /etc/init.d/hyperiond && chmod +x /etc/init.d/hyperiond && update-rc.d hyperiond defaults 98 02
chmod +x /etc/init.d/hyperion start_msg="---> service hyperiond start"
update-rc.d hyperion defaults 98 02 service hyperiond start
service hyperion start fi
fi fi
echo "- done"
#cleanup
rm -r /usr/share/hyperion/service
#link binarys and set exec bit
BINSP=/usr/share/hyperion/bin
BINTP=/usr/bin
chmod +x -R $BINSP
ln -fs $BINSP/hyperiond $BINTP/hyperiond
ln -fs $BINSP/hyperion-remote $BINTP/hyperion-remote
ln -fs $BINSP/hyperion-v4l2 $BINTP/hyperion-v4l2
ln -fs $BINSP/hyperion-framebuffer $BINTP/hyperion-framebuffer 2>/dev/null
ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
ln -fs $BINSP/hyperion-qt $BINTP/hyperion-qt 2>/dev/null
# install desktop icons
echo "---> Install Hyperion desktop icons"
mkdir /usr/share/pixmaps/hyperion 2>/dev/null
cp /usr/share/hyperion/desktop/*.png /usr/share/pixmaps/hyperion 2>/dev/null
desktop-file-install /usr/share/hyperion/desktop/hyperiond.desktop 2>/dev/null
# cleanup desktop icons
rm -r /usr/share/hyperion/desktop 2>/dev/null
#Check, if dtparam=spi=on is in place
if [ $CPU_RPI -eq 1 ]; then
BOOT_DIR="/boot"
if [ $BOOT_BERRYBOOT -eq 1 ]; then
BOOT_DIR=$(sed -ne "s#/dev/mmcblk0p1 \([^ ]*\) vfat rw,.*#\1#p" /etc/mtab)
fi
if [ -z "$BOOT_DIR" -o ! -f "$BOOT_DIR/config.txt" ]; then
echo '---> Warning: RPi using BERRYBOOT found but can not locate where config.txt is to enable SPI. (BOOT_DIR='"$BOOT_DIR)"
SPIOK=1 # Not sure if OK, but don't ask to reboot
else
SPIOK=`grep '^\dtparam=spi=on' "$BOOT_DIR/config.txt" | wc -l`
if [ $SPIOK -ne 1 ]; then
echo '---> Raspberry Pi found, but SPI is not set, we write "dtparam=spi=on" to '"$BOOT_DIR/config.txt"
sed -i '$a dtparam=spi=on' "$BOOT_DIR/config.txt"
REBOOTMESSAGE="echo Please reboot your Raspberry Pi, we inserted dtparam=spi=on to $BOOT_DIR/config.txt"
fi
fi
fi
echo ${start_msg}
echo "-----------------------------------------------------------------------------"
echo "---> Hyperion has been installed/updated!"
echo "---> "
$STARTUP_MSG
echo "---> For configuration, visit with your browser: ${NET_IP}:8090"
echo "---> or if already used by another service try: ${NET_IP}:8091"
$REBOOTMESSAGE
echo "-----------------------------------------------------------------------------"
echo "Webpage: www.hyperion-project.org"
echo "Wiki: wiki.hyperion-project.org"
echo "Forum: forum.hyperion-project.org"
echo "-----------------------------------------------------------------------------"
if [ -e /opt/hyperion/ ]
then
echo
echo "---------------------------------------------------------------------------------"
echo "- It seemd that you have an older version of hyperion installed in /opt/hyperion -"
echo "- please remove it to avoid problems -"
echo "---------------------------------------------------------------------------------"
fi
exit 0

61
cmake/rpm/preinst Normal file
View File

@ -0,0 +1,61 @@
#!/bin/sh
echo "---Hyperion ambient light preinst ---"
# search for users in system, returns first entry
FOUND_USR=`who | grep -o '^\w*\b'` || "root"
# stop running daemon before we install
if pgrep hyperiond > /dev/null 2>&1
then
if grep -m1 systemd /proc/1/comm > /dev/null
then
echo "--> stop init deamon: systemd"
# systemd
systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null
elif [ -e /sbin/initctl ]
then
echo "--> stop init deamon: upstart"
# upstart
initctl stop hyperiond
else
echo "--> stop init deamon: sysV"
# sysV
service hyperiond stop 2>/dev/null
fi
fi
# In case we don't use a service kill all instances
killall hyperiond 2> /dev/null
exit 0
#$USR=hyperionIS;
#addToGroup()
##{
# getent group $1 && adduser $USR $1;
#}
#check if user exists
#if id $USR >/dev/null 2>&1; then
# echo "--> hyperion user exists, skip creation";
#else
## create user
# echo "--> Create Hyperion user";
# adduser --system --group $USR;
#fi
# add user to groups if required
## secondary user groups that are required to access system things
#addToGroup(dialout);
#addToGroup(video);
#addToGroup(audio);
#addToGroup(systemd-journal);
# platform specific groups
#addToGroup(i2c);
#addToGroup(spi);
#addToGroup(gpio);

50
cmake/rpm/prerm Normal file
View File

@ -0,0 +1,50 @@
#!/bin/sh
echo "---Hyperion ambient light prerm ---"
# search for users in system, returns first entry
FOUND_USR=`who | grep -o '^\w*\b'` || "root"
# stop running daemon before we delete it
HYPERION_RUNNING=false
pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true
if grep -m1 systemd /proc/1/comm > /dev/null
then
echo "---> stop init deamon: systemd"
# systemd
$HYPERION_RUNNING && systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null
# disable user specific symlink
echo "---> Disable service and remove entry"
systemctl -q disable hyperiond"@${FOUND_USR}"
rm -v /etc/systemd/system/hyperiond@.service 2>/dev/null
elif [ -e /sbin/initctl ]
then
echo "---> stop init deamon: upstart"
# upstart
$HYPERION_RUNNING && initctl stop hyperiond
echo "---> Remove upstart service"
rm -v /etc/init/hyperion* 2>/dev/null
initctl reload-configuration
else
echo "---> stop init deamon: sysV"
# sysV
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null
echo "---> Remove sysV service"
update-rc.d -f hyperion remove
rm /etc/init.d/hyperion* 2>/dev/null
fi
# In case we don't use a service kill all instances
killall hyperiond 2> /dev/null
# delete desktop icons; desktop-file-edit is a workaround to hide the entry and delete it afterwards manual.
# TODO Better way for deletion and keep the desktop in sync without logout/login or desktop dependend cmds?
echo "---> Delete Hyperion desktop icons"
desktop-file-edit --set-key=NoDisplay --set-value=true /usr/share/applications/hyperiond.desktop 2>/dev/null
rm -v /usr/share/applications/hyperion* 2>/dev/null
rm -rv /usr/share/pixmaps/hyperion 2>/dev/null
exit 0

View File

@ -20,14 +20,14 @@
/// Device configuration contains the following fields: /// Device configuration contains the following fields:
/// * 'name' : The user friendly name of the device (only used for display purposes) /// * 'name' : The user friendly name of the device (only used for display purposes)
/// * 'type' : The type of the device or leds (known types for now are /// * 'type' : The type of the device
/// APA102, WS2801, P9813, LPD6803, LPD8806, ---------PWM---------, WS2812b (just RPi1), WS281X (RPi1, RPi2, RPi3), --------OTHER--------, PhilipsHUE, AtmoOrb, PiBlaster, Tinkerforge, FadeCandy, RawHID (USB), UDP, SEDU, TPM2, USBASP-WS2801, USBASP-WS2812, ------3rd PARTY------, Adalight, AdalightAPA102, Atmo, Lightpack, Multi-Lightpack, Paintpack, Test (file), None)
/// * [device type specific configuration] /// * [device type specific configuration]
/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.). /// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).
/// * 'rewriteTime': in ms. Data is resend to leds, if no new data is available in thistime. 0 means no refresh /// * 'rewriteTime': in ms. Data is resend to leds, if no new data is available in thistime. 0 means no refresh
"device" : "device" :
{ {
"type" : "file", "type" : "file",
"hardwareLedCount" : 1,
"output" : "/dev/null", "output" : "/dev/null",
"rate" : 1000000, "rate" : 1000000,
"colorOrder" : "rgb", "colorOrder" : "rgb",
@ -43,7 +43,7 @@
/// * 'id' : The unique identifier of the channel adjustments (eg 'device_1') /// * 'id' : The unique identifier of the channel adjustments (eg 'device_1')
/// * 'leds' : The indices (or index ranges) of the leds to which this channel adjustment applies /// * 'leds' : The indices (or index ranges) of the leds to which this channel adjustment applies
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based. /// (eg '0-5, 9, 11, 12-17'). The indices are zero based.
/// * 'black'/'white'/'red'/'green'/'blue'/'cyan'/'magenta'/'yellow' : Array of RGB to adjust the output color /// * 'white'/'red'/'green'/'blue'/'cyan'/'magenta'/'yellow' : Array of RGB to adjust the output color
/// * 'gammaRed'/'gammaGreen'/'gammaBlue' : Gamma value for each channel /// * 'gammaRed'/'gammaGreen'/'gammaBlue' : Gamma value for each channel
/// * 'id' : The unique identifier of the channel adjustments (eg 'device_1') /// * 'id' : The unique identifier of the channel adjustments (eg 'device_1')
/// * 'id' : The unique identifier of the channel adjustments (eg 'device_1') /// * 'id' : The unique identifier of the channel adjustments (eg 'device_1')
@ -60,7 +60,6 @@
{ {
"id" : "default", "id" : "default",
"leds" : "*", "leds" : "*",
"black" : [0,0,0],
"white" : [255,255,255], "white" : [255,255,255],
"red" : [255,0,0], "red" : [255,0,0],
"green" : [0,255,0], "green" : [0,255,0],
@ -99,15 +98,9 @@
}, },
/// Configuration for the embedded V4L2 grabber /// Configuration for the embedded V4L2 grabber
/// * enable : Enable or disable the v4lgrabber (true/false) /// * device : V4L2 Device to use [default="auto"] (Auto detection)
/// * device : V4L2 Device to use [default="/dev/video0"] /// * standard : Video standard (PAL/NTSC/SECAM/NO_CHANGE) [default="NO_CHANGE"]
/// * input : V4L2 input to use [default=0]
/// * standard : Video standard (PAL/NTSC/SECAM) [default="PAL"]
/// * width : V4L2 width to set [default=-1]
/// * height : V4L2 height to set [default=-1]
/// * frameDecimation : Frame decimation factor [default=2]
/// * sizeDecimation : Size decimation factor [default=8] /// * sizeDecimation : Size decimation factor [default=8]
/// * priority : Hyperion priority channel [default=900]
/// * cropLeft : Cropping from the left [default=0] /// * cropLeft : Cropping from the left [default=0]
/// * cropRight : Cropping from the right [default=0] /// * cropRight : Cropping from the right [default=0]
/// * cropTop : Cropping from the top [default=0] /// * cropTop : Cropping from the top [default=0]
@ -123,13 +116,8 @@
"grabberV4L2" : "grabberV4L2" :
[ [
{ {
"enable" : false,
"device" : "auto", "device" : "auto",
"input" : 0, "standard" : "NO_CHANGE",
"standard" : "PAL",
"width" : 0,
"height" : 0,
"frameDecimation" : 2,
"sizeDecimation" : 8, "sizeDecimation" : 8,
"priority" : 240, "priority" : 240,
"cropLeft" : 0, "cropLeft" : 0,
@ -148,20 +136,16 @@
], ],
/// The configuration for the frame-grabber, contains the following items: /// The configuration for the frame-grabber, contains the following items:
/// * enable : true if the framegrabber (platform grabber) should be activated /// * type : type of grabber. (auto|osx|dispmanx|amlogic|x11|framebuffer|qt) [auto]
/// * type : type of grabber. (auto|osx|dispmanx|amlogic|x11|framebuffer) [auto]
/// * width : The width of the grabbed frames [pixels] /// * width : The width of the grabbed frames [pixels]
/// * height : The height of the grabbed frames [pixels] /// * height : The height of the grabbed frames [pixels]
/// * frequency_Hz : The frequency of the frame grab [Hz] /// * frequency_Hz : The frequency of the frame grab [Hz]
/// * priority : The priority of the frame-gabber (Default=250) HINT: lower value result in HIGHER priority!
/// * ATTENTION : Power-of-Two resolution is not supported and leads to unexpected behaviour! /// * ATTENTION : Power-of-Two resolution is not supported and leads to unexpected behaviour!
"framegrabber" : "framegrabber" :
{ {
// for all type of grabbers // for all type of grabbers
"enable" : true,
"type" : "framebuffer", "type" : "framebuffer",
"frequency_Hz" : 10, "frequency_Hz" : 10,
"priority" : 250,
"cropLeft" : 0, "cropLeft" : 0,
"cropRight" : 0, "cropRight" : 0,
"cropTop" : 0, "cropTop" : 0,
@ -171,10 +155,11 @@
"width" : 96, "width" : 96,
"height" : 96, "height" : 96,
// valid for x11 // valid for x11|qt
"useXGetImage" : false, "pixelDecimation" : 8,
"horizontalPixelDecimation" : 8,
"verticalPixelDecimation" : 8, // valid for qt
"display" 0,
// valid for framebuffer // valid for framebuffer
"device" : "/dev/fb0" "device" : "/dev/fb0"
@ -231,14 +216,14 @@
/// The configuration of the Json/Proto forwarder. Forward messages to multiple instances of Hyperion on same and/or other hosts /// The configuration of the Json/Proto forwarder. Forward messages to multiple instances of Hyperion on same and/or other hosts
/// 'proto' is mostly used for video streams and 'json' for effects /// 'proto' is mostly used for video streams and 'json' for effects
/// * enable : Enable or disable the forwarder (true/false) /// * enable : Enable or disable the forwarder (true/false)
/// * proto : Proto server adress and port of your target. Syntax:[IP:PORT] -> ["127.0.0.1:19447"] or more instances to forward ["127.0.0.1:19447","192.168.0.24:19449"] /// * proto : Proto server adress and port of your target. Syntax:[IP:PORT] -> ["127.0.0.1:19401"] or more instances to forward ["127.0.0.1:19401","192.168.0.24:19403"]
/// * json : Json server adress and port of your target. Syntax:[IP:PORT] -> ["127.0.0.1:19446"] or more instances to forward ["127.0.0.1:19446","192.168.0.24:19448"] /// * json : Json server adress and port of your target. Syntax:[IP:PORT] -> ["127.0.0.1:19446"] or more instances to forward ["127.0.0.1:19446","192.168.0.24:19448"]
/// HINT:If you redirect to "127.0.0.1" (localhost) you could start a second hyperion with another device/led config! /// HINT:If you redirect to "127.0.0.1" (localhost) you could start a second hyperion with another device/led config!
/// Be sure your client(s) is/are listening on the configured ports. The second Hyperion (if used) also needs to be configured! (HyperCon -> External -> Json Server/Proto Server) /// Be sure your client(s) is/are listening on the configured ports. The second Hyperion (if used) also needs to be configured! (WebUI -> Settings Level (Expert) -> Configuration -> Network Services -> Forwarder)
"forwarder" : "forwarder" :
{ {
"enable" : false, "enable" : false,
"proto" : ["127.0.0.1:19447"], "proto" : ["127.0.0.1:19401"],
"json" : ["127.0.0.1:19446"] "json" : ["127.0.0.1:19446"]
}, },
@ -249,11 +234,13 @@
"port" : 19444 "port" : 19444
}, },
/// The configuration of the Proto server which enables the protobuffer remote interface /// The configuration of the Flatbuffer server which enables the Flatbuffer remote interface
/// * port : Port at which the protobuffer server is started /// * port : Port at which the flatbuffer server is started
"protoServer" : "flatbufServer" :
{ {
"port" : 19445 "enable" : true,
"port" : 19400,
"timeout" : 5
}, },
/// The configuration of the boblight server which enables the boblight remote interface /// The configuration of the boblight server which enables the boblight remote interface
@ -285,12 +272,10 @@
}, },
/// Configuration of the Hyperion webserver /// Configuration of the Hyperion webserver
/// * enable : enable or disable the webserver (true/false)
/// * document_root : path to hyperion webapp files (webconfig developer only) /// * document_root : path to hyperion webapp files (webconfig developer only)
/// * port : the port where hyperion webapp is accasible /// * port : the port where hyperion webapp is accasible
"webConfig" : "webConfig" :
{ {
"enable" : true,
"document_root" : "/path/to/files", "document_root" : "/path/to/files",
"port" : 8090 "port" : 8090
}, },
@ -313,6 +298,13 @@
] ]
}, },
"instCapture" : {
"systemEnable" : true,
"systemPriority" : 250,
"v4lEnable" : false,
"v4lPriority" : 240
},
/// Recreate and save led layouts made with web config. These values are just helpers for ui, not for Hyperion. /// Recreate and save led layouts made with web config. These values are just helpers for ui, not for Hyperion.
"ledConfig" : "ledConfig" :
{ {

View File

@ -12,9 +12,11 @@
"device" : "device" :
{ {
"type" : "file", "type" : "file",
"hardwareLedCount" : 1,
"output" : "/dev/null", "output" : "/dev/null",
"rate" : 1000000, "rate" : 1000000,
"colorOrder" : "rgb", "colorOrder" : "rgb",
"latchTime" : 1,
"rewriteTime": 5000 "rewriteTime": 5000
}, },
@ -26,7 +28,6 @@
{ {
"id" : "default", "id" : "default",
"leds" : "*", "leds" : "*",
"black" : [0,0,0],
"white" : [255,255,255], "white" : [255,255,255],
"red" : [255,0,0], "red" : [255,0,0],
"green" : [0,255,0], "green" : [0,255,0],
@ -58,15 +59,9 @@
"grabberV4L2" : "grabberV4L2" :
[ [
{ {
"enable" : false,
"device" : "auto", "device" : "auto",
"input" : 0, "standard" : "NO_CHANGE",
"standard" : "PAL",
"width" : 0,
"height" : 0,
"frameDecimation" : 2,
"sizeDecimation" : 8, "sizeDecimation" : 8,
"priority" : 240,
"cropLeft" : 0, "cropLeft" : 0,
"cropRight" : 0, "cropRight" : 0,
"cropTop" : 0, "cropTop" : 0,
@ -84,15 +79,11 @@
"framegrabber" : "framegrabber" :
{ {
"enable" : true,
"type" : "auto", "type" : "auto",
"width" : 80, "width" : 80,
"height" : 45, "height" : 45,
"frequency_Hz" : 10, "frequency_Hz" : 10,
"priority" : 250, "pixelDecimation" : 8,
"useXGetImage" : false,
"horizontalPixelDecimation" : 8,
"verticalPixelDecimation" : 8,
"cropLeft" : 0, "cropLeft" : 0,
"cropRight" : 0, "cropRight" : 0,
"cropTop" : 0, "cropTop" : 0,
@ -132,7 +123,7 @@
{ {
"enable" : false, "enable" : false,
"json" : ["127.0.0.1:19446"], "json" : ["127.0.0.1:19446"],
"proto" : ["127.0.0.1:19447"] "proto" : ["127.0.0.1:19401"]
}, },
"jsonServer" : "jsonServer" :
@ -140,9 +131,11 @@
"port" : 19444 "port" : 19444
}, },
"protoServer" : "flatbufServer" :
{ {
"port" : 19445 "enable" : true,
"port" : 19400,
"timeout" : 5
}, },
"boblightServer" : "boblightServer" :
@ -164,7 +157,6 @@
"webConfig" : "webConfig" :
{ {
"enable" : true,
"document_root" : "", "document_root" : "",
"port" : 8090 "port" : 8090
}, },
@ -175,6 +167,13 @@
"disable": [""] "disable": [""]
}, },
"instCapture" : {
"systemEnable" : true,
"systemPriority" : 250,
"v4lEnable" : false,
"v4lPriority" : 240
},
"ledConfig" : "ledConfig" :
{ {
"top" : 8, "top" : 8,

View File

@ -9,106 +9,44 @@ if(ENABLE_WS281XPWM)
external/rpi_ws281x/rpihw.c) external/rpi_ws281x/rpihw.c)
endif() endif()
set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system") set(USE_SYSTEM_FLATBUFFERS_LIBS ${DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS} CACHE BOOL "use flatbuffers library from system")
if (USE_SYSTEM_PROTO_LIBS) if (USE_SYSTEM_FLATBUFFERS_LIBS)
find_package(Protobuf REQUIRED) find_package(flatbuffers REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS}) include_directories(${FLATBUFFERS_INCLUDE_DIRS})
else () else ()
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library") set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared flatbuffers library")
add_subdirectory(external/protobuf) set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "Build Flatbuffers with tests")
add_subdirectory(external/flatbuffers)
if(CMAKE_CROSSCOMPILING) if(CMAKE_CROSSCOMPILING)
# when crosscompiling import the protoc executable targets from a file generated by a native build # when crosscompiling import the flatc executable targets from a file generated by a native build
option(IMPORT_PROTOC "Protoc export file (protoc_export.cmake) from a native build" "IMPORT_PROTOC-FILE_NOT_FOUND") option(IMPORT_FLATC "flatc export file (flatc_export.cmake) from a native build" "IMPORT_FLATC-FILE_NOT_FOUND")
include(${IMPORT_PROTOC}) include(${IMPORT_FLATC})
else() else()
# export the protoc compiler so it can be used when cross compiling # export the flatc compiler so it can be used when cross compiling
export(TARGETS protoc_compiler FILE "${CMAKE_BINARY_DIR}/protoc_export.cmake") export(TARGETS flatc FILE "${CMAKE_BINARY_DIR}/flatc_export.cmake")
endif() endif()
# define the include for the protobuf library at the parent scope # define the include for the flatbuffers library at the parent scope
set(PROTOBUF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/protobuf/src") set(FLATBUFFERS_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/flatbuffers/include")
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE) set(FLATBUFFERS_INCLUDE_DIRS ${FLATBUFFERS_INCLUDE_DIRS} PARENT_SCOPE)
# define the protoc executable at the parent scope # define the flatc executable at the parent scope
get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION) get_property(FLATBUFFERS_FLATC_EXECUTABLE TARGET flatc PROPERTY LOCATION)
set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE) set(FLATBUFFERS_FLATC_EXECUTABLE ${FLATBUFFERS_FLATC_EXECUTABLE} PARENT_SCOPE)
endif() endif()
message(STATUS "Using protobuf compiler: " ${PROTOBUF_PROTOC_EXECUTABLE}) message(STATUS "Using flatbuffers compiler: " ${FLATBUFFERS_FLATC_EXECUTABLE})
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009-2011 Philip Lowman <philip@yhbt.com>
# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH) function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR)
# Create an include path for each file specified string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
foreach(FIL ${ARGN}) add_custom_command(
get_filename_component(ABS_FIL ${FIL} ABSOLUTE) OUTPUT ${GEN_HEADER}
get_filename_component(ABS_PATH ${ABS_FIL} PATH) COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) --gen-object-api
if(${_contains_already} EQUAL -1) -o "${OUTPUT_DIR}"
list(APPEND _protobuf_include_path -I ${ABS_PATH}) "${SRC_FBS}"
endif() DEPENDS flatc)
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(DEFINED PROTOBUF_IMPORT_DIRS)
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
if(CMAKE_CROSSCOMPILING OR USE_SYSTEM_PROTO_LIBS)
set(PROTOC_DEPENDENCY ${PROTOBUF_PROTOC_EXECUTABLE})
else()
set(PROTOC_DEPENDENCY protoc_compiler)
endif()
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${PROTOC_DEPENDENCY}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM
)
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction() endfunction()

View File

@ -7,7 +7,7 @@
*/ */
#ifndef _WIN32 #ifndef _WIN32
#define _BSD_SOURCE // for usleep from unistd.h #define _DEFAULT_SOURCE // for usleep from unistd.h
#endif #endif
#include <errno.h> #include <errno.h>

1
dependencies/external/flatbuffers vendored Submodule

@ -0,0 +1 @@
Subproject commit 0eb7b3beb037748bf5b469e4df9db862c4833e35

@ -1 +0,0 @@
Subproject commit adce8a99fdab90f290d659b6b3bf2d09b721e24a

View File

@ -1,32 +1,34 @@
option(BUILD_HYPERION_DOC "Build hyperion documentation" OFF)
# Find doxygen # Find doxygen and check if Doxygen is installed
find_package(Doxygen QUIET) find_package(Doxygen QUIET)
# This processes our hyperion-cmake.doxyfile and subsitutes variables to generate a final hyperion.doxyfile if (BUILD_HYPERION_DOC)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hyperion.in.doxygen ${CMAKE_CURRENT_BINARY_DIR}/hyperion.doxygen) if (DOXYGEN_FOUND)
# This processes the shell script that is used to build the documentation and check the result # set input and output files
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hyperion-build-doc.in.sh ${CMAKE_CURRENT_BINARY_DIR}/hyperion-build-doc.sh) set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/hyperion.in.doxygen)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/hyperion.doxygen)
# Define all static (i.e. not generated) documentation files # request to configure the file
set(StaticDocumentationFiles hyperion-header.html hyperion-footer.html hyperion-stylesheet.css) configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
message(STATUS "Doxygen build started")
# Loop over all static documentation files # Define all static (i.e. not generated) documentation files
foreach(StaticDocumentationFile ${StaticDocumentationFiles}) set(StaticDocumentationFiles hyperion-footer.html)
# Copy the file to the bindary documentation directory
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${StaticDocumentationFile} ${CMAKE_CURRENT_BINARY_DIR}/html/${StaticDocumentationFile} COPYONLY)
endforeach()
if(DOXYGEN_FOUND) # Loop over all static documentation files
option(BuildDocumentationSearchEngine "Enable doxygen's search engine (requires that documentation to be installed on a php enabled web server)" OFF) foreach(StaticDocumentationFile ${StaticDocumentationFiles})
if(BuildDocumentationSearchEngine) # Copy the file to the bindary documentation directory
set(DOXYGEN_SEARCHENGINE YES) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${StaticDocumentationFile} ${CMAKE_CURRENT_BINARY_DIR}/html/${StaticDocumentationFile} COPYONLY)
else(BuildDocumentationSearchEngine) endforeach()
set(DOXYGEN_SEARCHENGINE NO)
endif(BuildDocumentationSearchEngine)
#Create a custom target to build documentation. It runs doxygen aginast the generated hyperion.doxyfile and checks its return value add_custom_target( doc_doxygen ALL
add_custom_target(doc sh ${CMAKE_CURRENT_BINARY_DIR}/hyperion-build-doc.sh) COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
else(DOXYGEN_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
message(WARNING "Doxygen not found, unable to generate documenation!") COMMENT "Generating API documentation with Doxygen"
endif(DOXYGEN_FOUND) VERBATIM )
else(DOXYGEN_FOUND)
message(WARNING "Doxygen not found, unable to generate documenation!")
endif(DOXYGEN_FOUND)
endif()

View File

@ -1,30 +0,0 @@
#!/bin/sh
# Fail on error.
set -e
# Log file containing documentation errors and warnings (if any).
log_file=${CMAKE_CURRENT_BINARY_DIR}/hyperion-doxygen.log
# Remove the log file before building the documentation.
rm -f $log_file
# Generate the documentation.
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/hyperion.doxygen
# At this point, the log file should have been generated.
# If not, an error is displayed on stderr and 1 is returned to indicate an error.
if [ -f $log_file ] ; then
# So the log file exists. If its size is > 0, show its contents on stderr and exit 1.
if [ -s $log_file ] ; then
cat $log_file 1>&2
exit 1;
else
# The log file exists, but its size is zero, meaning there were no documentation warnings or errors.
# Exit with 0 to indicate success.
exit 0;
fi
else
echo "The doxygen log file ($log_file) does not exist. Ensure that WARN_LOGFILE is set correctly in hyperion-cmake.doxyfile." 1>&2
exit 1;
fi

View File

@ -1,9 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>$title</title>
<link href="$relpath$doxygen.css" rel="stylesheet" type="text/css">
<link href="$relpath$tabs.css" rel="stylesheet" type="text/css">
</head>
<body>

View File

@ -1,472 +0,0 @@
BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
font-family: Geneva, Arial, Helvetica, sans-serif;
}
BODY,TD {
font-size: 90%;
}
H1 {
text-align: center;
font-size: 160%;
}
H2 {
font-size: 120%;
}
H3 {
font-size: 100%;
}
CAPTION {
font-weight: bold
}
DIV.qindex {
width: 100%;
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
padding: 2px;
line-height: 140%;
}
DIV.navpath {
width: 100%;
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
padding: 2px;
line-height: 140%;
}
DIV.navtab {
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
TD.navtab {
font-size: 70%;
}
A.qindex {
text-decoration: none;
font-weight: bold;
color: #1A419D;
}
A.qindex:visited {
text-decoration: none;
font-weight: bold;
color: #1A419D
}
A.qindex:hover {
text-decoration: none;
background-color: #ddddff;
}
A.qindexHL {
text-decoration: none;
font-weight: bold;
background-color: #6666cc;
color: #ffffff;
border: 1px double #9295C2;
}
A.qindexHL:hover {
text-decoration: none;
background-color: #6666cc;
color: #ffffff;
}
A.qindexHL:visited {
text-decoration: none;
background-color: #6666cc;
color: #ffffff
}
A.el {
text-decoration: none;
font-weight: bold
}
A.elRef {
font-weight: bold
}
A.code:link {
text-decoration: none;
font-weight: normal;
color: #0000FF
}
A.code:visited {
text-decoration: none;
font-weight: normal;
color: #0000FF
}
A.codeRef:link {
font-weight: normal;
color: #0000FF
}
A.codeRef:visited {
font-weight: normal;
color: #0000FF
}
A:hover {
text-decoration: none;
background-color: #f2f2ff
}
DL.el {
margin-left: -1cm
}
.fragment {
font-family: monospace, fixed;
font-size: 95%;
}
PRE.fragment {
border: 1px solid #CCCCCC;
background-color: #f5f5f5;
margin-top: 4px;
margin-bottom: 4px;
margin-left: 2px;
margin-right: 8px;
padding-left: 6px;
padding-right: 6px;
padding-top: 4px;
padding-bottom: 4px;
}
DIV.ah {
background-color: black;
font-weight: bold;
color: #ffffff;
margin-bottom: 3px;
margin-top: 3px
}
DIV.groupHeader {
margin-left: 16px;
margin-top: 12px;
margin-bottom: 6px;
font-weight: bold;
}
DIV.groupText {
margin-left: 16px;
font-style: italic;
font-size: 90%
}
BODY {
background: white;
color: black;
margin-right: 20px;
margin-left: 20px;
}
TD.indexkey {
background-color: #e8eef2;
font-weight: bold;
padding-right : 10px;
padding-top : 2px;
padding-left : 10px;
padding-bottom : 2px;
margin-left : 0px;
margin-right : 0px;
margin-top : 2px;
margin-bottom : 2px;
border: 1px solid #CCCCCC;
}
TD.indexvalue {
background-color: #e8eef2;
font-style: italic;
padding-right : 10px;
padding-top : 2px;
padding-left : 10px;
padding-bottom : 2px;
margin-left : 0px;
margin-right : 0px;
margin-top : 2px;
margin-bottom : 2px;
border: 1px solid #CCCCCC;
}
TR.memlist {
background-color: #f0f0f0;
}
P.formulaDsp {
text-align: center;
}
IMG.formulaDsp {
}
IMG.formulaInl {
vertical-align: middle;
}
SPAN.keyword { color: #008000 }
SPAN.keywordtype { color: #604020 }
SPAN.keywordflow { color: #e08000 }
SPAN.comment { color: #800000 }
SPAN.preprocessor { color: #806020 }
SPAN.stringliteral { color: #002080 }
SPAN.charliteral { color: #008080 }
SPAN.vhdldigit { color: #ff00ff }
SPAN.vhdlchar { color: #000000 }
SPAN.vhdlkeyword { color: #700070 }
SPAN.vhdllogic { color: #ff0000 }
.mdescLeft {
padding: 0px 8px 4px 8px;
font-size: 80%;
font-style: italic;
background-color: #FAFAFA;
border-top: 1px none #E0E0E0;
border-right: 1px none #E0E0E0;
border-bottom: 1px none #E0E0E0;
border-left: 1px none #E0E0E0;
margin: 0px;
}
.mdescRight {
padding: 0px 8px 4px 8px;
font-size: 80%;
font-style: italic;
background-color: #FAFAFA;
border-top: 1px none #E0E0E0;
border-right: 1px none #E0E0E0;
border-bottom: 1px none #E0E0E0;
border-left: 1px none #E0E0E0;
margin: 0px;
}
.memItemLeft {
padding: 1px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: solid;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memItemRight {
padding: 1px 8px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: solid;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memTemplItemLeft {
padding: 1px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: none;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memTemplItemRight {
padding: 1px 8px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: none;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
background-color: #FAFAFA;
font-size: 80%;
}
.memTemplParams {
padding: 1px 0px 0px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-color: #E0E0E0;
border-right-color: #E0E0E0;
border-bottom-color: #E0E0E0;
border-left-color: #E0E0E0;
border-top-style: solid;
border-right-style: none;
border-bottom-style: none;
border-left-style: none;
color: #606060;
background-color: #FAFAFA;
font-size: 80%;
}
.search {
color: #003399;
font-weight: bold;
}
FORM.search {
margin-bottom: 0px;
margin-top: 0px;
}
INPUT.search {
font-size: 75%;
color: #000080;
font-weight: normal;
background-color: #e8eef2;
}
TD.tiny {
font-size: 75%;
}
a {
color: #1A41A8;
}
a:visited {
color: #2A3798;
}
.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #84b0c7;
}
TH.dirtab {
background: #e8eef2;
font-weight: bold;
}
HR {
height: 1px;
border: none;
border-top: 1px solid black;
}
/* Style for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #606060;
font-weight: normal;
margin-left: 3px;
}
.memnav {
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
.memitem {
padding: 4px;
background-color: #eef3f5;
border-width: 1px;
border-style: solid;
border-color: #dedeee;
-moz-border-radius: 8px 8px 8px 8px;
}
.memname {
white-space: nowrap;
font-weight: bold;
}
.memdoc {
padding-left: 10px;
}
.memproto {
background-color: #d5e1e8;
width: 100%;
border-width: 1px;
border-style: solid;
border-color: #84b0c7;
font-weight: bold;
-moz-border-radius: 8px 8px 8px 8px;
}
.paramkey {
text-align: right;
}
.paramtype {
white-space: nowrap;
}
.paramname {
color: #602020;
font-style: italic;
white-space: nowrap;
}
/* End Styling for detailed member documentation */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin:0.5em;
}
/* these are for tree view when used as main index */
.directory {
font-size: 9pt;
font-weight: bold;
}
.directory h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
/* The following two styles can be used to replace the root node title */
/* with an image of your choice. Simply uncomment the next two styles, */
/* specify the name of your image and be sure to set 'height' to the */
/* proper pixel height of your image. */
/* .directory h3.swap { */
/* height: 61px; */
/* background-repeat: no-repeat; */
/* background-image: url("yourimage.gif"); */
/* } */
/* .directory h3.swap span { */
/* display: none; */
/* } */
.directory > h3 {
margin-top: 0;
}
.directory p {
margin: 0px;
white-space: nowrap;
}
.directory div {
display: none;
margin: 0px;
}
.directory img {
vertical-align: -30%;
}
/* these are for tree view when not used as main index */
.directory-alt {
font-size: 100%;
font-weight: bold;
}
.directory-alt h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
.directory-alt > h3 {
margin-top: 0;
}
.directory-alt p {
margin: 0px;
white-space: nowrap;
}
.directory-alt div {
display: none;
margin: 0px;
}
.directory-alt img {
vertical-align: -30%;
}

View File

@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If # entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used. # left blank the current directory will be used.
OUTPUT_DIRECTORY = "${CMAKE_CURRENT_BINARY_DIR}" OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and # directories (in 2 levels) under the output directory of each output format and
@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES
# will be relative from the directory where doxygen is started. # will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES. # This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH = ${CMAKE_SOURCE_DIR} STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which # path mentioned in the documentation of a class, which tells the reader which
@ -409,7 +409,7 @@ LOOKUP_CACHE_SIZE = 0
# normally produced when WARNINGS is set to YES. # normally produced when WARNINGS is set to YES.
# The default value is: NO. # The default value is: NO.
EXTRACT_ALL = NO EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
# be included in the documentation. # be included in the documentation.
@ -742,7 +742,7 @@ WARN_FORMAT = "$file:$line: $text"
# messages should be written. If left blank the output is written to standard # messages should be written. If left blank the output is written to standard
# error (stderr). # error (stderr).
WARN_LOGFILE = ${CMAKE_CURRENT_BINARY_DIR}/hyperion-doxygen.log WARN_LOGFILE = @CMAKE_CURRENT_BINARY_DIR@/hyperion-doxygen.log
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the input files # Configuration options related to the input files
@ -754,10 +754,10 @@ WARN_LOGFILE = ${CMAKE_CURRENT_BINARY_DIR}/hyperion-doxygen.log
# spaces. # spaces.
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = "${CMAKE_SOURCE_DIR}/include" \ INPUT = @CMAKE_SOURCE_DIR@/include \
"${CMAKE_SOURCE_DIR}/libsrc" \ @CMAKE_SOURCE_DIR@/libsrc \
"${CMAKE_SOURCE_DIR}/src" \ @CMAKE_SOURCE_DIR@/src \
"${CMAKE_SOURCE_DIR}/test" @CMAKE_SOURCE_DIR@/test
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -1050,7 +1050,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation. # of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER = "html/hyperion-header.html" HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard # generated HTML page. If the tag is left blank doxygen will generate a standard
@ -1482,7 +1482,7 @@ MATHJAX_CODEFILE =
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
SEARCHENGINE = ${DOXYGEN_SEARCHENGINE} SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There # implemented using a web server instead of a web client using Javascript. There
@ -2080,7 +2080,7 @@ DOT_NUM_THREADS = 0
# The default value is: Helvetica. # The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = FreeSans DOT_FONTNAME =
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of # The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs. # dot graphs.
@ -2234,7 +2234,7 @@ INTERACTIVE_SVG = NO
# found. If left blank, it is assumed the dot tool can be found in the path. # found. If left blank, it is assumed the dot tool can be found in the path.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
DOT_PATH = "${DOXYGEN_DOT_PATH}" DOT_PATH = ""
# The DOTFILE_DIRS tag can be used to specify one or more directories that # The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the \dotfile # contain dot files that are included in the documentation (see the \dotfile

47
effects/Seawaves.json Normal file
View File

@ -0,0 +1,47 @@
{
"args": {
"center_x": 1.25,
"center_y": -0.25,
"colors": [
[
8,
0,
255
],
[
0,
161,
255
],
[
0,
222,
255
],
[
0,
153,
255
],
[
38,
0,
255
],
[
0,
199,
255
]
],
"random-center": false,
"reverse": false,
"reverse_time": 0,
"rotation_time": 60,
"smoothing-custom-settings": true,
"smoothing-time_ms": 200,
"smoothing-updateFrequency": 25
},
"name": "Sea waves",
"script": "waves.py"
}

8
effects/Waves.json Normal file
View File

@ -0,0 +1,8 @@
{
"name" : "Waves with Color",
"script" : "waves.py",
"args" :
{
"reverse" : false
}
}

View File

@ -6,8 +6,10 @@ framesPerSecond = float(hyperion.args.get('fps', 25))
reverse = bool(hyperion.args.get('reverse', False)) reverse = bool(hyperion.args.get('reverse', False))
sleepTime = 1./framesPerSecond sleepTime = 1./framesPerSecond
imageList = []
if imageFile: if imageFile:
imageList = list(reversed(hyperion.getImage(imageFile))) if reverse else hyperion.getImage(imageFile) imageList = [reversed(hyperion.getImage(imageFile))] if reverse else hyperion.getImage(imageFile)
# Start the write data loop # Start the write data loop
while not hyperion.abort() and imageList: while not hyperion.abort() and imageList:

View File

@ -1,10 +0,0 @@
{
"name" : "Running dots",
"script" : "running_dots.py",
"args" :
{
"speed" : 1.5,
"whiteLevel" : 100,
"colorLevel" : 230
}
}

View File

@ -3,11 +3,16 @@
"script" : "gif.py", "script" : "gif.py",
"title":"edt_eff_gif_header", "title":"edt_eff_gif_header",
"required":true, "required":true,
"properties":{ "properties": {
"image": { "image": {
"type": "string", "type": "string",
"title":"edt_eff_image", "title":"edt_eff_image",
"format" : "file", "format" : "url",
"options" :
{
"upload" : true,
"auto_upload" : true
},
"default": "", "default": "",
"propertyOrder" : 1 "propertyOrder" : 1
}, },

View File

@ -1,32 +0,0 @@
{
"type":"object",
"script" : "running_dots.py",
"title":"edt_eff_runningdots_header",
"required":true,
"properties":{
"speed": {
"type": "number",
"title":"edt_eff_speed",
"default": 1.5,
"minimum" : 0.1,
"propertyOrder" : 1
},
"colorLevel": {
"type": "integer",
"title":"edt_eff_colorevel",
"default": 220,
"minimium" : 0,
"maximum" : 255,
"propertyOrder" : 2
},
"whiteLevel": {
"type": "integer",
"title":"edt_eff_whitelevel",
"default": 0,
"minimium" : 0,
"maximum" : 254,
"propertyOrder" : 3
}
},
"additionalProperties": false
}

View File

@ -0,0 +1,121 @@
{
"type":"object",
"script" : "waves.py",
"title":"edt_eff_waves_header",
"required":true,
"properties":{
"reverse": {
"type": "boolean",
"title":"edt_eff_reversedirection",
"default": false,
"propertyOrder" : 1
},
"reverse_time": {
"type": "integer",
"title":"edt_eff_reverseRandomTime",
"default": 0,
"minimum": 0,
"append" : "edt_append_s",
"propertyOrder" : 2
},
"rotation_time": {
"type": "integer",
"title":"edt_eff_rotationtime",
"default": 50,
"minimum": 1,
"append" : "edt_append_s",
"propertyOrder" : 2
},
"random-center": {
"type": "boolean",
"title":"edt_eff_randomCenter",
"default": false,
"propertyOrder" : 3
},
"center_x": {
"type": "number",
"title":"edt_eff_centerx",
"default": -0.15,
"minimum" : -3.0,
"maximum" : 4.0,
"step" : 0.1,
"options": {
"dependencies": {
"random-center": false
}
},
"propertyOrder" : 4
},
"center_y": {
"type": "number",
"title":"edt_eff_centery",
"default": -0.15,
"minimum" : -3.0,
"maximum" : 4.0,
"step" : 0.1,
"options": {
"dependencies": {
"random-center": false
}
},
"propertyOrder" : 5
},
"smoothing-custom-settings" :
{
"type" : "boolean",
"title" : "edt_eff_smooth_custom",
"default" : true,
"propertyOrder" : 6
},
"smoothing-time_ms" :
{
"type" : "integer",
"title" : "edt_eff_smooth_time_ms",
"minimum" : 25,
"maximum": 600,
"default" : 200,
"append" : "edt_append_ms",
"options": {
"dependencies": {
"smoothing-custom-settings": true
}
},
"propertyOrder" : 7
},
"smoothing-updateFrequency" :
{
"type" : "number",
"title" : "edt_eff_smooth_updateFrequency",
"minimum" : 1.0,
"maximum" : 100.0,
"default" : 25.0,
"append" : "edt_append_hz",
"options": {
"dependencies": {
"smoothing-custom-settings": true
}
},
"propertyOrder" : 8
},
"colors": {
"type": "array",
"title":"edt_eff_customColor",
"items" : {
"type": "array",
"title" : "edt_eff_color",
"format":"colorpicker",
"default" : [255,0,0],
"items":{
"type":"integer",
"minimum": 0,
"maximum": 255
},
"minItems": 3,
"maxItems": 3
},
"minItems": 6,
"propertyOrder" : 9
}
},
"additionalProperties": false
}

77
effects/waves.py Normal file
View File

@ -0,0 +1,77 @@
import hyperion, time, math, random
randomCenter = bool(hyperion.args.get('random-center', False))
centerX = float(hyperion.args.get('center_x', -0.15))
centerY = float(hyperion.args.get('center_y', -0.25))
rotationTime = float(hyperion.args.get('rotation_time', 90))
colors = hyperion.args.get('colors', ((255,0,0),(255,255,0),(0,255,0),(0,255,255),(0,0,255),(255,0,255)))
reverse = bool(hyperion.args.get('reverse', False))
reverseTime = int(hyperion.args.get('reverse_time', 0))
#rotate = bool(hyperion.args.get('rotate', True))
positions = []
# calc center if random
if randomCenter:
centerX = random.uniform(0.0, 1.0)
centerY = random.uniform(0.0, 1.0)
rCenterX = int(round(float(hyperion.imageWidth())*centerX))
rCenterY = int(round(float(hyperion.imageHeight())*centerY))
#calc interval
sleepTime = max(1/(255/rotationTime), 0.016)
#calc diagonal
if centerX < 0.5:
cX = 1.0-centerX
else:
cX = 0.0+centerX
if centerY < 0.5:
cY = 1.0-centerY
else:
cY = 0.0+centerY
diag = int(round(math.sqrt(((cX*hyperion.imageWidth())**2)+((cY*hyperion.imageHeight())**2))))
# some diagonal overhead
diag = int(diag*1.3)
# calc positions
pos = 0
step = int(255/len(colors))
for entry in colors:
positions.append(pos)
pos += step
# target time
targetTime = time.time()+float(reverseTime)
#hyperion.imageCOffset(int(hyperion.imageWidth()/2), int(hyperion.imageHeight()/2))
while not hyperion.abort():
# verify reverseTime, randomize reverseTime based on reverseTime up to reversedTime*2
if reverseTime >= 1:
now = time.time()
if now > targetTime:
reverse = not reverse
targetTime = time.time()+random.uniform(float(reverseTime), float(reverseTime*2.0))
# apply rotate
#if rotate:
# hyperion.imageCRotate(1)
# prepare bytearray with colors and positions
gradientBa = bytearray()
it = 0
for color in colors:
gradientBa += bytearray((positions[it],color[0],color[1],color[2]))
it += 1
hyperion.imageRadialGradient(rCenterX,rCenterY, diag, gradientBa,0)
# increment positions
for i, pos in enumerate(positions):
if reverse:
positions[i] = pos - 1 if pos >= 1 else 255
else:
positions[i] = pos + 1 if pos <= 254 else 0
hyperion.imageShow()
time.sleep(sleepTime)

View File

@ -7,36 +7,13 @@
#include <hyperion/Hyperion.h> #include <hyperion/Hyperion.h>
// qt includess // qt includess
#include <QTimer>
#include <QJsonObject> #include <QJsonObject>
#include <QMutex> #include <QMutex>
#include <QString> #include <QString>
// createEffect helper class JsonCB;
struct find_schema: std::unary_function<EffectSchema, bool>
{
QString pyFile;
find_schema(QString pyFile):pyFile(pyFile) { }
bool operator()(EffectSchema const& schema) const
{
return schema.pyFile == pyFile;
}
};
// deleteEffect helper class JsonAPI : public QObject
struct find_effect: std::unary_function<EffectDefinition, bool>
{
QString effectName;
find_effect(QString effectName) :effectName(effectName) { }
bool operator()(EffectDefinition const& effectDefinition) const
{
return effectDefinition.name == effectName;
}
};
class ImageProcessor;
class JsonProcessor : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -49,7 +26,7 @@ public:
/// @param parent Parent QObject /// @param parent Parent QObject
/// @param noListener if true, this instance won't listen for hyperion push events /// @param noListener if true, this instance won't listen for hyperion push events
/// ///
JsonProcessor(QString peerAddress, Logger* log, QObject* parent, bool noListener = false); JsonAPI(QString peerAddress, Logger* log, QObject* parent, bool noListener = false);
/// ///
/// Handle an incoming JSON message /// Handle an incoming JSON message
@ -58,26 +35,20 @@ public:
/// ///
void handleMessage(const QString & message); void handleMessage(const QString & message);
///
/// send a forced serverinfo to a client
///
void forceServerInfo();
public slots: public slots:
/// _timer_ledcolors requests ledcolor updates (if enabled) ///
void streamLedcolorsUpdate(); /// @brief is called whenever the current Hyperion instance pushes new led raw values (if enabled)
/// @param ledColors The current ledColors
///
void streamLedcolorsUpdate(const std::vector<ColorRgb>& ledColors);
/// push images whenever hyperion emits (if enabled) /// push images whenever hyperion emits (if enabled)
void setImage(int priority, const Image<ColorRgb> & image, int duration_ms); void setImage(const Image<ColorRgb> & image);
/// process and push new log messages from logger (if enabled) /// process and push new log messages from logger (if enabled)
void incommingLogMessage(Logger::T_LOG_MESSAGE); void incommingLogMessage(Logger::T_LOG_MESSAGE);
signals: signals:
///
/// Signal which is emitted when a sendSuccessReply() has been executed
///
void pushReq();
/// ///
/// Signal emits with the reply message provided with handleMessage() /// Signal emits with the reply message provided with handleMessage()
/// ///
@ -89,6 +60,9 @@ signals:
void forwardJsonMessage(QJsonObject); void forwardJsonMessage(QJsonObject);
private: private:
// true if further callbacks are forbidden (http)
bool _noListener;
/// The peer address of the client /// The peer address of the client
QString _peerAddress; QString _peerAddress;
@ -98,17 +72,8 @@ private:
/// Hyperion instance /// Hyperion instance
Hyperion* _hyperion; Hyperion* _hyperion;
/// The processor for translating images to led-values // The JsonCB instance which handles data subscription/notifications
ImageProcessor * _imageProcessor; JsonCB* _jsonCB;
/// holds the state before off state
static std::map<hyperion::Components, bool> _componentsPrevState;
/// returns if hyperion is on or off
inline bool hyperionIsActive() { return JsonProcessor::_componentsPrevState.empty(); };
/// timer for ledcolors streaming
QTimer _timer_ledcolors;
// streaming buffers // streaming buffers
QJsonObject _streaming_leds_reply; QJsonObject _streaming_leds_reply;
@ -121,9 +86,15 @@ private:
/// mutex to determine state of image streaming /// mutex to determine state of image streaming
QMutex _image_stream_mutex; QMutex _image_stream_mutex;
/// mutex to determine state of image streaming
QMutex _led_stream_mutex;
/// timeout for live video refresh /// timeout for live video refresh
volatile qint64 _image_stream_timeout; volatile qint64 _image_stream_timeout;
/// timeout for led color refresh
volatile qint64 _led_stream_timeout;
/// ///
/// Handle an incoming JSON Color message /// Handle an incoming JSON Color message
/// ///
@ -143,7 +114,7 @@ private:
/// ///
/// @param message the incoming message /// @param message the incoming message
/// ///
void handleEffectCommand(const QJsonObject & message, const QString &command, const int tan); void handleEffectCommand(const QJsonObject &message, const QString &command, const int tan);
/// ///
/// Handle an incoming JSON Effect message (Write JSON Effect) /// Handle an incoming JSON Effect message (Write JSON Effect)
@ -180,13 +151,6 @@ private:
/// ///
void handleClearCommand(const QJsonObject & message, const QString &command, const int tan); void handleClearCommand(const QJsonObject & message, const QString &command, const int tan);
///
/// Handle an incoming JSON Clearall message
///
/// @param message the incoming message
///
void handleClearallCommand(const QJsonObject & message, const QString &command, const int tan);
/// ///
/// Handle an incoming JSON Adjustment message /// Handle an incoming JSON Adjustment message
/// ///
@ -213,12 +177,6 @@ private:
/// ///
void handleSchemaGetCommand(const QJsonObject & message, const QString &command, const int tan); void handleSchemaGetCommand(const QJsonObject & message, const QString &command, const int tan);
/// Handle an incoming JSON GetConfig message from handleConfigCommand()
///
/// @param message the incoming message
///
void handleConfigGetCommand(const QJsonObject & message, const QString &command, const int tan);
/// Handle an incoming JSON SetConfig message from handleConfigCommand() /// Handle an incoming JSON SetConfig message from handleConfigCommand()
/// ///
/// @param message the incoming message /// @param message the incoming message
@ -256,6 +214,13 @@ private:
/// ///
void handleVideoModeCommand(const QJsonObject & message, const QString &command, const int tan); void handleVideoModeCommand(const QJsonObject & message, const QString &command, const int tan);
///
/// Handle an incoming JSON Clearall message
///
/// @param message the incoming message
///
void handleClearallCommand(const QJsonObject & message, const QString &command, const int tan);
/// ///
/// Handle an incoming JSON message of unknown type /// Handle an incoming JSON message of unknown type
/// ///
@ -266,6 +231,11 @@ private:
/// ///
void sendSuccessReply(const QString &command="", const int tan=0); void sendSuccessReply(const QString &command="", const int tan=0);
///
/// Send a standard reply indicating success with data
///
void sendSuccessDataReply(const QJsonDocument &doc, const QString &command="", const int &tan=0);
/// ///
/// Send an error message back to the client /// Send an error message back to the client
/// ///

112
include/api/JsonCB.h Normal file
View File

@ -0,0 +1,112 @@
#pragma once
// qt incl
#include <QObject>
#include <QJsonObject>
// components def
#include <utils/Components.h>
// bonjour
#include <bonjour/bonjourrecord.h>
// videModes
#include <utils/VideoMode.h>
// settings
#include <utils/settings.h>
class Hyperion;
class ComponentRegister;
class BonjourBrowserWrapper;
class PriorityMuxer;
class JsonCB : public QObject
{
Q_OBJECT
public:
JsonCB(QObject* parent);
///
/// @brief Subscribe to future data updates given by cmd
/// @param cmd The cmd which will be subscribed for
/// @return True on success, false if not found
///
bool subscribeFor(const QString& cmd);
///
/// @brief Get all possible commands to subscribe for
/// @return The list of commands
///
QStringList getCommands() { return _availableCommands; };
///
/// @brief Get all subscribed commands
/// @return The list of commands
///
QStringList getSubscribedCommands() { return _subscribedCommands; };
signals:
///
/// @brief Emits whenever a new json mesage callback is ready to send
/// @param The JsonObject message
///
void newCallback(QJsonObject);
private slots:
///
/// @brief handle component state changes
///
void handleComponentState(const hyperion::Components comp, const bool state);
///
/// @brief handle emits from bonjour wrapper
/// @param bRegisters The full register map
///
void handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters);
///
/// @brief handle emits from PriorityMuxer
///
void handlePriorityUpdate();
///
/// @brief Handle imageToLedsMapping updates
///
void handleImageToLedsMappingChange(const int& mappingType);
///
/// @brief Handle the adjustment update
///
void handleAdjustmentChange();
///
/// @brief Handle video mode change
/// @param mode The new videoMode
///
void handleVideoModeChange(const VideoMode& mode);
///
/// @brief Handle effect list change
///
void handleEffectListChange();
///
/// @brief Handle a config part change. This does NOT include (global) changes from other hyperion instances
/// @param type The settings type from enum
/// @param data The data as QJsonDocument
///
void handleSettingsChange(const settings::type& type, const QJsonDocument& data);
private:
/// pointer of Hyperion instance
Hyperion* _hyperion;
/// pointer of comp register
ComponentRegister* _componentRegister;
/// Bonjour instance
BonjourBrowserWrapper* _bonjour;
/// priority muxer instance
PriorityMuxer* _prioMuxer;
/// contains all available commands
QStringList _availableCommands;
/// contains active subscriptions
QStringList _subscribedCommands;
/// construct callback msg
void doCallback(const QString& cmd, const QVariant& data);
};

View File

@ -89,10 +89,9 @@ namespace hyperion
// find first X pixel of the image // find first X pixel of the image
for (int x = 0; x < width33percent; ++x) for (int x = 0; x < width33percent; ++x)
{ {
const Pixel_T & color1 = image( (width - x), yCenter); // right side center line check if (!isBlack(image((width - x), yCenter))
const Pixel_T & color2 = image(x, height33percent); || !isBlack(image(x, height33percent))
const Pixel_T & color3 = image(x, height66percent); || !isBlack(image(x, height66percent)))
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
{ {
firstNonBlackXPixelIndex = x; firstNonBlackXPixelIndex = x;
break; break;
@ -102,10 +101,9 @@ namespace hyperion
// find first Y pixel of the image // find first Y pixel of the image
for (int y = 0; y < height33percent; ++y) for (int y = 0; y < height33percent; ++y)
{ {
const Pixel_T & color1 = image(xCenter, (height - y)); // bottom center line check if (!isBlack(image(xCenter, (height - y)))
const Pixel_T & color2 = image(width33percent, y ); || !isBlack(image(width33percent, y))
const Pixel_T & color3 = image(width66percent, y); || !isBlack(image(width66percent, y)))
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
{ {
firstNonBlackYPixelIndex = y; firstNonBlackYPixelIndex = y;
break; break;
@ -203,10 +201,9 @@ namespace hyperion
int x; int x;
for (x = 0; x < width33percent; ++x) for (x = 0; x < width33percent; ++x)
{ {
const Pixel_T & color1 = image( (width - x), yCenter); // right side center line check if (!isBlack(image((width - x), yCenter))
const Pixel_T & color2 = image(x, height33percent); || !isBlack(image(x, height33percent))
const Pixel_T & color3 = image(x, height66percent); || !isBlack(image(x, height66percent)))
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
{ {
firstNonBlackXPixelIndex = x; firstNonBlackXPixelIndex = x;
break; break;
@ -216,13 +213,13 @@ namespace hyperion
// find first Y pixel of the image // find first Y pixel of the image
for (int y = 0; y < height33percent; ++y) for (int y = 0; y < height33percent; ++y)
{ {
const Pixel_T & color1 = image(x, y );// left side top check // left side top + left side bottom + right side top + right side bottom
const Pixel_T & color2 = image(x, (height - y)); // left side bottom check if (!isBlack(image(x, y))
const Pixel_T & color3 = image( (width - x), y); // right side top check || !isBlack(image(x, (height - y)))
const Pixel_T & color4 = image( (width - x), (height - y)); // right side bottom check || !isBlack(image((width - x), y))
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3) || !isBlack(color4)) || !isBlack(image((width - x), (height - y))))
{ {
// std::cout << "y " << y << " lt " << int(isBlack(color1)) << " lb " << int(isBlack(color2)) << " rt " << int(isBlack(color3)) << " rb " << int(isBlack(color4)) << std::endl; // std::cout << "y " << y << " lt " << int(isBlack(color1)) << " lb " << int(isBlack(color2)) << " rt " << int(isBlack(color3)) << " rb " << int(isBlack(color4)) << std::endl;
firstNonBlackYPixelIndex = y; firstNonBlackYPixelIndex = y;
break; break;
} }

View File

@ -4,30 +4,28 @@
// QT includes // QT includes
#include <QJsonObject> #include <QJsonObject>
// util
#include <utils/Logger.h>
#include <utils/settings.h>
#include <utils/Components.h>
// Local Hyperion includes // Local Hyperion includes
#include "BlackBorderDetector.h" #include "BlackBorderDetector.h"
class Hyperion;
namespace hyperion namespace hyperion
{ {
/// ///
/// The BlackBorder processor is a wrapper around the black-border detector for keeping track of /// The BlackBorder processor is a wrapper around the black-border detector for keeping track of
/// detected borders and count of the type and size of detected borders. /// detected borders and count of the type and size of detected borders.
/// ///
class BlackBorderProcessor class BlackBorderProcessor : public QObject
{ {
Q_OBJECT
public: public:
/// BlackBorderProcessor(Hyperion* hyperion, QObject* parent);
/// Constructor for the BlackBorderProcessor ~BlackBorderProcessor();
/// @param unknownFrameCnt The number of frames(images) that need to contain an unknown
/// border before the current border is set to unknown
/// @param borderFrameCnt The number of frames(images) that need to contain a vertical or
/// horizontal border becomes the current border
/// @param blurRemoveCnt The size to add to a horizontal or vertical border (because the
/// outer pixels is blurred (black and color combined due to image scaling))
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
///
BlackBorderProcessor(const QJsonObject &blackborderConfig);
/// ///
/// Return the current (detected) border /// Return the current (detected) border
/// @return The current border /// @return The current border
@ -46,6 +44,13 @@ namespace hyperion
/// ///
void setEnabled(bool enable); void setEnabled(bool enable);
///
/// Sets the _hardDisabled state, if True prevents the enable from COMP_BLACKBORDER state emit (mimiks wrong state to external!)
/// It's not possible to enable bb from this method, if the user requsted a disable!
/// @param disable The new state
///
void setHardDisable(const bool& disable);
/// ///
/// Processes the image. This performs detecion of black-border on the given image and /// Processes the image. This performs detecion of black-border on the given image and
/// updates the current border accordingly. If the current border is updated the method call /// updates the current border accordingly. If the current border is updated the method call
@ -70,11 +75,11 @@ namespace hyperion
} }
if (_detectionMode == "default") { if (_detectionMode == "default") {
imageBorder = _detector.process(image); imageBorder = _detector->process(image);
} else if (_detectionMode == "classic") { } else if (_detectionMode == "classic") {
imageBorder = _detector.process_classic(image); imageBorder = _detector->process_classic(image);
} else if (_detectionMode == "osd") { } else if (_detectionMode == "osd") {
imageBorder = _detector.process_osd(image); imageBorder = _detector->process_osd(image);
} }
// add blur to the border // add blur to the border
if (imageBorder.horizontalSize > 0) if (imageBorder.horizontalSize > 0)
@ -89,8 +94,23 @@ namespace hyperion
const bool borderUpdated = updateBorder(imageBorder); const bool borderUpdated = updateBorder(imageBorder);
return borderUpdated; return borderUpdated;
} }
private slots:
///
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
/// @param type settingyType from enum
/// @param config configuration object
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
///
/// @brief Handle component state changes, it's not possible for BB to be enabled, when a hardDisable is active
///
void componentStateChanged(const hyperion::Components component, bool enable);
private: private:
/// Hyperion instance
Hyperion* _hyperion;
/// ///
/// Updates the current border based on the newly detected border. Returns true if the /// Updates the current border based on the newly detected border. Returns true if the
/// current border has changed. /// current border has changed.
@ -102,24 +122,24 @@ namespace hyperion
/// flag for blackborder detector usage /// flag for blackborder detector usage
bool _enabled; bool _enabled;
/// The number of unknown-borders detected before it becomes the current border /// The number of unknown-borders detected before it becomes the current border
const unsigned _unknownSwitchCnt; unsigned _unknownSwitchCnt;
/// The number of horizontal/vertical borders detected before it becomes the current border /// The number of horizontal/vertical borders detected before it becomes the current border
const unsigned _borderSwitchCnt; unsigned _borderSwitchCnt;
// The number of frames that are "ignored" before a new border gets set as _previousDetectedBorder // The number of frames that are "ignored" before a new border gets set as _previousDetectedBorder
const unsigned _maxInconsistentCnt; unsigned _maxInconsistentCnt;
/// The number of pixels to increase a detected border for removing blury pixels /// The number of pixels to increase a detected border for removing blury pixels
unsigned _blurRemoveCnt; unsigned _blurRemoveCnt;
/// The border detection mode /// The border detection mode
const QString _detectionMode; QString _detectionMode;
/// The blackborder detector /// The blackborder detector
BlackBorderDetector _detector; BlackBorderDetector* _detector;
/// The current detected border /// The current detected border
BlackBorder _currentBorder; BlackBorder _currentBorder;
@ -131,5 +151,12 @@ namespace hyperion
unsigned _consistentCnt; unsigned _consistentCnt;
/// The number of frame the previous detected border NOT matched the incomming border /// The number of frame the previous detected border NOT matched the incomming border
unsigned _inconsistentCnt; unsigned _inconsistentCnt;
/// old threshold
double _oldThreshold;
/// True when disabled in specific situations, this prevents to enable BB when the visible priority requested a disable
bool _hardDisabled;
/// Reflect the last component state request from user (comp change)
bool _userEnabled;
}; };
} // end namespace hyperion } // end namespace hyperion

View File

@ -4,15 +4,19 @@
#include <cstdint> #include <cstdint>
// Qt includes // Qt includes
#include <QTcpServer>
#include <QSet> #include <QSet>
#include <QJsonDocument>
// Hyperion includes // Hyperion includes
#include <hyperion/Hyperion.h>
#include <utils/Logger.h> #include <utils/Logger.h>
#include <utils/Components.h> #include <utils/Components.h>
// settings
#include <utils/settings.h>
class BoblightClientConnection; class BoblightClientConnection;
class Hyperion;
class QTcpServer;
/// ///
/// This class creates a TCP server which accepts connections from boblight clients. /// This class creates a TCP server which accepts connections from boblight clients.
@ -27,25 +31,24 @@ public:
/// @param hyperion Hyperion instance /// @param hyperion Hyperion instance
/// @param port port number on which to start listening for connections /// @param port port number on which to start listening for connections
/// ///
BoblightServer(const int priority, uint16_t port = 19333); BoblightServer(Hyperion* hyperion, const QJsonDocument& config);
~BoblightServer(); ~BoblightServer();
/// ///
/// @return the port number on which this TCP listens for incoming connections /// @return the port number on which this TCP listens for incoming connections
/// ///
uint16_t getPort() const; uint16_t getPort() const;
/// @return true if server is active (bind to a port) /// @return true if server is active (bind to a port)
/// ///
bool active() { return _isActive; }; bool active();
bool componentState() { return active(); };
public slots: public slots:
/// ///
/// bind server to network /// bind server to network
/// ///
void start(); void start();
/// ///
/// close server /// close server
/// ///
@ -53,8 +56,12 @@ public slots:
void componentStateChanged(const hyperion::Components component, bool enable); void componentStateChanged(const hyperion::Components component, bool enable);
signals: ///
void statusChanged(bool isActive); /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
/// @param type settingyType from enum
/// @param config configuration object
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
private slots: private slots:
/// ///
@ -73,19 +80,17 @@ private:
Hyperion * _hyperion; Hyperion * _hyperion;
/// The TCP server object /// The TCP server object
QTcpServer _server; QTcpServer * _server;
/// List with open connections /// List with open connections
QSet<BoblightClientConnection *> _openConnections; QSet<BoblightClientConnection *> _openConnections;
/// hyperion priority /// hyperion priority
const int _priority; int _priority;
/// Logger instance /// Logger instance
Logger * _log; Logger * _log;
/// state of connection // current port
bool _isActive;
uint16_t _port; uint16_t _port;
}; };

View File

@ -0,0 +1,68 @@
#pragma once
// qt incl
#include <QObject>
#include <QMap>
#include <QHostInfo>
#include <bonjour/bonjourrecord.h>
class BonjourServiceBrowser;
class BonjourServiceResolver;
class QTimer;
class BonjourBrowserWrapper : public QObject
{
Q_OBJECT
private:
friend class HyperionDaemon;
///
/// @brief Browse for hyperion services in bonjour, constructed from HyperionDaemon
/// Searching for hyperion http service by default
///
BonjourBrowserWrapper(QObject * parent = 0);
public:
///
/// @brief Browse for a service
///
bool browseForServiceType(const QString &serviceType);
///
/// @brief Get all available sessions
///
QMap<QString,BonjourRecord> getAllServices() { return _hyperionSessions; };
static BonjourBrowserWrapper* instance;
static BonjourBrowserWrapper* getInstance(){ return instance; };
signals:
///
/// @brief Emits whenever a change happend
///
void browserChange(const QMap<QString,BonjourRecord>& bRegisters);
private:
/// map of service names and browsers
QMap< QString, BonjourServiceBrowser* > _browsedServices;
/// Resolver
BonjourServiceResolver* _bonjourResolver;
// contains all current active service sessions
QMap<QString,BonjourRecord> _hyperionSessions;
QString _bonjourCurrentServiceToResolve;
/// timer to resolve changes
QTimer* _timerBonjourResolver;
private slots:
///
/// @brief is called whenever a BonjourServiceBrowser emits change
void currentBonjourRecordsChanged(const QList<BonjourRecord> &list);
/// @brief new record resolved
void bonjourRecordResolved(const QHostInfo &hostInfo, int port);
///
/// @brief timer slot which updates regularly entries
///
void bonjourResolve();
};

View File

@ -43,9 +43,12 @@ public:
BonjourServiceRegister(QObject *parent = 0); BonjourServiceRegister(QObject *parent = 0);
~BonjourServiceRegister(); ~BonjourServiceRegister();
void registerService(const BonjourRecord &record, quint16 servicePort, std::vector<std::pair<std::string, std::string>> txt); void registerService(const QString& service, const int& port);
void registerService(const BonjourRecord &record, quint16 servicePort, std::vector<std::pair<std::string, std::string>> txt = std::vector<std::pair<std::string, std::string>>());
inline BonjourRecord registeredRecord() const {return finalRecord; } inline BonjourRecord registeredRecord() const {return finalRecord; }
const quint16 & getPort() { return _port; };
signals: signals:
void error(DNSServiceErrorType error); void error(DNSServiceErrorType error);
void serviceRegistered(const BonjourRecord &record); void serviceRegistered(const BonjourRecord &record);
@ -61,6 +64,9 @@ private:
DNSServiceRef dnssref; DNSServiceRef dnssref;
QSocketNotifier *bonjourSocket; QSocketNotifier *bonjourSocket;
BonjourRecord finalRecord; BonjourRecord finalRecord;
// current port
quint16 _port = 0;
}; };
#endif // BONJOURSERVICEREGISTER_H #endif // BONJOURSERVICEREGISTER_H

View File

@ -0,0 +1,97 @@
#pragma once
// Python includes
// collide of qt slots macro
#undef slots
#include "Python.h"
#define slots
// Qt includes
#include <QThread>
#include <QJsonObject>
#include <QSize>
#include <QImage>
#include <QPainter>
#include <QMap>
// Hyperion includes
#include <utils/Components.h>
#include <utils/Image.h>
class Hyperion;
class Logger;
class Effect : public QThread
{
Q_OBJECT
public:
friend class EffectModule;
Effect(Hyperion *hyperion
, int priority
, int timeout
, const QString &script
, const QString &name
, const QJsonObject &args = QJsonObject()
, const QString &imageData = ""
);
virtual ~Effect();
virtual void run();
int getPriority() const { return _priority; };
///
/// @brief Set manual interuption to true,
/// Note: DO NOT USE QThread::interuption!
///
void setInteruptionFlag() { _interupt = true; };
///
/// @brief Check if the interuption flag has been set
/// @return The flag state
///
bool hasInteruptionFlag() { return _interupt; };
QString getScript() const { return _script; }
QString getName() const { return _name; }
int getTimeout() const {return _timeout; }
QJsonObject getArgs() const { return _args; }
signals:
void setInput(const int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms, const bool &clearEffect);
void setInputImage(const int priority, const Image<ColorRgb> &image, const int timeout_ms, const bool &clearEffect);
private:
void addImage();
Hyperion *_hyperion;
const int _priority;
const int _timeout;
const QString _script;
const QString _name;
const QJsonObject _args;
const QString _imageData;
int64_t _endTime;
/// Buffer for colorData
QVector<ColorRgb> _colors;
Logger *_log;
// Reflects whenever this effects should interupt (timeout or external request)
bool _interupt = false;
QSize _imageSize;
QImage _image;
QPainter *_painter;
QVector<QImage> _imageStack;
};

View File

@ -17,38 +17,72 @@
#include <effectengine/EffectSchema.h> #include <effectengine/EffectSchema.h>
#include <utils/Logger.h> #include <utils/Logger.h>
// pre-declarioation // pre-declaration
class Effect; class Effect;
typedef struct _ts PyThreadState; class EffectFileHandler;
class EffectEngine : public QObject class EffectEngine : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
EffectEngine(Hyperion * hyperion, const QJsonObject & jsonEffectConfig); EffectEngine(Hyperion * hyperion);
virtual ~EffectEngine(); virtual ~EffectEngine();
void readEffects(); const std::list<EffectDefinition> & getEffects() const { return _availableEffects; };
const std::list<EffectDefinition> & getEffects() const
{
return _availableEffects;
};
const std::list<ActiveEffectDefinition> & getActiveEffects(); const std::list<ActiveEffectDefinition> & getActiveEffects();
const std::list<EffectSchema> & getEffectSchemas() ///
{ /// Get available schemas from EffectFileHandler
return _effectSchemas; /// @return all schemas
}; ///
const std::list<EffectSchema> & getEffectSchemas();
///
/// @brief Save an effect with EffectFileHandler
/// @param obj The effect args
/// @param[out] resultMsg The feedback message
/// @return True on success else false
///
const bool saveEffect(const QJsonObject& obj, QString& resultMsg);
///
/// @brief Delete an effect by name.
/// @param[in] effectName The effect name to delete
/// @param[out] resultMsg The message on error
/// @return True on success else false
///
const bool deleteEffect(const QString& effectName, QString& resultMsg);
///
/// @brief Get all init data of the running effects and stop them
///
void cacheRunningEffects();
///
/// @brief Start all cached effects, origin and smooth cfg is default
///
void startCachedEffects();
signals:
/// Emit when the effect list has been updated
void effectListUpdated();
public slots: public slots:
/// Run the specified effect on the given priority channel and optionally specify a timeout /// Run the specified effect on the given priority channel and optionally specify a timeout
int runEffect(const QString &effectName, int priority, int timeout = -1, const QString &origin="System"); int runEffect(const QString &effectName, int priority, int timeout = -1, const QString &origin="System");
/// Run the specified effect on the given priority channel and optionally specify a timeout /// Run the specified effect on the given priority channel and optionally specify a timeout
int runEffect(const QString &effectName, const QJsonObject & args, int priority, int timeout = -1, const QString &pythonScript = "", const QString &origin = "System", unsigned smoothCfg=0); int runEffect(const QString &effectName
, const QJsonObject &args
, int priority
, int timeout = -1
, const QString &pythonScript = ""
, const QString &origin = "System"
, unsigned smoothCfg=0
, const QString &imageData = ""
);
/// Clear any effect running on the provided channel /// Clear any effect running on the provided channel
void channelCleared(int priority); void channelCleared(int priority);
@ -59,28 +93,36 @@ public slots:
private slots: private slots:
void effectFinished(); void effectFinished();
///
/// @brief is called whenever the EffectFileHandler emits updated effect list
///
void handleUpdatedEffectList();
private: private:
bool loadEffectDefinition(const QString & path, const QString & effectConfigFile, EffectDefinition &effectDefinition);
bool loadEffectSchema(const QString & path, const QString & effectSchemaFile, EffectSchema &effectSchema);
/// Run the specified effect on the given priority channel and optionally specify a timeout /// Run the specified effect on the given priority channel and optionally specify a timeout
int runEffectScript(const QString &script, const QString &name, const QJsonObject & args, int priority, int timeout = -1, const QString & origin="System", unsigned smoothCfg=0); int runEffectScript(const QString &script
,const QString &name
, const QJsonObject &args
, int priority
, int timeout = -1
, const QString &origin="System"
, unsigned smoothCfg=0
, const QString &imageData = ""
);
private: private:
Hyperion * _hyperion; Hyperion * _hyperion;
QJsonObject _effectConfig;
std::list<EffectDefinition> _availableEffects; std::list<EffectDefinition> _availableEffects;
std::list<Effect *> _activeEffects; std::list<Effect *> _activeEffects;
std::list<ActiveEffectDefinition> _availableActiveEffects; std::list<ActiveEffectDefinition> _availableActiveEffects;
std::list<EffectSchema> _effectSchemas; std::list<ActiveEffectDefinition> _cachedActiveEffects;
Logger * _log; Logger * _log;
PyThreadState* _mainThreadState; // The global effect file handler
EffectFileHandler* _effectFileHandler;
}; };

View File

@ -0,0 +1,86 @@
#pragma once
// util
#include <utils/Logger.h>
#include <effectengine/EffectDefinition.h>
#include <effectengine/EffectSchema.h>
#include <utils/settings.h>
class EffectFileHandler : public QObject
{
Q_OBJECT
private:
friend class HyperionDaemon;
EffectFileHandler(const QString& rootPath, const QJsonDocument& effectConfig, QObject* parent = nullptr);
public:
static EffectFileHandler* efhInstance;
static EffectFileHandler* getInstance() { return efhInstance; };
///
/// @brief Get all available effects
///
const std::list<EffectDefinition> & getEffects() const { return _availableEffects; };
///
/// @brief Get all available schemas
///
const std::list<EffectSchema> & getEffectSchemas() { return _effectSchemas; };
///
/// @brief Save an effect
/// @param obj The effect args
/// @param[out] resultMsg The feedback message
/// @return True on success else false
///
const bool saveEffect(const QJsonObject& obj, QString& resultMsg);
///
/// @brief Delete an effect by name.
/// @param[in] effectName The effect name to delete
/// @param[out] resultMsg The message on error
/// @return True on success else false
///
const bool deleteEffect(const QString& effectName, QString& resultMsg);
public slots:
///
/// @brief Handle settings update from Hyperion Settingsmanager emit
/// @param type settingyType from enum
/// @param config configuration object
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
signals:
///
/// @brief Emits whenever the data changes for an effect
///
void effectListChanged();
private:
///
/// @brief refresh available schemas and effects
///
void updateEffects();
///
/// @brief Load the effect definition, called by updateEffects()
///
bool loadEffectDefinition(const QString & path, const QString & effectConfigFile, EffectDefinition &effectDefinition);
///
/// @brief load effect schemas, called by updateEffects()
///
bool loadEffectSchema(const QString & path, const QString & effectSchemaFile, EffectSchema &effectSchema);
private:
QJsonObject _effectConfig;
Logger* _log;
const QString _rootPath;
// available effects
std::list<EffectDefinition> _availableEffects;
// all schemas
std::list<EffectSchema> _effectSchemas;
};

View File

@ -1,49 +1,27 @@
#pragma once #pragma once
// Python includes
// collide of qt slots macro
#undef slots #undef slots
#include <Python.h> #include <Python.h>
#define slots #define slots
// Qt includes #include <QJsonValue>
#include <QThread>
#include <QSize>
#include <QImage>
#include <QPainter>
#include <QMap>
// Hyperion includes class Effect;
#include <hyperion/ImageProcessor.h>
#include <utils/Components.h>
class Effect : public QThread class EffectModule
{ {
Q_OBJECT
public: public:
Effect(PyThreadState* mainThreadState, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args = QJsonObject(), const QString & origin="System", unsigned smoothCfg=0); // Python 3 module def
virtual ~Effect(); static struct PyModuleDef moduleDef;
virtual void run(); // Init module
static PyObject* PyInit_hyperion();
int getPriority() const { return _priority; }; // Register module once
static void registerHyperionExtensionModule();
QString getScript() const { return _script; } // json 2 python
QString getName() const { return _name; } static PyObject * json2python(const QJsonValue & jsonData);
int getTimeout() const {return _timeout; }
QJsonObject getArgs() const { return _args; }
/// This function registers the extension module in Python
static void registerHyperionExtensionModule();
signals:
void setColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms, bool clearEffects, hyperion::Components componentconst, QString origin, unsigned smoothCfg);
private:
PyObject * json2python(const QJsonValue & jsonData) const;
// Wrapper methods for Python interpreter extra buildin methods // Wrapper methods for Python interpreter extra buildin methods
static PyMethodDef effectMethods[]; static PyMethodDef effectMethods[];
@ -71,38 +49,5 @@ private:
static PyObject* wrapImageCOffset (PyObject *self, PyObject *args); static PyObject* wrapImageCOffset (PyObject *self, PyObject *args);
static PyObject* wrapImageCShear (PyObject *self, PyObject *args); static PyObject* wrapImageCShear (PyObject *self, PyObject *args);
static PyObject* wrapImageResetT (PyObject *self, PyObject *args); static PyObject* wrapImageResetT (PyObject *self, PyObject *args);
static Effect * getEffect(); static Effect * getEffect();
static struct PyModuleDef moduleDef;
static PyObject* PyInit_hyperion();
void addImage();
PyThreadState* _mainThreadState;
const int _priority;
const int _timeout;
const QString _script;
const QString _name;
unsigned _smoothCfg;
const QJsonObject _args;
int64_t _endTime;
/// The processor for translating images to led-values
ImageProcessor * _imageProcessor;
/// Buffer for colorData
QVector<ColorRgb> _colors;
Logger* _log;
QString _origin;
QSize _imageSize;
QImage _image;
QPainter* _painter;
QVector<QImage> _imageStack;
}; };

View File

@ -0,0 +1,134 @@
#pragma once
// Qt includes
#include <QString>
#include <QColor>
#include <QImage>
#include <QTcpSocket>
#include <QTimer>
#include <QMap>
// hyperion util
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/VideoMode.h>
#include <utils/Logger.h>
// flatbuffer FBS
#include "hyperion_reply_generated.h"
#include "hyperion_request_generated.h"
///
/// Connection class to setup an connection to the hyperion server and execute commands.
///
class FlatBufferConnection : public QObject
{
Q_OBJECT
public:
///
/// @brief Constructor
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
/// @param skipReply If true skip reply
///
FlatBufferConnection(const QString& origin, const QString & address, const int& priority, const bool& skipReply);
///
/// @brief Destructor
///
~FlatBufferConnection();
/// @brief Do not read reply messages from Hyperion if set to true
void setSkipReply(const bool& skip);
///
/// @brief Register a new priority with given origin
/// @param origin The user friendly origin string
/// @param priority The priority to register
///
void setRegister(const QString& origin, int priority);
///
/// @brief Set all leds to the specified color
/// @param color The color
/// @param priority The priority
/// @param duration The duration in milliseconds
///
void setColor(const ColorRgb & color, int priority, int duration = 1);
///
/// @brief Clear the given priority channel
/// @param priority The priority
///
void clear(int priority);
///
/// @brief Clear all priority channels
///
void clearAll();
///
/// @brief Send a command message and receive its reply
/// @param message The message to send
///
void sendMessage(const uint8_t* buffer, uint32_t size);
public slots:
///
/// @brief Set the leds according to the given image
/// @param image The image
///
void setImage(const Image<ColorRgb> &image);
private slots:
///
/// @brief Try to connect to the Hyperion host
///
void connectToHost();
///
/// @brief Slot called when new data has arrived
///
void readData();
signals:
///
/// @brief emits when a new videoMode was requested from flatbuf client
///
void setVideoMode(const VideoMode videoMode);
private:
///
/// @brief Parse a reply message
/// @param reply The received reply
/// @return true if the reply indicates success
///
bool parseReply(const hyperionnet::Reply *reply);
private:
/// The TCP-Socket with the connection to the server
QTcpSocket _socket;
QString _origin;
int _priority;
/// Host address
QString _host;
/// Host port
uint16_t _port;
/// buffer for reply
QByteArray _receiveBuffer;
QTimer _timer;
QAbstractSocket::SocketState _prevSocketState;
Logger * _log;
flatbuffers::FlatBufferBuilder _builder;
bool _registered;
};

View File

@ -0,0 +1,65 @@
#pragma once
// util
#include <utils/Logger.h>
#include <utils/settings.h>
// qt
#include <QVector>
class QTcpServer;
class FlatBufferClient;
///
/// @brief A TcpServer to receive images of different formats with Google Flatbuffer
/// Images will be forwarded to all Hyperion instances
///
class FlatBufferServer : public QObject
{
Q_OBJECT
public:
FlatBufferServer(const QJsonDocument& config, QObject* parent = nullptr);
~FlatBufferServer();
public slots:
///
/// @brief Handle settings update
/// @param type The type from enum
/// @param config The configuration
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
void initServer();
private slots:
///
/// @brief Is called whenever a new socket wants to connect
///
void newConnection();
///
/// @brief is called whenever a client disconnected
///
void clientDisconnected();
private:
///
/// @brief Start the server with current _port
///
void startServer();
///
/// @brief Stop server
///
void stopServer();
private:
QTcpServer* _server;
Logger* _log;
int _timeout;
quint16 _port;
const QJsonDocument _config;
QVector<FlatBufferClient*> _openConnections;
};

View File

@ -18,9 +18,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels] /// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels] /// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz] /// @param[in] updateRate_Hz The image grab rate [Hz]
/// @param[in] hyperion The instance of Hyperion used to write the led values
/// ///
AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority); AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
/// ///
/// Destructor of this dispmanx frame grabber. Releases any claimed resources. /// Destructor of this dispmanx frame grabber. Releases any claimed resources.

View File

@ -40,14 +40,23 @@ public:
/// ///
int grabFrame(Image<ColorRgb> & image); int grabFrame(Image<ColorRgb> & image);
///
///@brief Set new width and height for dispmanx, overwrite Grabber.h impl
virtual bool setWidthHeight(int width, int height);
private: private:
/// ///
/// Updates the frame-grab flags as used by the VC library for frame grabbing /// Updates the frame-grab flags as used by the VC library for frame grabbing
/// ///
/// @param vc_flags The snapshot grabbing mask /// @param vc_flags The snapshot grabbing mask
/// ///
void setFlags(const int vc_flags); void setFlags(const int vc_flags);
///
/// @brief free _vc_resource and captureBuffer
///
void freeResources();
/// Handle to the display that is being captured /// Handle to the display that is being captured
DISPMANX_DISPLAY_HANDLE_T _vc_display; DISPMANX_DISPLAY_HANDLE_T _vc_display;

View File

@ -7,8 +7,7 @@
/// ///
/// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the /// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the
/// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the /// displayed content. This ImageRgb is forwarded to all Hyperion instances via HyperionDaemon
/// attached Hyperion.
/// ///
class DispmanxWrapper: public GrabberWrapper class DispmanxWrapper: public GrabberWrapper
{ {
@ -20,9 +19,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels] /// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels] /// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz] /// @param[in] updateRate_Hz The image grab rate [Hz]
/// @param[in] hyperion The instance of Hyperion used to write the led values
/// ///
DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority); DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
/// ///
/// Destructor of this dispmanx frame grabber. Releases any claimed resources. /// Destructor of this dispmanx frame grabber. Releases any claimed resources.

View File

@ -5,7 +5,7 @@
#include <hyperion/Grabber.h> #include <hyperion/Grabber.h>
/// ///
/// The FramebufferFrameGrabber is used for creating snapshots of the display (screenshots) /// The FramebufferFrameGrabber is used for creating snapshots of the display (screenshots)
/// ///
class FramebufferFrameGrabber : public Grabber class FramebufferFrameGrabber : public Grabber
{ {
@ -30,13 +30,18 @@ public:
/// ///
int grabFrame(Image<ColorRgb> & image); int grabFrame(Image<ColorRgb> & image);
///
/// @brief Overwrite Grabber.h implememtation
///
virtual void setDevicePath(const QString& path);
private: private:
/// Framebuffer file descriptor /// Framebuffer file descriptor
int _fbfd; int _fbfd;
/// Pointer to framebuffer /// Pointer to framebuffer
unsigned char * _fbp; unsigned char * _fbp;
/// Framebuffer device e.g. /dev/fb0 /// Framebuffer device e.g. /dev/fb0
const QString _fbDevice; QString _fbDevice;
}; };

View File

@ -20,7 +20,7 @@ public:
/// @param[in] grabHeight The height of the grabbed images [pixels] /// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz] /// @param[in] updateRate_Hz The image grab rate [Hz]
/// ///
FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority); FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
/// ///
/// Destructor of this framebuffer frame grabber. Releases any claimed resources. /// Destructor of this framebuffer frame grabber. Releases any claimed resources.

View File

@ -12,7 +12,7 @@
#include <hyperion/Grabber.h> #include <hyperion/Grabber.h>
/// ///
/// The OsxFrameGrabber is used for creating snapshots of the display (screenshots) /// The OsxFrameGrabber is used for creating snapshots of the display (screenshots)
/// ///
class OsxFrameGrabber : public Grabber class OsxFrameGrabber : public Grabber
{ {
@ -37,10 +37,15 @@ public:
/// ///
int grabFrame(Image<ColorRgb> & image); int grabFrame(Image<ColorRgb> & image);
private: ///
/// @brief Overwrite Grabber.h implementation
///
virtual void setDisplayIndex(int index);
private:
/// display /// display
const unsigned _screenIndex; unsigned _screenIndex;
/// Reference to the captured diaplay /// Reference to the captured diaplay
CGDirectDisplayID _display; CGDirectDisplayID _display;
}; };

View File

@ -19,9 +19,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels] /// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels] /// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz] /// @param[in] updateRate_Hz The image grab rate [Hz]
/// @param[in] hyperion The instance of Hyperion used to write the led values
/// ///
OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority); OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
/// ///
/// Destructor of this osx frame grabber. Releases any claimed resources. /// Destructor of this osx frame grabber. Releases any claimed resources.

View File

@ -0,0 +1,96 @@
#pragma once
#include <QObject>
// Hyperion-utils includes
#include <utils/ColorRgb.h>
#include <hyperion/Grabber.h>
class QScreen;
///
/// @brief The platform capture implementation based on QT API
///
class QtGrabber : public Grabber
{
public:
QtGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display);
virtual ~QtGrabber();
///
/// Captures a single snapshot of the display and writes the data to the given image. The
/// provided image should have the same dimensions as the configured values (_width and
/// _height)
///
/// @param[out] image The snapped screenshot (should be initialized with correct width and
/// height)
///
virtual int grabFrame(Image<ColorRgb> & image);
///
/// @brief Set a new video mode
///
virtual void setVideoMode(VideoMode mode);
///
/// @brief Apply new width/height values, overwrite Grabber.h implementation as qt doesn't use width/height, just pixelDecimation to calc dimensions
///
virtual bool setWidthHeight(int width, int height) { return true; };
///
/// @brief Apply new pixelDecimation
///
virtual void setPixelDecimation(int pixelDecimation);
///
/// Set the crop values
/// @param cropLeft Left pixel crop
/// @param cropRight Right pixel crop
/// @param cropTop Top pixel crop
/// @param cropBottom Bottom pixel crop
///
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
///
/// @brief Apply display index
///
virtual void setDisplayIndex(int index);
private slots:
///
/// @brief is called whenever the current _screen changes it's geometry
/// @param geo The new geometry
///
void geometryChanged(const QRect &geo);
private:
///
/// @brief Setup a new capture display, will free the previous one
/// @return True on success, false if no display is found
///
const bool setupDisplay();
///
/// @brief Is called whenever we need new screen dimension calculations based on window geometry
///
int updateScreenDimensions(const bool& force);
///
/// @brief free the _screen pointer
///
void freeResources();
private:
unsigned _display;
int _pixelDecimation;
unsigned _screenWidth;
unsigned _screenHeight;
unsigned _src_x;
unsigned _src_y;
unsigned _src_x_max;
unsigned _src_y_max;
QScreen* _screen;
};

View File

@ -0,0 +1,38 @@
#pragma once
#include <hyperion/GrabberWrapper.h>
#include <grabber/QtGrabber.h>
///
/// The QtWrapper uses QtFramework API's to get a picture from system
///
class QtWrapper: public GrabberWrapper
{
public:
///
/// Constructs the framebuffer frame grabber with a specified grab size and update rate.
///
/// @param[in] cropLeft Remove from left [pixels]
/// @param[in] cropRight Remove from right [pixels]
/// @param[in] cropTop Remove from top [pixels]
/// @param[in] cropBottom Remove from bottom [pixels]
/// @param[in] pixelDecimation Decimation factor for image [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
///
QtWrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display, const unsigned updateRate_Hz);
///
/// Destructor of this qt frame grabber. Releases any claimed resources.
///
virtual ~QtWrapper() {};
public slots:
///
/// Performs a single frame grab and computes the led-colors
///
virtual void action();
private:
/// The actual grabber
QtGrabber _grabber;
};

View File

@ -23,13 +23,9 @@ class V4L2Grabber : public Grabber
public: public:
V4L2Grabber(const QString & device, V4L2Grabber(const QString & device,
int input, VideoStandard videoStandard,
VideoStandard videoStandard, PixelFormat pixelFormat, PixelFormat pixelFormat,
unsigned width, int pixelDecimation
unsigned height,
int frameDecimation,
int horizontalPixelDecimation,
int verticalPixelDecimation
); );
virtual ~V4L2Grabber(); virtual ~V4L2Grabber();
@ -37,21 +33,46 @@ public:
bool getSignalDetectionEnabled(); bool getSignalDetectionEnabled();
int grabFrame(Image<ColorRgb> &); int grabFrame(Image<ColorRgb> &);
public slots: ///
void setSignalThreshold( /// @brief overwrite Grabber.h implementation, as v4l doesn't use width/height
///
virtual void setWidthHeight(){};
///
/// @brief set new PixelDecimation value to ImageResampler
/// @param pixelDecimation The new pixelDecimation value
///
virtual void setPixelDecimation(int pixelDecimation);
///
/// @brief overwrite Grabber.h implementation
///
virtual void setSignalThreshold(
double redSignalThreshold, double redSignalThreshold,
double greenSignalThreshold, double greenSignalThreshold,
double blueSignalThreshold, double blueSignalThreshold,
int noSignalCounterThreshold); int noSignalCounterThreshold = 50);
void setSignalDetectionOffset( ///
/// @brief overwrite Grabber.h implementation
///
virtual void setSignalDetectionOffset(
double verticalMin, double verticalMin,
double horizontalMin, double horizontalMin,
double verticalMax, double verticalMax,
double horizontalMax); double horizontalMax);
///
/// @brief overwrite Grabber.h implementation
///
virtual void setSignalDetectionEnable(bool enable);
void setSignalDetectionEnable(bool enable); ///
/// @brief overwrite Grabber.h implementation
///
virtual void setDeviceVideoStandard(QString device, VideoStandard videoStandard);
public slots:
bool start(); bool start();
@ -66,7 +87,7 @@ private slots:
private: private:
void getV4Ldevices(); void getV4Ldevices();
bool init(); bool init();
void uninit(); void uninit();
@ -120,9 +141,9 @@ private:
std::vector<buffer> _buffers; std::vector<buffer> _buffers;
PixelFormat _pixelFormat; PixelFormat _pixelFormat;
int _pixelDecimation;
int _lineLength; int _lineLength;
int _frameByteSize; int _frameByteSize;
int _frameDecimation;
// signal detection // signal detection
int _noSignalCounterThreshold; int _noSignalCounterThreshold;
@ -134,7 +155,6 @@ private:
double _y_frac_min; double _y_frac_min;
double _x_frac_max; double _x_frac_max;
double _y_frac_max; double _y_frac_max;
int _currentFrame;
QSocketNotifier * _streamNotifier; QSocketNotifier * _streamNotifier;

View File

@ -9,17 +9,9 @@ class V4L2Wrapper : public GrabberWrapper
public: public:
V4L2Wrapper(const QString & device, V4L2Wrapper(const QString & device,
int input,
VideoStandard videoStandard, VideoStandard videoStandard,
PixelFormat pixelFormat, PixelFormat pixelFormat,
unsigned width, int pixelDecimation );
unsigned height,
int frameDecimation,
int pixelDecimation,
double redSignalThreshold,
double greenSignalThreshold,
double blueSignalThreshold,
const int priority);
virtual ~V4L2Wrapper() {}; virtual ~V4L2Wrapper() {};
bool getSignalDetectionEnable(); bool getSignalDetectionEnable();
@ -28,19 +20,16 @@ public slots:
bool start(); bool start();
void stop(); void stop();
void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold);
void setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom); void setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom);
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax); void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
void setSignalDetectionEnable(bool enable); void setSignalDetectionEnable(bool enable);
// signals:
// void emitColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms);
private slots: private slots:
void newFrame(const Image<ColorRgb> & image); void newFrame(const Image<ColorRgb> & image);
void readError(const char* err); void readError(const char* err);
virtual void action(); virtual void action();
void checkSources();
private: private:
/// The V4L2 grabber /// The V4L2 grabber

View File

@ -17,12 +17,12 @@ class X11Grabber : public Grabber
{ {
public: public:
X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation); X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation);
virtual ~X11Grabber(); virtual ~X11Grabber();
bool Setup(); bool Setup();
/// ///
/// Captures a single snapshot of the display and writes the data to the given image. The /// Captures a single snapshot of the display and writes the data to the given image. The
/// provided image should have the same dimensions as the configured values (_width and /// provided image should have the same dimensions as the configured values (_width and
@ -32,15 +32,34 @@ public:
/// height) /// height)
/// ///
virtual int grabFrame(Image<ColorRgb> & image, bool forceUpdate=false); virtual int grabFrame(Image<ColorRgb> & image, bool forceUpdate=false);
/// ///
/// update dimension according current screen /// update dimension according current screen
int updateScreenDimensions(bool force=false); int updateScreenDimensions(bool force=false);
virtual void setVideoMode(VideoMode mode); virtual void setVideoMode(VideoMode mode);
///
/// @brief Apply new width/height values, overwrite Grabber.h implementation as X11 doesn't use width/height, just pixelDecimation to calc dimensions
///
virtual bool setWidthHeight(int width, int height) { return true; };
///
/// @brief Apply new pixelDecimation
///
virtual void setPixelDecimation(int pixelDecimation);
///
/// Set the crop values
/// @param cropLeft Left pixel crop
/// @param cropRight Right pixel crop
/// @param cropTop Top pixel crop
/// @param cropBottom Bottom pixel crop
///
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
private: private:
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable; bool _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
XImage* _xImage; XImage* _xImage;
XShmSegmentInfo _shminfo; XShmSegmentInfo _shminfo;
@ -49,17 +68,16 @@ private:
Display* _x11Display; Display* _x11Display;
Window _window; Window _window;
XWindowAttributes _windowAttr; XWindowAttributes _windowAttr;
Pixmap _pixmap; Pixmap _pixmap;
XRenderPictFormat* _srcFormat; XRenderPictFormat* _srcFormat;
XRenderPictFormat* _dstFormat; XRenderPictFormat* _dstFormat;
XRenderPictureAttributes _pictAttr; XRenderPictureAttributes _pictAttr;
Picture _srcPicture; Picture _srcPicture;
Picture _dstPicture; Picture _dstPicture;
XTransform _transform; XTransform _transform;
int _horizontalDecimation; int _pixelDecimation;
int _verticalDecimation;
unsigned _screenWidth; unsigned _screenWidth;
unsigned _screenHeight; unsigned _screenHeight;
@ -67,7 +85,7 @@ private:
unsigned _src_y; unsigned _src_y;
Image<ColorRgb> _image; Image<ColorRgb> _image;
void freeResources(); void freeResources();
void setupResources(); void setupResources();
}; };

View File

@ -24,7 +24,7 @@ public:
/// @param[in] grabHeight The height of the grabbed images [pixels] /// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz] /// @param[in] updateRate_Hz The image grab rate [Hz]
/// ///
X11Wrapper(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation, const unsigned updateRate_Hz, const int priority); X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, const unsigned updateRate_Hz);
/// ///
/// Destructor of this framebuffer frame grabber. Releases any claimed resources. /// Destructor of this framebuffer frame grabber. Releases any claimed resources.
@ -43,4 +43,3 @@ private:
bool _init; bool _init;
}; };

View File

@ -0,0 +1,71 @@
#pragma once
#include <utils/Logger.h>
#include <hyperion/Hyperion.h>
#include <utils/settings.h>
///
/// @brief Handle the background Effect settings, reacts on runtime to settings changes
///
class BGEffectHandler : public QObject
{
Q_OBJECT
public:
BGEffectHandler(Hyperion* hyperion)
: QObject(hyperion)
, _hyperion(hyperion)
{
// listen for config changes
connect(_hyperion, &Hyperion::settingsChanged, this, &BGEffectHandler::handleSettingsUpdate);
// init
handleSettingsUpdate(settings::BGEFFECT, _hyperion->getSetting(settings::BGEFFECT));
};
private slots:
///
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
/// @param type settingyType from enum
/// @param config configuration object
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
{
if(type == settings::BGEFFECT)
{
const QJsonObject& BGEffectConfig = config.object();
#define BGCONFIG_ARRAY bgColorConfig.toArray()
// clear bg prioritiy
_hyperion->clear(254);
// initial background effect/color
if (BGEffectConfig["enable"].toBool(true))
{
const QString bgTypeConfig = BGEffectConfig["type"].toString("effect");
const QString bgEffectConfig = BGEffectConfig["effect"].toString("Warm mood blobs");
const QJsonValue bgColorConfig = BGEffectConfig["color"];
if (bgTypeConfig.contains("color"))
{
ColorRgb bg_color = {
(uint8_t)BGCONFIG_ARRAY.at(0).toInt(0),
(uint8_t)BGCONFIG_ARRAY.at(1).toInt(0),
(uint8_t)BGCONFIG_ARRAY.at(2).toInt(0)
};
_hyperion->setColor(254, bg_color);
Info(Logger::getInstance("HYPERION"),"Inital background color set (%d %d %d)",bg_color.red,bg_color.green,bg_color.blue);
}
else
{
int result = _hyperion->setEffect(bgEffectConfig, 254);
Info(Logger::getInstance("HYPERION"),"Inital background effect '%s' %s", QSTRING_CSTR(bgEffectConfig), ((result == 0) ? "started" : "failed"));
}
}
#undef BGCONFIG_ARRAY
}
};
private:
/// Hyperion instance pointer
Hyperion* _hyperion;
};

View File

@ -0,0 +1,75 @@
#pragma once
#include <utils/Logger.h>
#include <utils/settings.h>
#include <utils/Components.h>
#include <utils/Image.h>
class Hyperion;
class QTimer;
///
/// @brief Capture Control class which is a interface to the HyperionDaemon native capture classes.
/// It controls the instance based enable/disable of capture feeds and PriorityMuxer registrations
///
class CaptureCont : public QObject
{
Q_OBJECT
public:
CaptureCont(Hyperion* hyperion);
~CaptureCont();
void setSystemCaptureEnable(const bool& enable);
void setV4LCaptureEnable(const bool& enable);
private slots:
///
/// @brief Handle component state change of V4L and SystemCapture
/// @param component The component from enum
/// @param enable The new state
///
void componentStateChanged(const hyperion::Components component, bool enable);
///
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
/// @param type settingyType from enum
/// @param config configuration object
///
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
///
/// @brief forward system image
/// @param image The image
///
void handleSystemImage(const Image<ColorRgb>& image);
///
/// @brief forward v4l image
/// @param image The image
///
void handleV4lImage(const Image<ColorRgb> & image);
///
/// @brief Is called from _v4lInactiveTimer to set source after specific time to inactive
///
void setV4lInactive();
///
/// @brief Is called from _systemInactiveTimer to set source after specific time to inactive
///
void setSystemInactive();
private:
/// Hyperion instance
Hyperion* _hyperion;
/// Reflect state of System capture and prio
bool _systemCaptEnabled;
quint8 _systemCaptPrio;
QTimer* _systemInactiveTimer;
/// Reflect state of v4l capture and prio
bool _v4lCaptEnabled;
quint8 _v4lCaptPrio;
QTimer* _v4lInactiveTimer;
};

Some files were not shown because too many files have changed in this diff Show More