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
*.cmake
Makefile
qrc_*.cpp
*.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"]
path = dependencies/external/rpi_ws281x
url = https://github.com/hyperion-project/rpi_ws281x.git
branch = master
[submodule "dependencies/external/flatbuffers"]
path = dependencies/external/flatbuffers
url = https://github.com/google/flatbuffers

View File

@ -5,19 +5,27 @@ cache:
notifications:
email: false
language: cpp
services:
- docker
matrix:
include:
- os: linux
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
osx_image: xcode7.3
osx_image: xcode8.3
env:
- HOMEBREW_CACHE=$HOME/brew-cache
before_install:
- ./.travis/travis_install.sh
script:
- ./.travis/travis_build.sh
- ./test/testrunner.sh
after_success:
- ./.travis/travis_deploy.sh

View File

@ -5,6 +5,7 @@
PLATFORM=x86
BUILD_TYPE=Debug
PACKAGES=""
# Detect number of processor cores
# default is 4 jobs
@ -16,32 +17,48 @@ elif [[ "$TRAVIS_OS_NAME" == 'linux' ]]
then
JOBS=$(nproc)
fi
echo "compile jobs: ${JOBS:=4}"
# compile prepare
mkdir build || exit 1
cd build
# Compile hyperion for tags
# Determine cmake build type; tag builds are Release, else Debug
[ -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
cmake -DPLATFORM=$PLATFORM -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=/usr .. || exit 2
if [[ "$TRAVIS_OS_NAME" == 'linux' ]]
# Build the package on osx
if [[ "$TRAVIS_OS_NAME" == 'osx' || "$TRAVIS_OS_NAME" == 'darwin' ]]
then
# activate dispmanx and osx mocks
cmake -DENABLE_OSX=ON -DENABLE_DISPMANX=ON .. || exit 5
# compile prepare
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
echo "compile jobs: ${JOBS:=4}"
make -j ${JOBS} || exit 3
# Build the package on Linux
# Build the package with docker
if [[ $TRAVIS_OS_NAME == 'linux' ]]
then
make -j ${JOBS} package || exit 4
fi
echo "Compile Hyperion with DOCKER_TAG = ${DOCKER_TAG} and friendly name DOCKER_NAME = ${DOCKER_NAME}"
# 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
# sf_upload <deploylist> <sf_dir>
# sf_upload <FILES> <sf_dir>
sf_upload()
{
echo "Uploading following files: ${1}
to dir /hyperion-project/${2}"
/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)*"
send "yes\r"
expect "*password:*"
@ -13,18 +16,49 @@ sf_upload()
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
cd $TRAVIS_BUILD_DIR/build
if [[ -n $TRAVIS_TAG ]]; then
echo "tag upload"
sf_upload $deploylist release
appendName
appendDate
getFiles
sf_upload $FILES release
elif [[ $TRAVIS_EVENT_TYPE == 'cron' ]]; then
echo "cron upload"
sf_upload $deploylist alpha
appendName
appendDate
getFiles
sf_upload $FILES dev/alpha
else
echo "PR can't be uploaded for security reasons"
sf_upload $deploylist pr
echo "Direct pushed no upload, PRs not possible"
#sf_upload $FILES pr
fi
fi

View File

@ -7,19 +7,19 @@
if [[ $TRAVIS_OS_NAME == 'osx' || $TRAVIS_OS_NAME == 'darwin' ]]
then
echo "Install OSX deps"
time brew update
time brew install qt5 || true
time brew install python3 || true
time brew install libusb || true
time brew install cmake || true
time brew install doxygen || true
brew update
brew install qt5 || true
brew upgrade python3 || true
brew upgrade libusb || true
brew upgrade cmake || true
brew install doxygen || true
# install linux deps for hyperion compile
elif [[ $TRAVIS_OS_NAME == 'linux' ]]
then
echo "Install linux deps"
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 -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
else
echo "Unsupported platform: $TRAVIS_OS_NAME"
exit 5

View File

@ -20,9 +20,10 @@ SET ( DEFAULT_AMLOGIC OFF )
SET ( DEFAULT_DISPMANX OFF )
SET ( DEFAULT_OSX OFF )
SET ( DEFAULT_X11 OFF )
SET ( DEFAULT_QT ON )
SET ( DEFAULT_WS281XPWM OFF )
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 )
IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
@ -47,7 +48,7 @@ endif()
if ( NOT DEFINED PLATFORM )
if ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86" )
SET( PLATFORM "x86")
SET( PLATFORM "x11")
elseif ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64")
SET( PLATFORM "rpi")
FILE( READ /proc/cpuinfo SYSTEM_CPUINFO )
@ -61,7 +62,7 @@ if ( NOT DEFINED PLATFORM )
if ( PLATFORM )
message( STATUS "PLATFORM is not defined, evaluated platform: ${PLATFORM}")
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()
@ -95,9 +96,9 @@ elseif ( "${PLATFORM}" STREQUAL "amlogic" )
SET ( DEFAULT_AMLOGIC ON )
elseif ( "${PLATFORM}" STREQUAL "amlogic64" )
SET ( DEFAULT_AMLOGIC ON )
elseif ( "${PLATFORM}" MATCHES "x86" )
elseif ( "${PLATFORM}" MATCHES "x11" )
SET ( DEFAULT_X11 ON )
if ( "${PLATFORM}" STREQUAL "x86-dev" )
if ( "${PLATFORM}" STREQUAL "x11-dev" )
SET ( DEFAULT_AMLOGIC ON)
SET ( DEFAULT_WS281XPWM ON )
endif()
@ -151,7 +152,8 @@ message(STATUS "ENABLE_USB_HID = ${ENABLE_USB_HID}")
option(ENABLE_X11 "Enable the X11 grabber" ${DEFAULT_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})
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)
message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}")
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf )
SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf )
# check all json files
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)
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)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
@ -246,7 +250,7 @@ if (UNIX AND NOT APPLE)
endif ()
# 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)
message( STATUS "Found Qt Version: ${Qt5Core_VERSION}" )
IF ( "${Qt5Core_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" )
@ -276,6 +280,9 @@ if (ENABLE_TESTS)
add_subdirectory(test)
endif ()
# Add resources directory
add_subdirectory(resources)
# Add the doxygen generation directory
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
@ -6,24 +20,13 @@
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
```
### 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**
```
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
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
# ... or run it from compile directory
bin/hyperiond
# webui is located on localhost:8090
# webui is located on localhost:8090 or 8091
```
### Download
Create 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
Creates hyperion directory and checkout the code from github
```
export HYPERION_DIR="hyperion"
git clone --recursive 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
git clone --recursive --depth 1 https://github.com/hyperion-project/hyperion.ng.git "$HYPERION_DIR"
```
### Preparations
@ -110,7 +105,7 @@ cmake -DCMAKE_BUILD_TYPE=Release ..
*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*):

View File

@ -12,7 +12,7 @@
sudo apt-get update
sudo apt-get upgrade
#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
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
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"
cmake -DENABLE_DISPMANX=OFF --build "$NATIVE_BUILD_DIR" "$HYPERION_DIR"
# 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"
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
#cmakedefine ENABLE_X11
// Define to enable the qt grabber
#cmakedefine ENABLE_QT
// Define to enable the spi-device
#cmakedefine ENABLE_SPIDEV
@ -42,5 +45,3 @@
#define HYPERION_VERSION "${HYPERION_VERSION_MAJOR}.${HYPERION_VERSION_MINOR}.${HYPERION_VERSION_PATCH}"
#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).
## 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
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 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*/
[class*="modal-icon"]{
padding:30px;
@ -993,4 +996,4 @@ input[type="radio"] .styled:checked + label::before {
input[type="checkbox"] .styled:checked + label::after,
input[type="radio"] .styled:checked + label::after {
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_itemtitle": "Json cíl",
"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_js_heading_title": "JSON Server",
"edt_conf_ps_heading_title": "PROTO Server",
@ -753,4 +753,4 @@
"edt_conf_enum_SECAM": "SECAM",
"general_speech_it": "Italština",
"general_speech_cs": "Czech"
}
}

View File

@ -20,6 +20,7 @@
"general_comp_FORWARDER" : "Weiterleitung",
"general_comp_UDPLISTENER" : "UDP Listener",
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
"general_comp_GRABBER" : "Plattform Aufnahme",
"general_comp_V4L" : "USB Aufnahme",
"general_comp_LEDDEVICE" : "LED Hardware",
@ -27,6 +28,7 @@
"general_col_green" : "grün",
"general_col_blue" : "blau",
"general_button_savesettings" : "Einstellungen speichern",
"general_btn_yes" : "Ja",
"general_btn_ok" : "OK",
"general_btn_cancel" : "Abbrechen",
"general_btn_continue" : "Fortfahren",
@ -46,7 +48,7 @@
"dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:",
"dashboard_infobox_label_platform" : "Plattform:",
"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_updatesuccess" : "Du nutzt die aktuellste Version von Hyperion.",
"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_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_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_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_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",
@ -283,6 +285,7 @@
"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_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_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!",
@ -341,11 +344,12 @@
"wiz_cc_morethanone" : "Du hast mehr als 1 Profil, bitte wähle das zu kalibrierende Profil",
"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.",
"edt_dev_auth_key_title" : "Aurora API Schlüssel",
"edt_dev_enum_subtract_minimum" : "Subtrahiere minimum",
"edt_dev_enum_sub_min_warm_adjust" : "Minimale Anpassung: warm",
"edt_dev_enum_white_off" : "Weiß ist aus",
"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_rewriteTime_title" : "Aktualisierungszeit",
"edt_dev_spec_header_title" : "Spezifische Einstellungen",
@ -415,6 +419,7 @@
"edt_conf_enum_PAL" : "PAL",
"edt_conf_enum_NTSC" : "NTSC",
"edt_conf_enum_SECAM" : "SECAM",
"edt_conf_enum_NO_CHANGE" : "Auto",
"edt_conf_enum_logsilent" : "Stille",
"edt_conf_enum_logwarn" : "Warnung",
"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_v4l2_heading_title" : "USB Aufnahme",
"edt_conf_v4l2_device_title" : "Gerät",
"edt_conf_v4l2_device_expl" : "Der Pfad zum USB Aufnahmegerät.",
"edt_conf_v4l2_input_title" : "Eingang",
"edt_conf_v4l2_input_expl" : "Der Eingang des Pfades.",
"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_standard_title" : "Videoformat",
"edt_conf_v4l2_standard_expl" : "Wähle das passende Videoformat deiner Region.",
"edt_conf_v4l2_width_title" : "Breite",
"edt_conf_v4l2_width_expl" : "Die Breite des Bildes. (-1 = Automatische Breitenbestimmung)",
"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_standard_expl" : "Wähle das passende Videoformat deiner Region. Auf 'Auto' wird der gewählte Modus vom v4l interface beibehalten.",
"edt_conf_v4l2_sizeDecimation_title" : "Bildverkleinerung Faktor",
"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_cropLeft_title" : "Entferne links",
"edt_conf_v4l2_cropLeft_expl" : "Anzahl der Pixel auf der linken Seite die vom Bild entfernt werden.",
"edt_conf_v4l2_cropRight_title" : "Entferne rechts",
@ -502,7 +499,7 @@
"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_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_expl" : "Je höher die rote Schwelle je eher wird abgeschalten bei entsprechendem rot-Anteil.",
"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_sDHOffsetMax_title" : "Signal Erkennung HMax",
"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_type_title" : "Typ",
"edt_conf_fg_type_expl" : "Art der Plattform Aufnahme, standard ist 'auto'",
"edt_conf_fg_frequency_Hz_title" : "Aufnahmefrequenz",
"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_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_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_verticalPixelDecimation_expl" : "Vertikale Pixelreduzierung (Faktor)",
"edt_conf_fg_pixelDecimation_title" : "Bildverkleinerung 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_display_title" : "Display",
"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_itemtitle" : "Json Ziel",
"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_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_udpl_heading_title" : "UDP Listener",
"edt_conf_udpl_address_title" : "Adresse",
"edt_conf_udpl_address_expl" : "Die Adresse auf der UDP Pakete akzeptiert werden.",
"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_expl" : "Wird gemeinsam über alle Hyperion Instanzen genutzt.",
"edt_conf_webc_heading_title" : "Web Konfiguration",
@ -593,9 +593,14 @@
"edt_eff_smooth_updateFrequency" : "Glättung: Aktualisierungsfrequenz",
"edt_eff_candle_header" : "Kerze",
"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_desc" : "Lights like a police car in action",
"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_desc" : "Alle LEDs Regenbogen Farbübergang",
"edt_eff_knightrider_header" : "Knight Rider",
@ -603,18 +608,24 @@
"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_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_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_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_runningdots_header" : "Rennende Punkte",
"edt_eff_random_header_desc" : "Pixel-Farb-Mix",
"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_desc" : "Wo ist das Futter?",
"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_traces_header" : "Farbspuren",
"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_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",
@ -679,6 +690,7 @@
"edt_eff_customColor" : "Benutzerdefinierte Farbe",
"edt_eff_randomCenter" : "Zufälliger Mittelpunkt",
"edt_eff_enableSecondSwirl":"Zweiter Wirbel",
"edt_eff_reverseRandomTime":"Richtungswechsel alle",
"edt_append_ns" : "ns",
"edt_append_ms" : "ms",
"edt_append_s" : "s",

View File

@ -20,6 +20,7 @@
"general_comp_FORWARDER" : "Forwarder",
"general_comp_UDPLISTENER" : "UDP Listener",
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
"general_comp_GRABBER" : "Platform Capture",
"general_comp_V4L" : "USB Capture",
"general_comp_LEDDEVICE" : "LED device",
@ -27,6 +28,7 @@
"general_col_green" : "green",
"general_col_blue" : "blue",
"general_button_savesettings" : "Save settings",
"general_btn_yes" : "Yes",
"general_btn_ok" : "OK",
"general_btn_cancel" : "Cancel",
"general_btn_continue" : "Continue",
@ -46,7 +48,7 @@
"dashboard_infobox_label_latesthyp" : "Latest Hyperion version:",
"dashboard_infobox_label_platform" : "Platform:",
"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_updatesuccess" : "You run the latest version of Hyperion.",
"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_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_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_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_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",
@ -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_foottext" : "The WebUI will be unlocked automatically after you solved the problem!",
"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_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!",
@ -341,12 +344,13 @@
"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_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_sub_min_warm_adjust" : "Min warm adjust",
"edt_dev_enum_white_off" : "White off",
"edt_dev_general_heading_title" : "General Settings",
"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_rewriteTime_title" : "Refresh time",
"edt_dev_spec_header_title" : "Specific Settings",
@ -416,6 +420,7 @@
"edt_conf_enum_PAL" : "PAL",
"edt_conf_enum_NTSC" : "NTSC",
"edt_conf_enum_SECAM" : "SECAM",
"edt_conf_enum_NO_CHANGE" : "Auto",
"edt_conf_enum_logsilent" : "Silent",
"edt_conf_enum_logwarn" : "Warning",
"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_v4l2_heading_title" : "USB Capture",
"edt_conf_v4l2_device_title" : "Device",
"edt_conf_v4l2_device_expl" : "The path to the usb capture.",
"edt_conf_v4l2_input_title" : "Input",
"edt_conf_v4l2_input_expl" : "Input of this path.",
"edt_conf_v4l2_device_expl" : "The path to the usb capture interface. Set to 'auto' for auto detection. Example: '/dev/video0'",
"edt_conf_v4l2_standard_title" : "Video standard",
"edt_conf_v4l2_standard_expl" : "Select the video standard for your region.",
"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_standard_expl" : "Select the video standard for your region. 'Auto' keeps the chosen one from v4l interface",
"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_expl" : "Count of pixels on the left side that are removed from the picture.",
"edt_conf_v4l2_cropRight_title" : "Crop right",
@ -503,7 +500,7 @@
"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_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_expl" : "Darkens low red values (recognized as black)",
"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_sDHOffsetMax_title" : "Signal Detection HMax",
"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_type_title" : "Type",
"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_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_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_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_useXGetImage_expl" : "XGetImage for newer X11 desktops",
"edt_conf_fg_verticalPixelDecimation_title" : "Vertical pixel decimation",
"edt_conf_fg_verticalPixelDecimation_expl" : "Vertical pixel decimation (factor)",
"edt_conf_fg_pixelDecimation_title" : "Picture decimation",
"edt_conf_fg_pixelDecimation_expl" : "Reduce picture size (factor) based on original size. A factor of 1 means no change",
"edt_conf_fg_device_title" : "Device",
"edt_conf_fg_display_title" : "Display",
"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_itemtitle" : "Json target",
"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_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_udpl_heading_title" : "UDP Listener",
"edt_conf_udpl_address_title" : "Address",
@ -592,6 +592,10 @@
"edt_eff_smooth_custom" : "Enable smoothing",
"edt_eff_smooth_time_ms" : "Smoothing time",
"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_desc" : "Shimmering candles",
"edt_eff_police_header" : "Police",
@ -605,20 +609,27 @@
"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_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_desc" : "Relax at the evening with slow moving and color changing blobs.",
"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_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_desc" : "A short animation with probably a real system shutdown",
"edt_eff_snake_header" : "Snake",
"edt_eff_snake_header_desc" : "Where is something to eat?",
"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_traces_header" : "Color Traces",
"edt_eff_traces_header_desc" : "Requires redesign",
"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_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-together" : "All together",
"edt_eff_enum_list" : "LED List",
@ -630,6 +641,8 @@
"edt_eff_colorcount" : "Color length",
"edt_eff_rotationtime" : "Rotation time",
"edt_eff_sleeptime" : "Sleep time",
"edt_eff_image" : "Image file",
"edt_eff_fps" : "Frames per seconds",
"edt_eff_reversedirection" : "Reverse direction",
"edt_eff_fadeintime" : "Fade in time",
"edt_eff_fadeouttime" : "Fade out time",
@ -681,6 +694,7 @@
"edt_eff_customColor" : "Custom Color",
"edt_eff_randomCenter" : "Random Center",
"edt_eff_enableSecondSwirl":"Second Swirl",
"edt_eff_reverseRandomTime":"Reverse every",
"edt_append_ns" : "ns",
"edt_append_ms" : "ms",
"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_itemtitle": "Destinatario json",
"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_js_heading_title": "Server JSON",
"edt_conf_ps_heading_title": "Server PROTO",
@ -753,4 +753,4 @@
"edt_conf_enum_SECAM": "SECAM",
"general_speech_it": "Italiano",
"general_speech_cs": "Czech"
}
}

View File

@ -1,10 +1,10 @@
{
"@metadata": {
"authors": [
"brindosch"
"brindosch, paulchen-panther"
],
"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_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_move_down_title" : "Title on Move Down 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_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>
<link href="css/bootstrap-colorpicker.min.css" rel="stylesheet">
<!-- BS Notfiy -->
<script src="js/lib/bootstrap-notify.min.js"></script>
<!-- JSONEditor -->
<script src="js/lib/jsoneditor.js"></script>
@ -176,7 +179,10 @@
<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_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>
</ul>
</li>

View File

@ -1,6 +1,6 @@
$(document).ready( function() {
performTranslation();
function newsCont(t,e,l)
{
var h = '<div style="padding-left:9px;border-left:6px solid #0088cc;">';
@ -10,7 +10,7 @@ $(document).ready( function() {
h += '</div><hr/>';
$('#dash_news').append(h);
}
function createNews(d)
{
for(var i = 0; i<d.length; i++)
@ -21,11 +21,11 @@ $(document).ready( function() {
title = d[i].title.rendered;
excerpt = d[i].excerpt.rendered;
link = d[i].link+'?pk_campaign=WebUI&pk_kwd=news_'+d[i].slug;
newsCont(title,excerpt,link);
}
}
function getNews()
{
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);
});
}
//getNews();
function updateComponents()
{
var components = serverInfo.components;
var components = comps;
components_html = "";
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);
//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>');
$('#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>');
hyperion_enabled = true;
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
$('#dash_leddevice').html(serverInfo.ledDevices.active);
$('#dash_currv').html(currentVersion);
$('#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 ) {
parsedUpdateJSON = JSON.parse(data);
latestVersion = parsedUpdateJSON[0].versionnr;
@ -76,13 +86,13 @@ $(document).ready( function() {
var cleanCurrentVersion = currentVersion.replace(/\./g, '');
// $('#dash_latev').html(latestVersion);
// if ( cleanCurrentVersion < cleanLatestVersion )
// $('#versioninforesult').html('<div class="bs-callout bs-callout-warning" style="margin:0px">'+$.i18n('dashboard_infobox_message_updatewarning', latestVersion)+'</div>');
// else
$('#versioninforesult').html('<div class="bs-callout bs-callout-success" style="margin:0px">'+$.i18n('dashboard_infobox_message_updatesuccess')+'</div>');
});
//determine platform
var grabbers = serverInfo.grabbers.available;
var html = "";
@ -97,16 +107,16 @@ $(document).ready( function() {
html += 'Amlogic';
else
html += 'Framebuffer';
$('#dash_platform').html(html);
$('#dash_platform').html(html);
//interval update
updateComponents();
$(hyperion).on("cmd-serverinfo",updateComponents);
$(hyperion).on("components-updated",updateComponents);
if(showOptHelp)
createHintH("intro", $.i18n('dashboard_label_intro'), "dash_intro");
removeOverlay();
});
});

View File

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

View File

@ -2,6 +2,7 @@ $(document).ready( function() {
performTranslation();
var oldDelList = [];
var effectName = "";
var imageData = "";
var effects_editor = null;
var effectPy = "";
var testrun;
@ -31,9 +32,29 @@ $(document).ready( function() {
function triggerTestEffect() {
testrun = true;
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) {
if(effects_editor != null)
@ -48,6 +69,7 @@ $(document).ready( function() {
effectPy = ':';
effectPy += effects[idx].schemaContent.script;
imageData = "";
$("#name-input").trigger("change");
$("#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) {
effectName = $(this).val();
if ($(this).val() == '') {
@ -81,8 +104,9 @@ $(document).ready( function() {
}
});
// Save Effect
$('#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) {
if (event.response.success)
showInfoDialog('success', "", $.i18n('infoDialog_effconf_created_text', effectName));
@ -93,21 +117,25 @@ $(document).ready( function() {
});
// Start test
$('#btn_start_test').off().on('click',function() {
triggerTestEffect();
});
// Stop test
$('#btn_stop_test').off().on('click',function() {
requestPriorityClear();
testrun = false;
});
// Continuous test
$('#btn_cont_test').off().on('click',function() {
toggleClass('#btn_cont_test', "btn-success", "btn-danger");
});
// Delete Effect
$('#btn_delete').off().on('click',function() {
var name = $("#effectsdellist").val();
var name = $("#effectsdellist").val().split("_")[1];
requestDeleteEffect(name);
$(hyperion).one("cmd-delete-effect", function(event) {
if (event.response.success)
@ -115,11 +143,13 @@ $(document).ready( function() {
});
});
// disable or enable Delete Effect Button
$('#effectsdellist').off().on('change', function(){
$(this).val() == null ? $('#btn_edit, #btn_delete').prop('disabled',true) : "";
$(this).val().startsWith("int_") ? $('#btn_delete').prop('disabled',true) : $('#btn_delete').prop('disabled',false);
});
// Load Effect
$('#btn_edit').off().on('click', function(){
var name = $("#effectsdellist").val().replace("ext_","");
@ -155,15 +185,18 @@ $(document).ready( function() {
//create basic effect list
var effects = serverSchema.properties.effectSchemas.internal
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");
updateDelEffectlist();
//interval update
$(hyperion).on("cmd-serverinfo",updateDelEffectlist);
$(hyperion).on("cmd-effects-update", function(event){
serverInfo.effects = event.response.data.effects
updateDelEffectlist();
});
removeOverlay();
});

View File

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

View File

@ -1,6 +1,4 @@
$(document).ready( function() {
var uiLock = false;
var prevSess = 0;
loadContentTo("#container_connection_lost","connection_lost");
loadContentTo("#container_restart","restart");
@ -8,70 +6,52 @@ $(document).ready( function() {
$(hyperion).on("cmd-serverinfo",function(event){
serverInfo = event.response.info;
// comps
comps = event.response.info.components
$(hyperion).trigger("ready");
if (serverInfo.hyperion.config_modified)
$("#hyperion_reload_notify").fadeIn("fast");
else
$("#hyperion_reload_notify").fadeOut("fast");
if (serverInfo.hyperion.off)
$("#hyperion_disabled_notify").fadeIn("fast");
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++)
comps.forEach( function(obj) {
if (obj.name == "ALL")
{
if(sess[i].type == "_hyperiond-http._tcp.")
{
wSess.push(sess[i]);
}
if(obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
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
$(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();
sysInfo = event.response.info;
currentVersion = sysInfo.hyperion.version;
});
$(hyperion).one("cmd-config-getschema", function(event) {
serverSchema = event.response.result;
serverSchema = event.response.info;
requestServerConfig();
schema = serverSchema.properties;
});
$(hyperion).one("cmd-config-getconfig", function(event) {
serverConfig = event.response.result;
$(hyperion).on("cmd-config-getconfig", function(event) {
serverConfig = event.response.info;
requestSysInfo();
showOptHelp = serverConfig.general.showOptHelp;
});
@ -82,15 +62,44 @@ $(document).ready( function() {
$(hyperion).on("open",function(event){
requestServerConfigSchema();
});
$(hyperion).one("ready", function(event) {
loadContent();
});
$("#btn_hyperion_reload").on("click", function(){
initRestart();
$(hyperion).on("cmd-adjustment-update", function(event) {
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){
loadContent(e);
window.scrollTo(0, 0);
@ -105,4 +114,3 @@ $(function(){
$(this).toggleClass('active inactive');
});
});

View File

@ -473,7 +473,7 @@ $(document).ready(function() {
devRPiSPI = ['apa102', 'apa104', 'ws2801', 'lpd6803', 'lpd8806', 'p9813', 'sk6812spi', 'sk6822spi', 'ws2812spi'];
devRPiPWM = ['ws281x'];
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'];
var optArr = [[]];

View File

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

View File

@ -86,22 +86,6 @@ $(document).ready(function() {
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()
{
$('.sstbody').html("");
@ -123,6 +107,7 @@ $(document).ready(function() {
var priority = prios[i].priority;
var compId = prios[i].componentId;
var duration = prios[i].duration_ms/1000;
var value = "0,0,0";
var btn_type = "default";
var btn_text = $.i18n('remote_input_setsource_btn');
var btn_state = "enabled";
@ -145,13 +130,16 @@ $(document).ready(function() {
if(ip)
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)
{
case "EFFECT":
owner = $.i18n('remote_effects_label_effects')+' '+owner;
break;
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;
case "GRABBER":
owner = $.i18n('general_comp_GRABBER')+': ('+owner+')';
@ -165,6 +153,9 @@ $(document).ready(function() {
case "UDPLISTENER":
owner = $.i18n('general_comp_UDPLISTENER');
break;
case "FLATBUFSERVER":
owner = $.i18n('general_comp_FLATBUFSERVER');
break;
}
if(duration && compId != "GRABBER" && compId != "PROTOSERVER")
@ -195,7 +186,7 @@ $(document).ready(function() {
function updateLedMapping()
{
mapping = serverInfo.ledMAppingType;
mapping = serverInfo.imageToLedMappingType;
$('#mappingsbutton').html("");
for(var ix = 0; ix < mappingList.length; ix++)
@ -211,16 +202,27 @@ $(document).ready(function() {
function updateComponents()
{
components = serverInfo.components;
components = comps;
var hyperionEnabled = true;
components.forEach( function(obj) {
if (obj.name == "ALL")
{
hyperionEnabled = obj.enabled
}
});
// create buttons
$('#componentsbutton').html("");
for ( idx=0; idx<components.length;idx++)
{
if(components[idx].name == "ALL")
continue
enable_style = (components[idx].enabled? "btn-success" : "btn-danger");
enable_icon = (components[idx].enabled? "fa-play" : "fa-stop");
comp_name = components[idx].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
if ($("#"+comp_btn_id).length == 0)
@ -266,7 +268,7 @@ $(document).ready(function() {
function updateVideoMode()
{
videoModes = ["2D","3DSBS","3DTAB"];
currVideoMode = serverInfo.grabbers.videomode;
currVideoMode = serverInfo.videomode;
$('#videomodebtns').html("");
for(var ix = 0; ix < videoModes.length; ix++)
@ -327,10 +329,34 @@ $(document).ready(function() {
});
//force first update
updateRemote();
updateComponents();
updateInputSelect();
updateLedMapping();
updateVideoMode();
updateEffectlist();
// 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();
});

View File

@ -22,6 +22,11 @@ var loggingHandlerInstalled = false;
var watchdog = 0;
var debugMessagesActive = true;
var wSess = [];
var plugins_installed = {};
var plugins_available = {};
//comps serverinfo
comps = [];
function initRestart()
{
@ -59,6 +64,7 @@ function connectionLostDetection(type)
setInterval(connectionLostDetection, 3000);
// init websocket to hyperion and bind socket events to jquery events of $(hyperion) object
function initWebSocket()
{
if ("WebSocket" in window)
@ -66,8 +72,8 @@ function initWebSocket()
if (websocket == null)
{
jsonPort = (document.location.port == '') ? '80' : document.location.port;
websocket = new WebSocket('ws://'+document.location.hostname+":"+document.location.port);
console.log(jsonPort)
websocket = new WebSocket('ws://'+document.location.hostname+":"+jsonPort);
websocket.onopen = function (event) {
$(hyperion).trigger({type:"open"});
@ -108,7 +114,7 @@ function initWebSocket()
response = JSON.parse(event.data);
success = response.success;
cmd = response.command;
if (success)
if (success || typeof(success) == "undefined")
{
$(hyperion).trigger({type:"cmd-"+cmd, response:response});
}
@ -161,7 +167,7 @@ function sendToHyperion(command, subcommand, msg)
// also used for watchdog
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()
@ -218,7 +224,7 @@ function requestPriorityClear(prio)
function requestClearAll()
{
sendToHyperion("clearall");
requestPriorityClear(-1)
}
function requestPlayEffect(effectName, duration)
@ -264,15 +270,15 @@ function requestWriteConfig(config, full)
sendToHyperion("config","setconfig", '"config":'+JSON.stringify(serverConfig));
}
function requestWriteEffect(effectName,effectPy,effectArgs)
function requestWriteEffect(effectName,effectPy,effectArgs,data)
{
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)

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;
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];
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');
this.preview.appendChild(uploadButton);
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() {
if(this.uploader) this.uploader.disabled = false;
@ -6825,10 +6814,7 @@ JSONEditor.defaults.themes.bootstrap3 = JSONEditor.AbstractTheme.extend({
},
getButton: function(text, icon, title) {
var el = this._super(text, icon, title);
if(icon.className.includes("fa-times"))
el.className += 'btn btn-sm btn-danger';
else
el.className += 'btn btn-sm btn-primary';
el.className += 'btn btn-default';
return el;
},
getTable: function() {

View File

@ -7,7 +7,7 @@ function removeOverlay()
function reload()
{
location.reload();
location.reload();
}
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)
{
if(typeof d === "undefined" || d < 0)
@ -70,12 +91,12 @@ function getHashtag()
}
}
function loadContent(event)
function loadContent(event, forceRefresh)
{
var tag;
if(typeof event != "undefined")
{
{
tag = event.currentTarget.hash;
tag = tag.substr(tag.indexOf("#") + 1);
setStorage('lasthashtag', tag, true);
@ -83,7 +104,7 @@ function loadContent(event)
else
tag = getHashtag();
if(prevTag != tag)
if(forceRefresh || prevTag != tag)
{
prevTag = tag;
$("#page-content").off();
@ -130,7 +151,7 @@ function setClassByBool(obj,enable,class1,class2)
}
function showInfoDialog(type,header,message)
{
{
if (type=="success"){
$('#id_body').html('<i style="margin-bottom:20px" class="fa fa-check modal-icon-check">');
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_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">');
if(header == "")
$('#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>');
}
}
else if (type == "select"){
$('#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>');
@ -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(message);
if(type == "select" || type == "iswitch")
$('#id_body').append('<select id="id_select" class="form-control" style="margin-top:10px;width:auto;"></select>');
$("#modal_dialog").modal({
backdrop : "static",
keyboard: false,
@ -193,14 +214,14 @@ function createHintH(type, text, container)
{
if(type = "intro")
tclass = "introd";
$('#'+container).prepend('<div class="'+tclass+'"><h4 style="font-size:16px">'+text+'</h4><hr/></div>');
}
function createHint(type, text, container, buttonid, buttontxt)
{
var fe, tclass;
if(type == "intro")
{
fe = '';
@ -212,21 +233,21 @@ function createHint(type, text, container, buttonid, buttontxt)
tclass = "info-hint";
}
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>';
tclass = "wizard-hint";
}
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>';
tclass = "warning-hint";
}
if(buttonid)
buttonid = '<p><button id="'+buttonid+'" class="btn btn-wizard" style="margin-top:15px;">'+text+'</button></p>';
else
buttonid = "";
if(type == "intro")
$('#'+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")
@ -247,8 +268,8 @@ function valValue(id,value,min,max)
{
if(typeof max === 'undefined' || max == "")
max = 999999;
if(Number(value) > Number(max))
if(Number(value) > Number(max))
{
$('#'+id).val(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));
return min;
}
return value;
return value;
}
function readImg(input,cb)
@ -294,12 +315,10 @@ function createJsonEditor(container,schema,setconfig,usePanel,arrayre)
{
$('#'+container).off();
$('#'+container).html("");
//JSONEditor.plugins.selectize.enable = true;
if (typeof arrayre === 'undefined')
arrayre = true;
var editor = new JSONEditor(document.getElementById(container),
{
theme: 'bootstrap3',
@ -338,18 +357,18 @@ function createJsonEditor(container,schema,setconfig,usePanel,arrayre)
}
function buildWL(link,linkt,cl)
{
{
var baseLink = "https://docs.hyperion-project.org/";
var lang;
if(typeof linkt == "undefined")
linkt = "Placeholder";
if(storedLang == "de" || navigator.locale == "de")
lang = "de";
else
lang = "en";
if(cl === true)
{
linkt = $.i18n(linkt);
@ -366,7 +385,7 @@ function rgbToHex(rgb)
return "#" +
("0" + parseInt(rgb[0],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
debugMessage('rgbToHex: Given rgb is no array or has wrong length');
@ -381,6 +400,57 @@ function hexToRgb(hex) {
} : 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)
{
@ -388,7 +458,7 @@ function createCP(id, color, cb)
color = rgbToHex(color);
else if(color == "undefined")
color = "#AA3399";
if(color.startsWith("#"))
{
$('#'+id).colorpicker({
@ -425,7 +495,7 @@ function createTable(hid, bid, cont, bless, tclass)
var table = document.createElement('table');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
table.className = "table";
if(bless === true)
table.className += " borderless";
@ -438,30 +508,30 @@ function createTable(hid, bid, cont, bless, tclass)
if(hid != "")
table.appendChild(thead);
table.appendChild(tbody);
$('#'+cont).append(table);
}
// Creates a table row <tr>
// @param array list :innerHTML content for <td>/<th>
// @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)
function createTableRow(list, head, align)
{
var row = document.createElement('tr');
for(var i = 0; i < list.length; i++)
{
if(head === true)
var el = document.createElement('th');
else
var el = document.createElement('td');
if(align)
el.style.verticalAlign = "middle";
el.innerHTML = list[i];
row.appendChild(el);
}
@ -483,7 +553,7 @@ function createOptPanel(phicon, phead, bodyid, footerid)
pfooter.className = "btn btn-primary";
pfooter.setAttribute("id", footerid);
pfooter.innerHTML = '<i class="fa fa-fw fa-save"></i>'+$.i18n('general_button_savesettings');
return createPanel(phead, "", pfooter, "panel-default", bodyid);
}
@ -506,30 +576,35 @@ function createHelpTable(list, phead){
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
list = sortProperties(list);
phead = '<i class="fa fa-fw fa-info-circle"></i>'+phead+' '+$.i18n("conf_helptable_expl");
table.className = 'table table-hover borderless';
thead.appendChild(createTableRow([$.i18n('conf_helptable_option'), $.i18n('conf_helptable_expl')], true, false));
for (key in list)
{
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');
tbody.appendChild(createTableRow([$.i18n(list[key].title), $.i18n(text)], false, false));
if(list[key].items && list[key].items.properties)
{
var ilist = sortProperties(list[key].items.properties);
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');
tbody.appendChild(createTableRow([$.i18n(ilist[ikey].title), $.i18n(itext)], false, false));
}
}
}
}
}
table.appendChild(thead);
@ -544,42 +619,42 @@ function createPanel(head, body, footer, type, bodyid){
var phead = document.createElement('div');
var pbody = document.createElement('div');
var pfooter = document.createElement('div');
cont.className = "col-lg-6";
if(typeof type == 'undefined')
type = 'panel-default';
p.className = 'panel '+type;
phead.className = 'panel-heading';
pbody.className = 'panel-body';
pfooter.className = 'panel-footer';
phead.innerHTML = head;
if(typeof bodyid != 'undefined')
{
pfooter.style.textAlign = 'right';
pbody.setAttribute("id", bodyid)
}
if(typeof body != 'undefined' && body != "")
pbody.appendChild(body);
if(typeof footer != 'undefined')
pfooter.appendChild(footer);
p.appendChild(phead);
p.appendChild(pbody);
if(typeof footer != 'undefined')
{
pfooter.style.textAlign = "right";
p.appendChild(pfooter);
}
cont.appendChild(p);
return cont;
}
@ -589,12 +664,12 @@ function createSelGroup(group)
el.setAttribute('label', group);
return el;
}
function createSelOpt(opt, title)
{
var el = document.createElement('option');
el.setAttribute('value', opt);
if (typeof title == 'undefined')
if (typeof title == 'undefined')
el.innerHTML = opt;
else
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('<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_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
$("#wizard_modal").modal({
@ -155,7 +155,6 @@
resetWizard();
serverConfig.device.colorOrder = new_rgb_order;
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_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_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
$("#wizard_modal").modal({
@ -500,7 +499,6 @@
$('#btn_wiz_save').off().on('click',function() {
requestWriteConfig(wiz_editor.getValue());
resetWizard();
setTimeout(initRestart, 200);
});
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>');
createTable("lidsh", "lidsb", "hue_ids_t");
$('.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>');
//open modal
@ -751,7 +749,7 @@
serverConfig.smoothing.enable = false;
requestWriteConfig(serverConfig, true);
setTimeout(initRestart,200);
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]
Description=Hyperion ambient light systemd service
Description=Hyperion ambient light systemd service for user %i
After=network.target
[Service]
ExecStart=/usr/bin/hyperiond
WorkingDirectory=/usr/share/hyperion/bin
User=%i
TimeoutStopSec=5
KillMode=mixed
Restart=always
Restart=on-failure
RestartSec=2
[Install]

View File

@ -9,7 +9,7 @@ Environment=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
ExecStart=./hyperiond /storage/.config/hyperion/hyperion.config.json
TimeoutStopSec=5
KillMode=mixed
Restart=always
Restart=on-failure
RestartSec=2
[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 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 "${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}" )

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"
if [ ! -e "$dest" ]
then
cp "$src" "${dest}"
return 1
else
@ -15,10 +16,7 @@ install_file()
}
echo "--- hyperion ambient light postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
mkdir -p /usr/share/hyperion/custom-effects
echo "---Hyperion ambient light postinstall ---"
#check system
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
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab)
#get current system ip + add default port
address=$(ip -o -4 a | awk '$2 == "eth0" { gsub(/\/.*/, "", $4); print $4 }')":8099"
#get current system ip
NET_IP=`hostname -I | cut -d " " -f1`
#check if hyperion is running
HYPERION_RUNNING=false
pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true
# 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=""
SERVICE_POSTFIX=""
if grep -m1 systemd /proc/1/comm > /dev/null
then
echo "--> init deamon: systemd"
echo "---> init deamon: systemd"
# systemd
$HYPERION_RUNNING && systemctl stop hyperiond 2> /dev/null
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond.service && systemctl -q enable hyperiond.service
start_msg="--> systemctl start hyperiond"
systemctl start hyperiond
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/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?!
if [ $ENABLE_SERVICE -eq 1 ]; then
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 ]
then
echo "--> init deamon: upstart"
echo "---> init deamon: upstart"
# upstart
$HYPERION_RUNNING && initctl stop hyperiond
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
start_msg="--> initctl start hyperiond"
initctl start hyperiond
if [ $ENABLE_SERVICE -eq 1 ]; then
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
start_msg="--> initctl start hyperiond"
initctl start hyperiond
fi
else
echo "--> init deamon: sysV"
echo "---> init deamon: sysV"
# sysV
$HYPERION_RUNNING && service hyperiond stop 2>/dev/null
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"
service hyperiond start
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
start_msg="---> service hyperiond start"
service hyperiond start
fi
fi
#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-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
@ -100,9 +119,14 @@ if [ $CPU_RPI -eq 1 ]; then
fi
fi
echo ${start_msg}
echo "-----------------------------------------------------------------------------"
echo "--> Hyperion has been installed/updated!"
echo "--> For configuration, visit with your browser: ${address}"
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"
@ -110,28 +134,14 @@ echo "Wiki: wiki.hyperion-project.org"
echo "Forum: forum.hyperion-project.org"
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/ ]
then
echo
echo "---------------------------------------------------------------------------------"
echo "- It seemd that you have an older version of hyperion installed in /opt/hyerion -"
echo "- please remove it and check your config to avoid problems -"
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

View File

@ -1,51 +1,61 @@
#!/bin/sh
# check which init script we should use
USE_SYSTEMD=`grep -m1 -c systemd /proc/1/comm`
USE_INITCTL=`which /sbin/initctl | wc -l`
USE_SERVICE=`which /usr/sbin/service | wc -l`
echo "---Hyperion ambient light preinst ---"
#check for hyperion install
if [ -d /usr/share/hyperion/bin ];then
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
# search for users in system, returns first entry
FOUND_USR=`who | grep -o '^\w*\b'` || "root"
#Disabling and delete service files
if [ $USE_SYSTEMD -eq 1 ]; then
# Delete and disable Hyperion systemd script
echo '---> Delete and disable Hyperion systemd service'
systemctl disable hyperion.service
rm -v /etc/systemd/system/hyperion* 2>/dev/null
elif [ $USE_INITCTL -eq 1 ]; then
echo '---> Delete and disable Hyperion initctl script'
rm -v /etc/init/hyperion* 2>/dev/null
initctl reload-configuration
elif [ $USE_SERVICE -eq 1 ]; then
# Delete and disable Hyperion init.d script
echo '---> Delete and disable Hyperion init.d script'
update-rc.d -f hyperion remove
rm /etc/init.d/hyperion* 2>/dev/null
fi
echo "--> Hyperion 1.0 installation has been moved"
fi
# 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
# 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
# default packages to build
IF (APPLE)
SET ( CPACK_GENERATOR "TGZ" "Bundle") # "RPM"
ELSE()
SET ( CPACK_GENERATOR "DEB" "TGZ" "STGZ") # "RPM"
SET ( CPACK_GENERATOR "TGZ" "Bundle")
ELSEIF (UNIX)
SET ( CPACK_GENERATOR "TGZ" "STGZ")
ELSEIF (WIN32)
SET ( CPACK_GENERATOR "ZIP")
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_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_CREATE_DESKTOP_LINKS "hyperiond;Hyperion" )
SET ( CPACK_DEBIAN_PACKAGE_MAINTAINER "Hyperion Team")
SET ( CPACK_DEBIAN_PACKAGE_NAME "Hyperion" )
SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst" )
SET ( CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.hyperion-project.org" )
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" )
# Specific CPack Package Generators
# https://cmake.org/Wiki/CMake:CPackPackageGenerators
# .deb files for apt
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_RPM_PACKAGE_NAME "Hyperion" )
SET ( CPACK_RPM_PACKAGE_URL "https://github.com/hyperion-project/hyperion.ng" )
# .rpm for rpm
# 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_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/prerm" )
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion")
SET ( CPACK_PACKAGE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Hyperion.icns )
# OSX "Bundle" generator TODO Add more osx generators
# https://cmake.org/cmake/help/v3.10/module/CPackBundle.html
SET ( CPACK_BUNDLE_NAME "Hyperion" )
SET ( CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Hyperion.icns )
SET ( CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/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_ICON ${CMAKE_CURRENT_SOURCE_DIR}/cmake/osxbundle/Hyperion.icns )
SET ( CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/cmake/osxbundle/Info.plist )
SET ( CPACK_BUNDLE_STARTUP_COMMAND "${CMAKE_SOURCE_DIR}/cmake/osxbundle/launch.sh" )
SET(CPACK_PACKAGE_VERSION_MAJOR "${HYPERION_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${HYPERION_VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${HYPERION_VERSION_PATCH}")
# NSIS for windows, requires NSIS TODO finish
SET ( CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nsis/installer.ico")
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_ARCHIVE_COMPONENT_INSTALL ON )
SET ( CPACK_DEB_COMPONENT_INSTALL ON )

View File

@ -5,53 +5,143 @@ install_file()
src="$1"
dest="$2"
if [ -e "$dest" ] && ! cmp --quiet "$src" "$dest"
if [ ! -e "$dest" ]
then
cp "$src" "${dest}.new"
else
cp "$src" "${dest}"
return 1
else
echo "--> Service file already exists, skip creation"
return 0
fi
}
echo "--- hyperion ambilight postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
install_file /usr/share/hyperion/config/hyperion.config.json /etc/hyperion/hyperion.config.json
echo "---Hyperion ambient light postinstall ---"
#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
then
echo "---> init deamon: systemd"
# systemd
echo
systemctl stop hyperion 2> /dev/null
install_file /usr/share/hyperion/service/hyperion.systemd.sh /etc/systemd/system/hyperion.service
systemctl -q enable hyperion.service
# if [ $OS_OSMC -eq 1 ]; then
# echo '---> Modify systemd script for OSMC usage'
# # Wait until kodi is sarted (for kodi checker)
# 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
install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/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?!
if [ $ENABLE_SERVICE -eq 1 ]; then
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 ]
then
echo "---> init deamon: upstart"
# upstart
install_file /usr/share/hyperion/service/hyperion.initctl.sh /etc/init/hyperion.conf
initctl reload-configuration
initctl start hyperion
if [ $ENABLE_SERVICE -eq 1 ]; then
install_file /usr/share/hyperion/service/hyperiond.initctl /etc/init/hyperion.conf && initctl reload-configuration
start_msg="--> initctl start hyperiond"
initctl start hyperiond
fi
else
echo "---> init deamon: sysV"
# sysV
service hyperion stop 2>/dev/null
install_file /usr/share/hyperion/service/hyperion.init.sh /etc/init.d/hyperion
chmod +x /etc/init.d/hyperion
update-rc.d hyperion defaults 98 02
service hyperion start
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
start_msg="---> service hyperiond start"
service hyperiond start
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:
/// * '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
/// 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)
/// * 'type' : The type of the device
/// * [device type specific configuration]
/// * '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
"device" :
{
"type" : "file",
"hardwareLedCount" : 1,
"output" : "/dev/null",
"rate" : 1000000,
"colorOrder" : "rgb",
@ -43,7 +43,7 @@
/// * '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
/// (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
/// * '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",
"leds" : "*",
"black" : [0,0,0],
"white" : [255,255,255],
"red" : [255,0,0],
"green" : [0,255,0],
@ -99,15 +98,9 @@
},
/// Configuration for the embedded V4L2 grabber
/// * enable : Enable or disable the v4lgrabber (true/false)
/// * device : V4L2 Device to use [default="/dev/video0"]
/// * 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]
/// * device : V4L2 Device to use [default="auto"] (Auto detection)
/// * standard : Video standard (PAL/NTSC/SECAM/NO_CHANGE) [default="NO_CHANGE"]
/// * sizeDecimation : Size decimation factor [default=8]
/// * priority : Hyperion priority channel [default=900]
/// * cropLeft : Cropping from the left [default=0]
/// * cropRight : Cropping from the right [default=0]
/// * cropTop : Cropping from the top [default=0]
@ -123,13 +116,8 @@
"grabberV4L2" :
[
{
"enable" : false,
"device" : "auto",
"input" : 0,
"standard" : "PAL",
"width" : 0,
"height" : 0,
"frameDecimation" : 2,
"standard" : "NO_CHANGE",
"sizeDecimation" : 8,
"priority" : 240,
"cropLeft" : 0,
@ -148,20 +136,16 @@
],
/// 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) [auto]
/// * type : type of grabber. (auto|osx|dispmanx|amlogic|x11|framebuffer|qt) [auto]
/// * width : The width of the grabbed frames [pixels]
/// * height : The height of the grabbed frames [pixels]
/// * 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!
"framegrabber" :
{
// for all type of grabbers
"enable" : true,
"type" : "framebuffer",
"frequency_Hz" : 10,
"priority" : 250,
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
@ -171,10 +155,11 @@
"width" : 96,
"height" : 96,
// valid for x11
"useXGetImage" : false,
"horizontalPixelDecimation" : 8,
"verticalPixelDecimation" : 8,
// valid for x11|qt
"pixelDecimation" : 8,
// valid for qt
"display" 0,
// valid for framebuffer
"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
/// 'proto' is mostly used for video streams and 'json' for effects
/// * 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"]
/// 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" :
{
"enable" : false,
"proto" : ["127.0.0.1:19447"],
"proto" : ["127.0.0.1:19401"],
"json" : ["127.0.0.1:19446"]
},
@ -249,11 +234,13 @@
"port" : 19444
},
/// The configuration of the Proto server which enables the protobuffer remote interface
/// * port : Port at which the protobuffer server is started
"protoServer" :
/// The configuration of the Flatbuffer server which enables the Flatbuffer remote interface
/// * port : Port at which the flatbuffer server is started
"flatbufServer" :
{
"port" : 19445
"enable" : true,
"port" : 19400,
"timeout" : 5
},
/// The configuration of the boblight server which enables the boblight remote interface
@ -285,12 +272,10 @@
},
/// Configuration of the Hyperion webserver
/// * enable : enable or disable the webserver (true/false)
/// * document_root : path to hyperion webapp files (webconfig developer only)
/// * port : the port where hyperion webapp is accasible
"webConfig" :
{
"enable" : true,
"document_root" : "/path/to/files",
"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.
"ledConfig" :
{

View File

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

View File

@ -9,106 +9,44 @@ if(ENABLE_WS281XPWM)
external/rpi_ws281x/rpihw.c)
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)
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
if (USE_SYSTEM_FLATBUFFERS_LIBS)
find_package(flatbuffers REQUIRED)
include_directories(${FLATBUFFERS_INCLUDE_DIRS})
else ()
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library")
add_subdirectory(external/protobuf)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared flatbuffers library")
set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "Build Flatbuffers with tests")
add_subdirectory(external/flatbuffers)
if(CMAKE_CROSSCOMPILING)
# when crosscompiling import the protoc 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")
include(${IMPORT_PROTOC})
# when crosscompiling import the flatc executable targets from a file generated by a native build
option(IMPORT_FLATC "flatc export file (flatc_export.cmake) from a native build" "IMPORT_FLATC-FILE_NOT_FOUND")
include(${IMPORT_FLATC})
else()
# export the protoc compiler so it can be used when cross compiling
export(TARGETS protoc_compiler FILE "${CMAKE_BINARY_DIR}/protoc_export.cmake")
# export the flatc compiler so it can be used when cross compiling
export(TARGETS flatc FILE "${CMAKE_BINARY_DIR}/flatc_export.cmake")
endif()
# define the include for the protobuf library at the parent scope
set(PROTOBUF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/protobuf/src")
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
# define the include for the flatbuffers library at the parent scope
set(FLATBUFFERS_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/flatbuffers/include")
set(FLATBUFFERS_INCLUDE_DIRS ${FLATBUFFERS_INCLUDE_DIRS} PARENT_SCOPE)
# define the protoc executable at the parent scope
get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION)
set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE)
# define the flatc executable at the parent scope
get_property(FLATBUFFERS_FLATC_EXECUTABLE TARGET flatc PROPERTY LOCATION)
set(FLATBUFFERS_FLATC_EXECUTABLE ${FLATBUFFERS_FLATC_EXECUTABLE} PARENT_SCOPE)
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)
# Create an include path for each file specified
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
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)
function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR)
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
add_custom_command(
OUTPUT ${GEN_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
--gen-object-api
-o "${OUTPUT_DIR}"
"${SRC_FBS}"
DEPENDS flatc)
endfunction()

View File

@ -7,7 +7,7 @@
*/
#ifndef _WIN32
#define _BSD_SOURCE // for usleep from unistd.h
#define _DEFAULT_SOURCE // for usleep from unistd.h
#endif
#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)
# This processes our hyperion-cmake.doxyfile and subsitutes variables to generate a final hyperion.doxyfile
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hyperion.in.doxygen ${CMAKE_CURRENT_BINARY_DIR}/hyperion.doxygen)
if (BUILD_HYPERION_DOC)
if (DOXYGEN_FOUND)
# This processes the shell script that is used to build the documentation and check the result
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hyperion-build-doc.in.sh ${CMAKE_CURRENT_BINARY_DIR}/hyperion-build-doc.sh)
# set input and output files
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
set(StaticDocumentationFiles hyperion-header.html hyperion-footer.html hyperion-stylesheet.css)
# request to configure the file
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
message(STATUS "Doxygen build started")
# Loop over all static documentation files
foreach(StaticDocumentationFile ${StaticDocumentationFiles})
# Copy the file to the bindary documentation directory
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${StaticDocumentationFile} ${CMAKE_CURRENT_BINARY_DIR}/html/${StaticDocumentationFile} COPYONLY)
endforeach()
# Define all static (i.e. not generated) documentation files
set(StaticDocumentationFiles hyperion-footer.html)
if(DOXYGEN_FOUND)
option(BuildDocumentationSearchEngine "Enable doxygen's search engine (requires that documentation to be installed on a php enabled web server)" OFF)
if(BuildDocumentationSearchEngine)
set(DOXYGEN_SEARCHENGINE YES)
else(BuildDocumentationSearchEngine)
set(DOXYGEN_SEARCHENGINE NO)
endif(BuildDocumentationSearchEngine)
# Loop over all static documentation files
foreach(StaticDocumentationFile ${StaticDocumentationFiles})
# Copy the file to the bindary documentation directory
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${StaticDocumentationFile} ${CMAKE_CURRENT_BINARY_DIR}/html/${StaticDocumentationFile} COPYONLY)
endforeach()
#Create a custom target to build documentation. It runs doxygen aginast the generated hyperion.doxyfile and checks its return value
add_custom_target(doc sh ${CMAKE_CURRENT_BINARY_DIR}/hyperion-build-doc.sh)
else(DOXYGEN_FOUND)
message(WARNING "Doxygen not found, unable to generate documenation!")
endif(DOXYGEN_FOUND)
add_custom_target( doc_doxygen ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
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
# 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-
# 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.
# 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
# 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.
# 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
# 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
# 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
@ -754,10 +754,10 @@ WARN_LOGFILE = ${CMAKE_CURRENT_BINARY_DIR}/hyperion-doxygen.log
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = "${CMAKE_SOURCE_DIR}/include" \
"${CMAKE_SOURCE_DIR}/libsrc" \
"${CMAKE_SOURCE_DIR}/src" \
"${CMAKE_SOURCE_DIR}/test"
INPUT = @CMAKE_SOURCE_DIR@/include \
@CMAKE_SOURCE_DIR@/libsrc \
@CMAKE_SOURCE_DIR@/src \
@CMAKE_SOURCE_DIR@/test
# 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
@ -1050,7 +1050,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# 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
# 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.
# 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
# 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.
# 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
# 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.
# 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
# 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))
sleepTime = 1./framesPerSecond
imageList = []
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
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",
"title":"edt_eff_gif_header",
"required":true,
"properties":{
"properties": {
"image": {
"type": "string",
"title":"edt_eff_image",
"format" : "file",
"format" : "url",
"options" :
{
"upload" : true,
"auto_upload" : true
},
"default": "",
"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>
// qt includess
#include <QTimer>
#include <QJsonObject>
#include <QMutex>
#include <QString>
// createEffect helper
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;
}
};
class JsonCB;
// deleteEffect helper
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
class JsonAPI : public QObject
{
Q_OBJECT
@ -49,7 +26,7 @@ public:
/// @param parent Parent QObject
/// @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
@ -58,26 +35,20 @@ public:
///
void handleMessage(const QString & message);
///
/// send a forced serverinfo to a client
///
void forceServerInfo();
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)
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)
void incommingLogMessage(Logger::T_LOG_MESSAGE);
signals:
///
/// Signal which is emitted when a sendSuccessReply() has been executed
///
void pushReq();
///
/// Signal emits with the reply message provided with handleMessage()
///
@ -89,6 +60,9 @@ signals:
void forwardJsonMessage(QJsonObject);
private:
// true if further callbacks are forbidden (http)
bool _noListener;
/// The peer address of the client
QString _peerAddress;
@ -98,17 +72,8 @@ private:
/// Hyperion instance
Hyperion* _hyperion;
/// The processor for translating images to led-values
ImageProcessor * _imageProcessor;
/// 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;
// The JsonCB instance which handles data subscription/notifications
JsonCB* _jsonCB;
// streaming buffers
QJsonObject _streaming_leds_reply;
@ -121,9 +86,15 @@ private:
/// mutex to determine state of image streaming
QMutex _image_stream_mutex;
/// mutex to determine state of image streaming
QMutex _led_stream_mutex;
/// timeout for live video refresh
volatile qint64 _image_stream_timeout;
/// timeout for led color refresh
volatile qint64 _led_stream_timeout;
///
/// Handle an incoming JSON Color message
///
@ -143,7 +114,7 @@ private:
///
/// @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)
@ -180,13 +151,6 @@ private:
///
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
///
@ -213,12 +177,6 @@ private:
///
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()
///
/// @param message the incoming message
@ -256,6 +214,13 @@ private:
///
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
///
@ -266,6 +231,11 @@ private:
///
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
///

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

View File

@ -4,30 +4,28 @@
// QT includes
#include <QJsonObject>
// util
#include <utils/Logger.h>
#include <utils/settings.h>
#include <utils/Components.h>
// Local Hyperion includes
#include "BlackBorderDetector.h"
class Hyperion;
namespace hyperion
{
///
/// 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.
///
class BlackBorderProcessor
class BlackBorderProcessor : public QObject
{
Q_OBJECT
public:
///
/// Constructor for the 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);
BlackBorderProcessor(Hyperion* hyperion, QObject* parent);
~BlackBorderProcessor();
///
/// Return the current (detected) border
/// @return The current border
@ -46,6 +44,13 @@ namespace hyperion
///
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
/// updates the current border accordingly. If the current border is updated the method call
@ -70,11 +75,11 @@ namespace hyperion
}
if (_detectionMode == "default") {
imageBorder = _detector.process(image);
imageBorder = _detector->process(image);
} else if (_detectionMode == "classic") {
imageBorder = _detector.process_classic(image);
imageBorder = _detector->process_classic(image);
} else if (_detectionMode == "osd") {
imageBorder = _detector.process_osd(image);
imageBorder = _detector->process_osd(image);
}
// add blur to the border
if (imageBorder.horizontalSize > 0)
@ -89,8 +94,23 @@ namespace hyperion
const bool borderUpdated = updateBorder(imageBorder);
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:
/// Hyperion instance
Hyperion* _hyperion;
///
/// Updates the current border based on the newly detected border. Returns true if the
/// current border has changed.
@ -102,24 +122,24 @@ namespace hyperion
/// flag for blackborder detector usage
bool _enabled;
/// 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
const unsigned _borderSwitchCnt;
unsigned _borderSwitchCnt;
// 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
unsigned _blurRemoveCnt;
/// The border detection mode
const QString _detectionMode;
QString _detectionMode;
/// The blackborder detector
BlackBorderDetector _detector;
BlackBorderDetector* _detector;
/// The current detected border
BlackBorder _currentBorder;
@ -131,5 +151,12 @@ namespace hyperion
unsigned _consistentCnt;
/// The number of frame the previous detected border NOT matched the incomming border
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

View File

@ -4,15 +4,19 @@
#include <cstdint>
// Qt includes
#include <QTcpServer>
#include <QSet>
#include <QJsonDocument>
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <utils/Logger.h>
#include <utils/Components.h>
// settings
#include <utils/settings.h>
class BoblightClientConnection;
class Hyperion;
class QTcpServer;
///
/// This class creates a TCP server which accepts connections from boblight clients.
@ -27,25 +31,24 @@ public:
/// @param hyperion Hyperion instance
/// @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();
///
/// @return the port number on which this TCP listens for incoming connections
///
uint16_t getPort() const;
/// @return true if server is active (bind to a port)
///
bool active() { return _isActive; };
bool componentState() { return active(); };
bool active();
public slots:
///
/// bind server to network
///
void start();
///
/// close server
///
@ -53,8 +56,12 @@ public slots:
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:
///
@ -73,19 +80,17 @@ private:
Hyperion * _hyperion;
/// The TCP server object
QTcpServer _server;
QTcpServer * _server;
/// List with open connections
QSet<BoblightClientConnection *> _openConnections;
/// hyperion priority
const int _priority;
int _priority;
/// Logger instance
Logger * _log;
/// state of connection
bool _isActive;
// current 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();
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; }
const quint16 & getPort() { return _port; };
signals:
void error(DNSServiceErrorType error);
void serviceRegistered(const BonjourRecord &record);
@ -61,6 +64,9 @@ private:
DNSServiceRef dnssref;
QSocketNotifier *bonjourSocket;
BonjourRecord finalRecord;
// current port
quint16 _port = 0;
};
#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 <utils/Logger.h>
// pre-declarioation
// pre-declaration
class Effect;
typedef struct _ts PyThreadState;
class EffectFileHandler;
class EffectEngine : public QObject
{
Q_OBJECT
public:
EffectEngine(Hyperion * hyperion, const QJsonObject & jsonEffectConfig);
EffectEngine(Hyperion * hyperion);
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<EffectSchema> & getEffectSchemas()
{
return _effectSchemas;
};
///
/// Get available schemas from EffectFileHandler
/// @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:
/// 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");
/// 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
void channelCleared(int priority);
@ -59,28 +93,36 @@ public slots:
private slots:
void effectFinished();
///
/// @brief is called whenever the EffectFileHandler emits updated effect list
///
void handleUpdatedEffectList();
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
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:
Hyperion * _hyperion;
QJsonObject _effectConfig;
std::list<EffectDefinition> _availableEffects;
std::list<Effect *> _activeEffects;
std::list<ActiveEffectDefinition> _availableActiveEffects;
std::list<EffectSchema> _effectSchemas;
std::list<ActiveEffectDefinition> _cachedActiveEffects;
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
// Python includes
// collide of qt slots macro
#undef slots
#include <Python.h>
#define slots
// Qt includes
#include <QThread>
#include <QSize>
#include <QImage>
#include <QPainter>
#include <QMap>
#include <QJsonValue>
// Hyperion includes
#include <hyperion/ImageProcessor.h>
#include <utils/Components.h>
class Effect;
class Effect : public QThread
class EffectModule
{
Q_OBJECT
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);
virtual ~Effect();
// Python 3 module def
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; }
QString getName() const { return _name; }
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;
// json 2 python
static PyObject * json2python(const QJsonValue & jsonData);
// Wrapper methods for Python interpreter extra buildin methods
static PyMethodDef effectMethods[];
@ -71,38 +49,5 @@ private:
static PyObject* wrapImageCOffset (PyObject *self, PyObject *args);
static PyObject* wrapImageCShear (PyObject *self, PyObject *args);
static PyObject* wrapImageResetT (PyObject *self, PyObject *args);
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;
static Effect * getEffect();
};

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] grabHeight The height of the grabbed images [pixels]
/// @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.

View File

@ -40,14 +40,23 @@ public:
///
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:
///
///
/// Updates the frame-grab flags as used by the VC library for frame grabbing
///
/// @param vc_flags The snapshot grabbing mask
///
void setFlags(const int vc_flags);
///
/// @brief free _vc_resource and captureBuffer
///
void freeResources();
/// Handle to the display that is being captured
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
/// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the
/// attached Hyperion.
/// displayed content. This ImageRgb is forwarded to all Hyperion instances via HyperionDaemon
///
class DispmanxWrapper: public GrabberWrapper
{
@ -20,9 +19,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @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.

View File

@ -5,7 +5,7 @@
#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
{
@ -30,13 +30,18 @@ public:
///
int grabFrame(Image<ColorRgb> & image);
///
/// @brief Overwrite Grabber.h implememtation
///
virtual void setDevicePath(const QString& path);
private:
/// Framebuffer file descriptor
int _fbfd;
/// Pointer to framebuffer
unsigned char * _fbp;
/// 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] 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.

View File

@ -12,7 +12,7 @@
#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
{
@ -37,10 +37,15 @@ public:
///
int grabFrame(Image<ColorRgb> & image);
private:
///
/// @brief Overwrite Grabber.h implementation
///
virtual void setDisplayIndex(int index);
private:
/// display
const unsigned _screenIndex;
unsigned _screenIndex;
/// Reference to the captured diaplay
CGDirectDisplayID _display;
};

View File

@ -19,9 +19,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @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.

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:
V4L2Grabber(const QString & device,
int input,
VideoStandard videoStandard, PixelFormat pixelFormat,
unsigned width,
unsigned height,
int frameDecimation,
int horizontalPixelDecimation,
int verticalPixelDecimation
VideoStandard videoStandard,
PixelFormat pixelFormat,
int pixelDecimation
);
virtual ~V4L2Grabber();
@ -37,21 +33,46 @@ public:
bool getSignalDetectionEnabled();
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 greenSignalThreshold,
double blueSignalThreshold,
int noSignalCounterThreshold);
int noSignalCounterThreshold = 50);
void setSignalDetectionOffset(
///
/// @brief overwrite Grabber.h implementation
///
virtual void setSignalDetectionOffset(
double verticalMin,
double horizontalMin,
double verticalMax,
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();
@ -66,7 +87,7 @@ private slots:
private:
void getV4Ldevices();
bool init();
void uninit();
@ -120,9 +141,9 @@ private:
std::vector<buffer> _buffers;
PixelFormat _pixelFormat;
int _pixelDecimation;
int _lineLength;
int _frameByteSize;
int _frameDecimation;
// signal detection
int _noSignalCounterThreshold;
@ -134,7 +155,6 @@ private:
double _y_frac_min;
double _x_frac_max;
double _y_frac_max;
int _currentFrame;
QSocketNotifier * _streamNotifier;

View File

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

View File

@ -17,12 +17,12 @@ class X11Grabber : public Grabber
{
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();
bool Setup();
///
/// 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
@ -32,15 +32,34 @@ public:
/// height)
///
virtual int grabFrame(Image<ColorRgb> & image, bool forceUpdate=false);
///
/// update dimension according current screen
int updateScreenDimensions(bool force=false);
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:
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
bool _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
XImage* _xImage;
XShmSegmentInfo _shminfo;
@ -49,17 +68,16 @@ private:
Display* _x11Display;
Window _window;
XWindowAttributes _windowAttr;
Pixmap _pixmap;
XRenderPictFormat* _srcFormat;
XRenderPictFormat* _dstFormat;
XRenderPictureAttributes _pictAttr;
Picture _srcPicture;
Picture _dstPicture;
XTransform _transform;
int _horizontalDecimation;
int _verticalDecimation;
int _pixelDecimation;
unsigned _screenWidth;
unsigned _screenHeight;
@ -67,7 +85,7 @@ private:
unsigned _src_y;
Image<ColorRgb> _image;
void freeResources();
void setupResources();
};

View File

@ -24,7 +24,7 @@ public:
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @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.
@ -43,4 +43,3 @@ private:
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