Merge pull request #618 from hyperion-project/Beta
Merge Beta to Master
This commit is contained in:
commit
a31855da06
|
@ -29,6 +29,8 @@ cmake -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
|||
cmake -DENABLE_WS2812BPWM=ON -DENABLE_WS281XPWM=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
# or if you are not compiling on the raspberry pi (e.g. OrangePi) and need to disable the Dispmanx grabber and support for spi devices
|
||||
cmake -DENABLE_DISPMANX=OFF -DENABLE_SPIDEV=OFF -DENABLE_X11=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
# on amlogic platforms
|
||||
cmake -DENABLE_DISPMANX=OFF -DENABLE_SPIDEV=OFF -DENABLE_AMLOGIC=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
# as an alternative for the dispmanx grabber on non-rpi devices (e.g. cubox-i) you could try the framebuffer grabber
|
||||
cmake -DENABLE_DISPMANX=OFF -DENABLE_SPIDEV=OFF -DENABLE_FB=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
# for OSX build you need XCode, qt4 libraries and cmake (maybe libusb too). You can use macport or homebrew(recommended) to install them:
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
**Please provide some information that we could help as fast as possible.
|
||||
Please check the wiki in case your problem is already known/feature requested.**
|
||||
BEFORE YOU OPEN A NEW ISSUE!
|
||||
|
||||
**1.** Used hardware and sofware (Wetek,RPi1,Rpi2,... Ubuntu 14.04(64bit),OSX,OpenELEC,OSMC,XBian,...)
|
||||
**2.** Your LED device and additional hardware (if used) (WS2801,APA102,WS2812B,... connected through (direct,arduino uno,...))
|
||||
**3.** Please upload your Hyperion log to pastebin.com and insert the link. Have a look at the wiki how you get one.
|
||||
**4.** Please upload your "Hyperion Configuration File" to pastebin.com and insert the link.
|
||||
Search at our wiki: wiki.hyperion-project.org
|
||||
Our FAQ: https://hyperion-project.org/wiki/FAQ-Frequently-Asked-Questions
|
||||
And have a look at our forum: forum.hyperion-project.org
|
||||
If you need help please open a new thread their!
|
||||
|
||||
WE PROVIDE NO SUPPORT AT GITHUB!
|
||||
All misleading issues will be closed without a announcement!
|
||||
|
|
|
@ -3,3 +3,5 @@ IMPORTANT: Please don´t commit to master, we will test your changes first at th
|
|||
**2.** If this changes affect the .conf file. Please provide the changed section
|
||||
**3.** Reference a issue (optional)
|
||||
|
||||
Note: For further discussions use our forum: forum.hyperion-project.org
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
HYPERION
|
||||
========
|
||||
|
||||
Hyperion is an opensource 'AmbiLight' implementation controlled using the RaspBerry Pi running [Raspbmc](http://www.raspbmc.com). The main features of Hyperion are:
|
||||
Hyperion is an opensource 'AmbiLight' implementation supported by many devices. The main features of Hyperion are:
|
||||
* Low CPU load. For a led string of 50 leds the CPU usage will typically be below 1.5% on a non-overclocked Pi.
|
||||
* Json interface which allows easy integration into scripts.
|
||||
* A command line utility allows easy testing and configuration of the color transforms (Transformation settings are not preserved over a restart at the moment...).
|
||||
* Priority channels are not coupled to a specific led data provider which means that a provider can post led data and leave without the need to maintain a connection to Hyperion. This is ideal for a remote application (like our Android app).
|
||||
* HyperCon. A tool which helps generate a Hyperion configuration file.
|
||||
* XBMC-checker which checks the playing status of XBMC and decides whether or not to capture the screen.
|
||||
* Kodi-checker which checks the playing status of Kodi and decides whether or not to capture the screen.
|
||||
* Black border detector.
|
||||
* A scriptable effect engine.
|
||||
* Generic software architecture to support new devices and new algorithms easily.
|
||||
|
||||
More information can be found on the [wiki](https://github.com/tvdzwan/hyperion/wiki) or the [Hyperion topic](http://forum.stmlabs.com/showthread.php?tid=11053) on the Raspbmc forum.
|
||||
More information can be found on the [wiki](wiki.hyperion-project.org) or the [Hyperion webpage/forum](www.hyperion-project.org).
|
||||
|
||||
The source is released under MIT-License (see http://opensource.org/licenses/MIT).
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/sh
|
||||
# create all directly for release with -DCMAKE_BUILD_TYPE=Release -Wno-dev
|
||||
# Create the x64 build
|
||||
mkdir build-x32x64
|
||||
cd build-x32x64
|
||||
mkdir build-x86x64
|
||||
cd build-x86x64
|
||||
cmake -DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
make -j 4
|
||||
cd ..
|
||||
|
@ -17,14 +17,14 @@ cd ..
|
|||
# Create the RPI build
|
||||
mkdir build-rpi
|
||||
cd build-rpi
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-rpi.cmake" -DIMPORT_PROTOC=../build-x32x64/protoc_export.cmake -DENABLE_WS2812BPWM=ON -DENABLE_WS281XPWM=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-rpi.cmake" -DIMPORT_PROTOC=../build-x86x64/protoc_export.cmake -DENABLE_WS2812BPWM=ON -DENABLE_WS281XPWM=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
make -j 4
|
||||
cd ..
|
||||
|
||||
# Create the WETEK build
|
||||
mkdir build-wetek
|
||||
cd build-wetek
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-rpi.cmake" -DIMPORT_PROTOC=../build-x32x64/protoc_export.cmake -DENABLE_DISPMANX=OFF -DENABLE_FB=ON -DENABLE_AMLOGIC=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-rpi.cmake" -DIMPORT_PROTOC=../build-x86x64/protoc_export.cmake -DENABLE_DISPMANX=OFF -DENABLE_FB=ON -DENABLE_AMLOGIC=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
|
||||
make -j 4
|
||||
cd ..
|
||||
|
||||
|
@ -35,7 +35,7 @@ cd ..
|
|||
#make -j 4
|
||||
#cd ..
|
||||
|
||||
bin/create_release.sh . x32x64
|
||||
bin/create_release.sh . x86x64
|
||||
#bin/create_release.sh . x32
|
||||
bin/create_release.sh . rpi
|
||||
bin/create_release.sh . wetek
|
||||
|
|
|
@ -9,16 +9,9 @@ if [ "$1" = "HyperConInstall" ] || [ "$2" = "HyperConInstall" ]; then
|
|||
HCInstall=1
|
||||
else HCInstall=0
|
||||
fi
|
||||
if [ "$1" = "WS281X" ] || [ "$2" = "WS281X" ]; then
|
||||
PWM=1
|
||||
else PWM=0
|
||||
fi
|
||||
|
||||
#Check if HyperCon is logged in as root
|
||||
if [ $(id -u) != 0 ] && [ $HCInstall -eq 1 ]; then
|
||||
echo '---> Critical Error: Please connect as user "root" through HyperCon'
|
||||
echo '---> We need admin privileges to install/update your Hyperion! -> abort'
|
||||
exit 1
|
||||
if [ "$1" = "BETA" ] || [ "$2" = "BETA" ]; then
|
||||
BETA=1
|
||||
else BETA=0
|
||||
fi
|
||||
|
||||
#Check, if script is running as root
|
||||
|
@ -27,27 +20,39 @@ if [ $(id -u) != 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
#Set welcome message
|
||||
if [ $BETA -eq 1 ]; then
|
||||
WMESSAGE="echo This script will update Hyperion to the latest BETA"
|
||||
else WMESSAGE="echo This script will install/update Hyperion ambilight"
|
||||
fi
|
||||
|
||||
#Welcome message
|
||||
echo '*******************************************************************************'
|
||||
echo 'This script will install/update Hyperion and it´s services'
|
||||
echo 'Version 0.1'
|
||||
$WMESSAGE
|
||||
echo 'Created by brindosch - hyperion-project.org - the official Hyperion source.'
|
||||
echo '*******************************************************************************'
|
||||
|
||||
# Find out if we are on OpenElec / OSMC
|
||||
# Find out if we are on OpenElec / OSMC / Raspbian
|
||||
OS_OPENELEC=`grep -m1 -c OpenELEC /etc/issue`
|
||||
OS_OSMC=`grep -m1 -c OSMC /etc/issue`
|
||||
OS_RASPBIAN=`grep -m1 -c 'Raspbian\|RetroPie' /etc/issue`
|
||||
|
||||
# Find out if its an imx6 device
|
||||
# Find out which device this script runs on
|
||||
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710' /proc/cpuinfo`
|
||||
CPU_IMX6=`grep -m1 -c i.MX6 /proc/cpuinfo`
|
||||
CPU_WETEK=`grep -m1 -c Amlogic /proc/cpuinfo`
|
||||
CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l`
|
||||
#CPU_X32=`uname -m | grep 'x86_32\|i686' | wc -l`
|
||||
# Check that we have a known configuration
|
||||
if [ $CPU_RPI -ne 1 ] && [ $CPU_IMX6 -ne 1 ] && [ $CPU_WETEK -ne 1 ] && [ $CPU_X32X64 -ne 1 ]; then
|
||||
echo '---> Critical Error: CPU information does not match any known releases -> abort'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#Check which RPi we are one (in case)
|
||||
RPI_1=`grep -m1 -c BCM2708 /proc/cpuinfo`
|
||||
RPI_2=`grep -m1 -c BCM2709 /proc/cpuinfo`
|
||||
RPI_3=`grep -m1 -c BCM2710 /proc/cpuinfo`
|
||||
|
||||
#Check, if year equals 1970
|
||||
DATE=$(date +"%Y")
|
||||
if [ "$DATE" -le "2015" ]; then
|
||||
|
@ -63,7 +68,7 @@ USE_SERVICE=`which /usr/sbin/service | wc -l`
|
|||
# Make sure that the boblight daemon is no longer running
|
||||
BOBLIGHT_PROCNR=$(pidof boblightd | wc -l)
|
||||
if [ $BOBLIGHT_PROCNR -eq 1 ]; then
|
||||
echo '---> Critical Error: Found running instance of boblight. Please stop boblight via XBMC menu before installing hyperion -> abort'
|
||||
echo '---> Critical Error: Found running instance of boblight. Please stop boblight via Kodi menu before installing hyperion -> abort'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -88,7 +93,7 @@ if [ $OS_OPENELEC -ne 1 ]; then
|
|||
fi
|
||||
|
||||
#Check, if dtparam=spi=on is in place (not for OPENELEC)
|
||||
if [ $PWM -ne 1 ] && [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -ne 1 ]; then
|
||||
if [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -ne 1 ]; then
|
||||
SPIOK=`grep '^\dtparam=spi=on' /boot/config.txt | wc -l`
|
||||
if [ $SPIOK -ne 1 ]; then
|
||||
echo '---> Raspberry Pi found, but SPI is not ready, we write "dtparam=spi=on" to /boot/config.txt'
|
||||
|
@ -98,7 +103,7 @@ if [ $PWM -ne 1 ] && [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -ne 1 ]; then
|
|||
fi
|
||||
|
||||
#Check, if dtparam=spi=on is in place (just for OPENELEC)
|
||||
if [ $PWM -ne 1 ] && [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ]; then
|
||||
if [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ]; then
|
||||
SPIOK=`grep '^\dtparam=spi=on' /flash/config.txt | wc -l`
|
||||
if [ $SPIOK -ne 1 ]; then
|
||||
mount -o remount,rw /flash
|
||||
|
@ -109,27 +114,6 @@ if [ $PWM -ne 1 ] && [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
#Check, if dtoverlay=pwm is in place (not for OPENELEC)
|
||||
#if [ $PWM -eq 1 ] && [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -ne 1 ]; then
|
||||
# PWMOK=`grep '^\dtoverlay=pwm' /boot/config.txt | wc -l`
|
||||
# if [ $PWMOK -ne 1 ]; then
|
||||
# echo '---> Raspberry Pi found, but PWM is not ready, we write "dtoverlay=pwm" to /boot/config.txt'
|
||||
# sed -i '$a dtoverlay=pwm' /boot/config.txt
|
||||
# PWMREBOOTMESSAGE="echo Please reboot your Raspberry Pi, we inserted dtoverlay=pwm to /boot/config.txt"
|
||||
# fi
|
||||
#fi
|
||||
|
||||
#Check, if dtoverlay=pwm is in place (just for OPENELEC)
|
||||
if [ $PWM -eq 1 ] && [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ]; then
|
||||
PWMOK=`grep '^\dtoverlay=pwm' /flash/config.txt | wc -l`
|
||||
if [ $PWMOK -ne 1 ]; then
|
||||
mount -o remount,rw /flash
|
||||
echo '---> Raspberry Pi with OpenELEC found, but PWM is not ready, we write "dtoverlay=pwm" to /flash/config.txt'
|
||||
sed -i '$a dtoverlay=pwm' /flash/config.txt
|
||||
mount -o remount,ro /flash
|
||||
PWMREBOOTMESSAGE="echo Please reboot your OpenELEC, we inserted dtoverlay=pwm to /flash/config.txt"
|
||||
fi
|
||||
fi
|
||||
#Backup the .conf files, if present
|
||||
echo '---> Backup Hyperion configuration(s), if present'
|
||||
rm -f /tmp/*.json 2>/dev/null
|
||||
|
@ -138,11 +122,33 @@ if [ $OS_OPENELEC -eq 1 ]; then
|
|||
else cp -v /opt/hyperion/config/*.json /tmp 2>/dev/null
|
||||
fi
|
||||
|
||||
# Select the appropriate download path
|
||||
if [ $BETA -eq 1 ]; then
|
||||
HYPERION_ADDRESS=https://sourceforge.net/projects/hyperion-project/files/beta
|
||||
else HYPERION_ADDRESS=https://sourceforge.net/projects/hyperion-project/files/release
|
||||
fi
|
||||
# Select the appropriate release
|
||||
HYPERION_ADDRESS=https://raw.githubusercontent.com/tvdzwan/hyperion/master/deploy
|
||||
if [ $CPU_RPI -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi.tar.gz
|
||||
if [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ] && [ $RPI_1 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi_oe.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-rpi.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ] && [ $RPI_2 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi2_oe.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-rpi.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ] && [ $RPI_3 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi3_oe.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-rpi.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $OS_OSMC -eq 1 ] && [ $RPI_1 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi_osmc.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $OS_OSMC -eq 1 ] && [ $RPI_2 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi2_osmc.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $OS_OSMC -eq 1 ] && [ $RPI_3 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi3_osmc.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $RPI_1 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $RPI_2 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi2.tar.gz
|
||||
elif [ $CPU_RPI -eq 1 ] && [ $RPI_3 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_rpi3.tar.gz
|
||||
elif [ $CPU_IMX6 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_imx6.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-imx6.tar.gz
|
||||
|
@ -150,11 +156,8 @@ elif [ $CPU_WETEK -eq 1 ]; then
|
|||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_wetek.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-rpi.tar.gz
|
||||
elif [ $CPU_X32X64 -eq 1 ]; then
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_x32x64.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-x32x64.tar.gz
|
||||
#elif [ $CPU_X32 -eq 1 ]; then
|
||||
# HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_x32.tar.gz
|
||||
# OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-x32x64.tar.gz
|
||||
HYPERION_RELEASE=$HYPERION_ADDRESS/hyperion_x86x64.tar.gz
|
||||
OE_DEPENDECIES=$HYPERION_ADDRESS/hyperion.deps.openelec-x86x64.tar.gz
|
||||
else
|
||||
echo "---> Critical Error: Target platform unknown -> abort"
|
||||
exit 1
|
||||
|
@ -185,9 +188,6 @@ else
|
|||
ln -fs /opt/hyperion/bin/hyperion-v4l2 /usr/bin/hyperion-v4l2
|
||||
ln -fs /opt/hyperion/bin/hyperion-dispmanx /usr/bin/hyperion-dispmanx 2>/dev/null
|
||||
ln -fs /opt/hyperion/bin/hyperion-x11 /usr/bin/hyperion-x11 2>/dev/null
|
||||
|
||||
# Copy a link to the hyperion configuration file to /etc (-s for people who replaced the symlink with their config)
|
||||
ln -s /opt/hyperion/config/hyperion.config.json /etc/hyperion.config.json 2>/dev/null
|
||||
fi
|
||||
|
||||
# Restore backup of .conf files, if present
|
||||
|
@ -203,16 +203,18 @@ if [ $USE_INITCTL -eq 1 ]; then
|
|||
cp -n /opt/hyperion/init.d/hyperion.initctl.sh /etc/init/hyperion.conf 2>/dev/null
|
||||
initctl reload-configuration
|
||||
elif [ $OS_OPENELEC -eq 1 ]; then
|
||||
#modify all old installs with a logfile output
|
||||
sed -i 's|/dev/null|/storage/logfiles/hyperion.log|g' /storage/.config/autostart.sh
|
||||
# only add to start script if hyperion is not present yet
|
||||
if [ `cat /storage/.config/autostart.sh 2>/dev/null | grep hyperiond | wc -l` -eq 0 ]; then
|
||||
echo '---> Adding Hyperion to OpenELEC autostart.sh'
|
||||
echo "/storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json > /dev/null 2>&1 &" >> /storage/.config/autostart.sh
|
||||
echo "/storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json > /storage/logfiles/hyperion.log 2>&1 &" >> /storage/.config/autostart.sh
|
||||
chmod +x /storage/.config/autostart.sh
|
||||
fi
|
||||
# only add hyperion-x11 to startup, if not found and x32x64 detected
|
||||
if [ $CPU_X32X64 -eq 1 ] && [ `cat /storage/.config/autostart.sh 2>/dev/null | grep hyperion-x11 | wc -l` -eq 0 ]; then
|
||||
echo '---> Adding Hyperion-x11 to OpenELEC autostart.sh'
|
||||
echo "DISPLAY=:0.0 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/storage/hyperion/bin /storage/hyperion/bin/hyperion-x11 </dev/null >/dev/null 2>&1 &" >> /storage/.config/autostart.sh
|
||||
echo "DISPLAY=:0.0 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/storage/hyperion/bin /storage/hyperion/bin/hyperion-x11 </dev/null >/storage/logfiles/hyperion.log 2>&1 &" >> /storage/.config/autostart.sh
|
||||
fi
|
||||
elif [ $USE_SYSTEMD -eq 1 ]; then
|
||||
echo '---> Installing systemd script'
|
||||
|
@ -223,22 +225,14 @@ elif [ $USE_SYSTEMD -eq 1 ]; then
|
|||
rm /etc/init.d/hyperion 2>/dev/null
|
||||
cp -n /opt/hyperion/init.d/hyperion.systemd.sh /etc/systemd/system/hyperion.service
|
||||
systemctl -q enable hyperion.service
|
||||
if [ $PWM -eq 1 ] && [ $OS_OSMC -eq 1 ]; then
|
||||
echo '---> Modify systemd script for OSMC usage (PWM Support)'
|
||||
# Wait until kodi is sarted (for xbmc checker) and FIX user in case it is wrong (need root for access to pwm!)!
|
||||
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
|
||||
elif [ $OS_OSMC -eq 1 ]; then
|
||||
echo '---> Modify systemd script for OSMC usage'
|
||||
# Wait until kodi is sarted (for xbmc checker) and replace user (for remote control through osmc)
|
||||
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=root/User=osmc/g' /etc/systemd/system/hyperion.service
|
||||
sed -i 's/Group=root/Group=osmc/g' /etc/systemd/system/hyperion.service
|
||||
systemctl -q daemon-reload
|
||||
fi
|
||||
elif [ $USE_SERVICE -eq 1 ]; then
|
||||
echo '---> Installing startup script in init.d'
|
||||
|
@ -248,10 +242,17 @@ elif [ $USE_SERVICE -eq 1 ]; then
|
|||
update-rc.d hyperion defaults 98 02
|
||||
fi
|
||||
|
||||
#chown the /config/ dir and all configs inside for hypercon config upload for non-root logins
|
||||
if [ $OS_OSMC -eq 1 ]; then
|
||||
chown -R osmc:osmc /opt/hyperion/config
|
||||
elif [ $OS_RASPBIAN -eq 1 ]; then
|
||||
chown -R pi:pi /opt/hyperion/config
|
||||
fi
|
||||
|
||||
# Start the hyperion daemon
|
||||
echo '---> Starting Hyperion'
|
||||
if [ $OS_OPENELEC -eq 1 ]; then
|
||||
/storage/.config/autostart.sh
|
||||
/storage/.config/autostart.sh > /dev/null 2>&1 &
|
||||
elif [ $USE_INITCTL -eq 1 ]; then
|
||||
/sbin/initctl start hyperion
|
||||
elif [ $USE_SERVICE -eq 1 ]; then
|
||||
|
@ -260,27 +261,21 @@ elif [ $USE_SYSTEMD -eq 1 ]; then
|
|||
service hyperion start
|
||||
fi
|
||||
|
||||
#Hint for the user with path to config
|
||||
if [ $OS_OPENELEC -eq 1 ];then
|
||||
HINTMESSAGE="echo Path to your configuration -> /storage/.config/hyperion.config.json"
|
||||
else HINTMESSAGE="echo Path to your configuration -> /etc/hyperion.config.json"
|
||||
fi
|
||||
echo '*******************************************************************************'
|
||||
echo 'Hyperion Installation/Update finished!'
|
||||
echo 'Please get a new HyperCon version to benefit from the latest features!'
|
||||
echo 'Create a new config file, if you encounter problems!'
|
||||
$HINTMESSAGE
|
||||
echo 'Please download the latest HyperCon version to benefit from new features!'
|
||||
echo 'To create a config, follow the HyperCon Guide at our Wiki (EN/DE)!'
|
||||
echo 'Wiki: wiki.hyperion-project.org Webpage: www.hyperion-project.org'
|
||||
$REBOOTMESSAGE
|
||||
$PWMREBOOTMESSAGE
|
||||
echo '*******************************************************************************'
|
||||
## Force reboot and prevent prompt if spi is added during a HyperCon Install
|
||||
if ( [ "$HCInstall" = "1" ] && [ "$CPU_RPI" = "1" ] ) && ( [ "$SPIOK" = "0" ] || [ "$PWMOK" = "0" ] ); then
|
||||
echo "Rebooting now, we added dtparam=spi=on and/or dtoverlay=pwm to config.txt"
|
||||
if [ $HCInstall -eq 1 ] && [ $CPU_RPI -eq 1 ] && [ $SPIOK -ne 1 ]; then
|
||||
echo "Rebooting now, we added dtparam=spi=on to config.txt"
|
||||
reboot
|
||||
exit 0
|
||||
fi
|
||||
#Prompt for reboot, if spi added to config.txt
|
||||
if ( [ "$CPU_RPI" = "1" ] ) && ( [ "$SPIOK" = "0" ] || [ "$PWMOK" = "0" ] ); then
|
||||
if [ $CPU_RPI -eq 1 ] && [ $SPIOK -ne 1 ]; then
|
||||
while true
|
||||
do
|
||||
echo -n "---> Do you want to reboot your Raspberry Pi now? (y or n) :"
|
||||
|
|
|
@ -21,6 +21,7 @@ fi
|
|||
echo '*******************************************************************************'
|
||||
echo 'This script will remove Hyperion and it´s services'
|
||||
echo '-----> Please BACKUP your hyperion.config.json if necessary <-----'
|
||||
echo 'Created by brindosch - hyperion-project.org - the official Hyperion source.'
|
||||
echo '*******************************************************************************'
|
||||
|
||||
#Skip the prompt if HyperCon Remove
|
||||
|
@ -49,6 +50,9 @@ USE_SYSTEMD=`grep -m1 -c systemd /proc/1/comm`
|
|||
USE_INITCTL=`which /sbin/initctl | wc -l`
|
||||
USE_SERVICE=`which /usr/sbin/service | wc -l`
|
||||
|
||||
# set count for forwarder
|
||||
SERVICEC=1
|
||||
|
||||
# Stop hyperion daemon if it is running
|
||||
echo '---> Stop Hyperion, if necessary'
|
||||
if [ $OS_OPENELEC -eq 1 ]; then
|
||||
|
@ -59,12 +63,19 @@ elif [ $USE_SERVICE -eq 1 ]; then
|
|||
/usr/sbin/service hyperion stop 2>/dev/null
|
||||
elif [ $USE_SYSTEMD -eq 1 ]; then
|
||||
service hyperion stop 2>/dev/null
|
||||
while [ $SERVICEC -le 20 ]; do
|
||||
service hyperion_fw$SERVICEC stop 2>/dev/null
|
||||
((SERVICEC++))
|
||||
done
|
||||
fi
|
||||
|
||||
#reset count
|
||||
SERVICEC=`which /usr/sbin/service | wc -l`
|
||||
|
||||
#Disabling and delete service files
|
||||
if [ $USE_INITCTL -eq 1 ]; then
|
||||
echo '---> Delete and disable Hyperion initctl script'
|
||||
rm -v /etc/init/hyperion.conf 2>/dev/null
|
||||
rm -v /etc/init/hyperion* 2>/dev/null
|
||||
initctl reload-configuration
|
||||
elif [ $OS_OPENELEC -eq 1 ]; then
|
||||
# Remove Hyperion from OpenELEC autostart.sh
|
||||
|
@ -75,12 +86,20 @@ elif [ $USE_SYSTEMD -eq 1 ]; then
|
|||
# Delete and disable Hyperion systemd script
|
||||
echo '---> Delete and disable Hyperion systemd script'
|
||||
systemctl disable hyperion.service
|
||||
rm -v /etc/systemd/system/hyperion.service 2>/dev/null
|
||||
while [ $SERVICEC -le 20 ]; do
|
||||
systemctl -q disable hyperion_fw$SERVICEC.service 2>/dev/null
|
||||
((SERVICEC++))
|
||||
done
|
||||
rm -v /etc/systemd/system/hyperion* 2>/dev/null
|
||||
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
|
||||
while [ $SERVICEC -le 20 ]; do
|
||||
update-rc.d -f hyperion_fw$SERVICEC remove 2>/dev/null
|
||||
((SERVICEC++))
|
||||
done
|
||||
rm /etc/init.d/hyperion* 2>/dev/null
|
||||
fi
|
||||
|
||||
# Delete Hyperion binaries
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
### END INIT INFO
|
||||
|
||||
DAEMON=hyperiond
|
||||
DAEMONOPTS="/etc/hyperion.config.json"
|
||||
DAEMONOPTS="/opt/hyperion/config/hyperion.config.json"
|
||||
DAEMON_PATH="/usr/bin"
|
||||
|
||||
NAME=$DAEMON
|
||||
|
@ -22,7 +22,7 @@ PIDFILE=/var/run/$NAME.pid
|
|||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
case "$1" in
|
||||
start)
|
||||
if [ $(pgrep -l $NAME |wc -l) = 1 ]
|
||||
if [ $(pgrep -xl $NAME |wc -l) = 1 ]
|
||||
then
|
||||
printf "%-50s\n" "Already running..."
|
||||
exit 1
|
||||
|
@ -59,7 +59,7 @@ stop)
|
|||
PID=`cat $PIDFILE`
|
||||
cd $DAEMON_PATH
|
||||
if [ -f $PIDFILE ]; then
|
||||
kill -HUP $PID
|
||||
kill $PID
|
||||
printf "%s\n" "Ok"
|
||||
rm -f $PIDFILE
|
||||
else
|
||||
|
|
|
@ -8,4 +8,4 @@ stop on (runlevel [!2345])
|
|||
|
||||
respawn
|
||||
|
||||
exec /usr/bin/hyperiond /etc/hyperion.config.json
|
||||
exec /usr/bin/hyperiond /opt/hyperion/config/hyperion.config.json
|
|
@ -6,10 +6,10 @@ Type=simple
|
|||
User=root
|
||||
Group=root
|
||||
UMask=007
|
||||
ExecStart=/opt/hyperion/bin/hyperiond /etc/hyperion.config.json
|
||||
ExecStart=/opt/hyperion/bin/hyperiond /opt/hyperion/config/hyperion.config.json
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=multi-user.target
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
// Automatically generated configuration file for 'Hyperion daemon'
|
||||
// Generated by: HyperCon (The Hyperion deamon configuration file builder
|
||||
// Generated by: HyperCon (The Hyperion deamon configuration file builder)
|
||||
// Created with HyperCon V1.02.0 (30.04.2016)
|
||||
|
||||
{
|
||||
/// 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, Adalight, AmbiLed, Atmo, Hyperion-USBASP-WS2801, Hyperion-USBASP-WS2812, Lightberry, Lightpack, LPD6803, LPD8806, Multi-Lightpack, P9813, Paintpack, PhilipsHUE, PiBlaster, SEDU, file, ThinkerForge, TPM2, WS2801, WS2812b, None)
|
||||
/// ---------SPI---------, 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, AmbiLed, Atmo, Lightpack, Multi-Lightpack, Paintpack, Test (file), None)
|
||||
/// * [device type specific configuration]
|
||||
/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).
|
||||
"device" :
|
||||
{
|
||||
"name" : "MyPi",
|
||||
"name" : "MyHyperionConfig",
|
||||
"type" : "ws2801",
|
||||
"output" : "/dev/spidev0.0",
|
||||
"rate" : 1000000,
|
||||
|
@ -20,18 +21,31 @@
|
|||
/// Color manipulation configuration used to tune the output colors to specific surroundings.
|
||||
/// The configuration contains a list of color-transforms. Each transform contains the
|
||||
/// following fields:
|
||||
/// * 'id' : The unique identifier of the color transformation (eg 'device_1') /// * 'leds' : The indices (or index ranges) of the leds to which this color transform applies
|
||||
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based. /// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following
|
||||
/// * 'channelAdjustment'
|
||||
/// * '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.
|
||||
/// * 'pureRed'/'pureGreen'/'pureBlue' : The manipulation in the Red-Green-Blue color domain with the
|
||||
/// following tuning parameters for each channel:
|
||||
/// * 'temperature'
|
||||
/// * 'id' : The unique identifier of the temperature (eg 'device_1')
|
||||
/// * 'leds' : The indices (or index ranges) of the leds to which this temperature applies
|
||||
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based.
|
||||
/// * 'red'/'green'/'blue' : The temperature manipulation in the Red-Green-Blue color domain with the
|
||||
/// following tuning parameters for each channel:
|
||||
/// * 'transform'
|
||||
/// * 'id' : The unique identifier of the color transformation (eg 'device_1')
|
||||
/// * 'leds' : The indices (or index ranges) of the leds to which this color transform applies
|
||||
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based.
|
||||
/// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following
|
||||
/// tuning parameters:
|
||||
/// - 'saturationGain' The gain adjustement of the saturation
|
||||
/// - 'valueGain' The gain adjustement of the value
|
||||
/// - 'luminanceGain' The gain adjustement of the luminance
|
||||
/// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the
|
||||
/// following tuning parameters for each channel:
|
||||
/// - 'threshold' The minimum required input value for the channel to be on
|
||||
/// (else zero)
|
||||
/// - 'gamma' The gamma-curve correction factor
|
||||
/// - 'blacklevel' The lowest possible value (when the channel is black)
|
||||
/// - 'whitelevel' The highest possible value (when the channel is white)
|
||||
///
|
||||
/// Next to the list with color transforms there is also a smoothing option.
|
||||
/// * 'smoothing' : Smoothing of the colors in the time-domain with the following tuning
|
||||
|
@ -42,16 +56,28 @@
|
|||
/// - 'updateDelay' The delay of the output to leds (in periods of smoothing)
|
||||
"color" :
|
||||
{
|
||||
"correction" :
|
||||
"channelAdjustment" :
|
||||
[
|
||||
{
|
||||
"id" : "default",
|
||||
"leds" : "*",
|
||||
"correctionValues" :
|
||||
"pureRed" :
|
||||
{
|
||||
"red" : 255,
|
||||
"green" : 255,
|
||||
"blue" : 255
|
||||
"redChannel" : 255,
|
||||
"greenChannel" : 0,
|
||||
"blueChannel" : 0
|
||||
},
|
||||
"pureGreen" :
|
||||
{
|
||||
"redChannel" : 0,
|
||||
"greenChannel" : 255,
|
||||
"blueChannel" : 0
|
||||
},
|
||||
"pureBlue" :
|
||||
{
|
||||
"redChannel" : 0,
|
||||
"greenChannel" : 0,
|
||||
"blueChannel" : 255
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -62,9 +88,9 @@
|
|||
"leds" : "*",
|
||||
"temperatureValues" :
|
||||
{
|
||||
"red" : 255,
|
||||
"green" : 255,
|
||||
"blue" : 255
|
||||
"red" : 255,
|
||||
"green" : 255,
|
||||
"blue" : 255
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -73,39 +99,29 @@
|
|||
{
|
||||
"id" : "default",
|
||||
"leds" : "*",
|
||||
"hsv" :
|
||||
{
|
||||
"saturationGain" : 1.0000,
|
||||
"valueGain" : 1.0000
|
||||
},
|
||||
"hsl" :
|
||||
{
|
||||
"saturationGain" : 1.0000,
|
||||
"luminanceGain" : 1.0000
|
||||
"saturationGain" : 1.0000,
|
||||
"luminanceGain" : 1.0000
|
||||
},
|
||||
"red" :
|
||||
{
|
||||
"threshold" : 0.0000,
|
||||
"gamma" : 1.0000,
|
||||
"blacklevel" : 0.0000,
|
||||
"whitelevel" : 1.0000
|
||||
"threshold" : 0.0000,
|
||||
"gamma" : 2.5000
|
||||
},
|
||||
"green" :
|
||||
{
|
||||
"threshold" : 0.0000,
|
||||
"gamma" : 1.0000,
|
||||
"blacklevel" : 0.0000,
|
||||
"whitelevel" : 1.0000
|
||||
"threshold" : 0.0000,
|
||||
"gamma" : 2.5000
|
||||
},
|
||||
"blue" :
|
||||
{
|
||||
"threshold" : 0.0000,
|
||||
"gamma" : 1.0000,
|
||||
"blacklevel" : 0.0000,
|
||||
"whitelevel" : 1.0000
|
||||
"threshold" : 0.0000,
|
||||
"gamma" : 2.5000
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"smoothing" :
|
||||
{
|
||||
"type" : "linear",
|
||||
|
@ -139,7 +155,7 @@
|
|||
/// * color : Set static color after boot -> set effect to "" (empty) and input the values [R,G,B] and set duration_ms NOT to 0 (use 1) instead
|
||||
/// * effect : The effect selected as 'boot sequence'
|
||||
/// * duration_ms : The duration of the selected effect (0=endless)
|
||||
/// * priority : The priority of the selected effect/static color (default=0)
|
||||
/// * priority : The priority of the selected effect/static color (default=990) HINT: lower value result in HIGHER priority!
|
||||
"effects" :
|
||||
{
|
||||
"paths" :
|
||||
|
@ -165,20 +181,21 @@
|
|||
// "forwarder" :
|
||||
// {
|
||||
// "proto" : ["127.0.0.1:19447"],
|
||||
// "json" : ["127.0.0.1:19446"]
|
||||
// "json" : ["127.0.0.1:19446"]
|
||||
// },
|
||||
|
||||
/// The configuration for the frame-grabber, contains the following items:
|
||||
/// * 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
|
||||
/// * priority : The priority of the frame-gabber (Default=890) HINT: lower value result in HIGHER priority!
|
||||
/// * ATTENTION : Power-of-Two resolution is not supported and leads to unexpected behaviour!
|
||||
"framegrabber" :
|
||||
{
|
||||
"width" : 80,
|
||||
"height" : 45,
|
||||
"width" : 64,
|
||||
"height" : 64,
|
||||
"frequency_Hz" : 10.0,
|
||||
"priority" : 900
|
||||
"priority" : 890
|
||||
},
|
||||
|
||||
/// The configuration of the Kodi connection used to enable and disable the frame-grabber. Contains the following fields:
|
||||
|
@ -217,10 +234,11 @@
|
|||
},
|
||||
|
||||
/// The configuration of the boblight server which enables the boblight remote interface
|
||||
/// * port : Port at which the boblight server is started
|
||||
/// * port : Port at which the boblight server is started
|
||||
/// * priority: Priority of the boblight server (Default=900) HINT: lower value result in HIGHER priority!
|
||||
// "boblightServer" :
|
||||
// {
|
||||
// "port" : 19333,
|
||||
// "port" : 19333,
|
||||
// "priority" : 900
|
||||
// },
|
||||
|
||||
|
@ -232,7 +250,7 @@
|
|||
/// * height : V4L2 height to set [default=-1]
|
||||
/// * frameDecimation : Frame decimation factor [default=2]
|
||||
/// * sizeDecimation : Size decimation factor [default=8]
|
||||
/// * priority : Hyperion priority channel [default=800]
|
||||
/// * priority : Hyperion priority channel [default=900]
|
||||
/// * mode : 3D mode to use 2D/3DSBS/3DTAB (note: no autodetection) [default="2D"]
|
||||
/// * cropLeft : Cropping from the left [default=0]
|
||||
/// * cropRight : Cropping from the right [default=0]
|
||||
|
@ -250,7 +268,7 @@
|
|||
// "height" : -1,
|
||||
// "frameDecimation" : 2,
|
||||
// "sizeDecimation" : 8,
|
||||
// "priority" : 800,
|
||||
// "priority" : 900,
|
||||
// "mode" : "2D",
|
||||
// "cropLeft" : 0,
|
||||
// "cropRight" : 0,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/// 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 'ws2801', 'ldp8806',
|
||||
/// 'lpd6803', 'sedu', 'adalight', 'lightpack', 'file' and 'none')
|
||||
/// 'lpd6803', 'sedu', 'adalight', 'lightpack', 'test' and 'none')
|
||||
/// * 'output' : The output specification depends on selected device. This can for example be the
|
||||
/// device specifier, device serial number, or the output file name
|
||||
/// * 'rate' : The baudrate of the output to the device
|
||||
|
@ -19,21 +19,6 @@
|
|||
"colorOrder" : "rgb"
|
||||
},
|
||||
|
||||
/// Configuration for message forwarding to other hyperions
|
||||
/// protobuffer and json remote interface are forwarded to configured hosts
|
||||
/// 'proto' is mostly used for video streams and 'json' for effects
|
||||
///
|
||||
/// ** pay attention which port you use. use correct ports for protols **
|
||||
///
|
||||
/// * 'proto' : list of host in form of <ip>:<port>
|
||||
/// * 'json' : list of host in form of <ip>:<port>
|
||||
/// "forwarder" :
|
||||
/// {
|
||||
/// "proto" : [ "127.0.0.1:19445","192.168.178.88:19445" ],
|
||||
/// "json" : [ "127.0.0.1:19444","192.168.178.88:19444" ]
|
||||
/// },
|
||||
|
||||
|
||||
/// Color manipulation configuration used to tune the output colors to specific surroundings.
|
||||
/// The configuration contains a list of color-transforms. Each transform contains the
|
||||
/// following fields:
|
||||
|
@ -374,10 +359,6 @@
|
|||
/// The configuration of the effect engine, contains the following items:
|
||||
/// * paths : An array with absolute location(s) of directories with effects
|
||||
/// * bootsequence : The effect selected as 'boot sequence'
|
||||
/// * effect : name of the effect you want to start. Set to empty if no effect wanted
|
||||
/// * color : switch to static color after effect is done
|
||||
/// * duration_ms : duration of boot effect in ms. 0 means effect stays forever
|
||||
/// * priority : priority of boot effect and static color
|
||||
"effects" :
|
||||
{
|
||||
"paths" :
|
||||
|
@ -388,23 +369,20 @@
|
|||
|
||||
"bootsequence" :
|
||||
{
|
||||
"color" : [0,0,0],
|
||||
"effect" : "Rainbow swirl fast",
|
||||
"duration_ms" : 3000,
|
||||
"priority" : 990
|
||||
"effect" : "Rainbow swirl fast",
|
||||
"duration_ms" : 3000
|
||||
},
|
||||
|
||||
/// The configuration for the frame-grabber, contains the following items:
|
||||
/// * 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]
|
||||
/// "framegrabber" :
|
||||
/// {
|
||||
/// "width" : 64,
|
||||
/// "height" : 64,
|
||||
/// "frequency_Hz" : 10.0,
|
||||
/// "priority" : 900
|
||||
/// },
|
||||
// "framegrabber" :
|
||||
// {
|
||||
// "width" : 64,
|
||||
// "height" : 64,
|
||||
// "frequency_Hz" : 10.0
|
||||
// },
|
||||
|
||||
/// The configuration of the XBMC connection used to enable and disable the frame-grabber. Contains the following fields:
|
||||
/// * xbmcAddress : The IP address of the XBMC-host
|
||||
|
@ -445,8 +423,7 @@
|
|||
/// * port : Port at which the boblight server is started
|
||||
// "boblightServer" :
|
||||
// {
|
||||
// "port" : 19333,
|
||||
// "priority" : 900
|
||||
// "port" : 19333
|
||||
// },
|
||||
|
||||
"endOfJson" : "endOfJson"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
// stl include
|
||||
#include <string>
|
||||
|
||||
// json include
|
||||
#include <json/value.h>
|
||||
|
||||
struct ActiveEffectDefinition
|
||||
{
|
||||
std::string script;
|
||||
int priority;
|
||||
int timeout;
|
||||
Json::Value args;
|
||||
};
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
// Effect engine includes
|
||||
#include <effectengine/EffectDefinition.h>
|
||||
#include <effectengine/ActiveEffectDefinition.h>
|
||||
|
||||
// pre-declarioation
|
||||
class Effect;
|
||||
|
@ -25,6 +26,8 @@ public:
|
|||
virtual ~EffectEngine();
|
||||
|
||||
const std::list<EffectDefinition> & getEffects() const;
|
||||
|
||||
const std::list<ActiveEffectDefinition> & getActiveEffects();
|
||||
|
||||
static bool loadEffectDefinition(const std::string & path, const std::string & effectConfigFile, EffectDefinition &effectDefinition);
|
||||
|
||||
|
@ -54,6 +57,8 @@ private:
|
|||
std::list<EffectDefinition> _availableEffects;
|
||||
|
||||
std::list<Effect *> _activeEffects;
|
||||
|
||||
std::list<ActiveEffectDefinition> _availableActiveEffects;
|
||||
|
||||
PyThreadState * _mainThreadState;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
// STL includes
|
||||
#include <string>
|
||||
|
||||
// Utils includes
|
||||
#include <utils/RgbChannelAdjustment.h>
|
||||
|
||||
class ColorAdjustment
|
||||
{
|
||||
public:
|
||||
|
||||
/// Unique identifier for this color transform
|
||||
std::string _id;
|
||||
|
||||
/// The RED-Channel (RGB) adjustment
|
||||
RgbChannelAdjustment _rgbRedAdjustment;
|
||||
/// The GREEN-Channel (RGB) transform
|
||||
RgbChannelAdjustment _rgbGreenAdjustment;
|
||||
/// The BLUE-Channel (RGB) transform
|
||||
RgbChannelAdjustment _rgbBlueAdjustment;
|
||||
};
|
|
@ -15,10 +15,12 @@
|
|||
#include <hyperion/PriorityMuxer.h>
|
||||
#include <hyperion/ColorTransform.h>
|
||||
#include <hyperion/ColorCorrection.h>
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
#include <hyperion/MessageForwarder.h>
|
||||
|
||||
// Effect engine includes
|
||||
#include <effectengine/EffectDefinition.h>
|
||||
#include <effectengine/ActiveEffectDefinition.h>
|
||||
|
||||
// Forward class declaration
|
||||
class LedDevice;
|
||||
|
@ -28,10 +30,11 @@ class HsvTransform;
|
|||
class HslTransform;
|
||||
class RgbChannelTransform;
|
||||
class RgbChannelCorrection;
|
||||
class RgbChannelAdjustment;
|
||||
class MultiColorTransform;
|
||||
class MultiColorCorrection;
|
||||
class MultiColorTemperature;
|
||||
|
||||
class MultiColorAdjustment;
|
||||
///
|
||||
/// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
|
||||
/// the priority muxer.
|
||||
|
@ -97,6 +100,10 @@ public:
|
|||
/// Get the list of available effects
|
||||
/// @return The list of available effects
|
||||
const std::list<EffectDefinition> &getEffects() const;
|
||||
|
||||
/// Get the list of active effects
|
||||
/// @return The list of active effects
|
||||
const std::list<ActiveEffectDefinition> &getActiveEffects();
|
||||
|
||||
public slots:
|
||||
///
|
||||
|
@ -135,6 +142,12 @@ public slots:
|
|||
///
|
||||
const std::vector<std::string> & getTemperatureIds() const;
|
||||
|
||||
///
|
||||
/// Returns the list with unique adjustment identifiers
|
||||
/// @return The list with adjustment identifiers
|
||||
///
|
||||
const std::vector<std::string> & getAdjustmentIds() const;
|
||||
|
||||
///
|
||||
/// Returns the ColorTransform with the given identifier
|
||||
/// @return The transform with the given identifier (or nullptr if the identifier does not exist)
|
||||
|
@ -153,6 +166,12 @@ public slots:
|
|||
///
|
||||
ColorCorrection * getTemperature(const std::string& id);
|
||||
|
||||
///
|
||||
/// Returns the ColorAdjustment with the given identifier
|
||||
/// @return The adjustment with the given identifier (or nullptr if the identifier does not exist)
|
||||
///
|
||||
ColorAdjustment * getAdjustment(const std::string& id);
|
||||
|
||||
///
|
||||
/// Returns MessageForwarder Object
|
||||
/// @return instance of message forwarder object
|
||||
|
@ -168,6 +187,9 @@ public slots:
|
|||
/// Tell Hyperion that the corrections have changed and the leds need to be updated
|
||||
void temperaturesUpdated();
|
||||
|
||||
/// Tell Hyperion that the corrections have changed and the leds need to be updated
|
||||
void adjustmentsUpdated();
|
||||
|
||||
///
|
||||
/// Clears the given priority channel. This will switch the led-colors to the colors of the next
|
||||
/// lower priority channel (or off if no more channels are set)
|
||||
|
@ -208,16 +230,19 @@ public:
|
|||
static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
|
||||
static MultiColorCorrection * createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorCorrectionConfig);
|
||||
static MultiColorCorrection * createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorTemperatureConfig);
|
||||
static MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorAdjustmentConfig);
|
||||
static ColorTransform * createColorTransform(const Json::Value & transformConfig);
|
||||
static ColorCorrection * createColorCorrection(const Json::Value & correctionConfig);
|
||||
static ColorAdjustment * createColorAdjustment(const Json::Value & adjustmentConfig);
|
||||
static HsvTransform * createHsvTransform(const Json::Value & hsvConfig);
|
||||
static HslTransform * createHslTransform(const Json::Value & hslConfig);
|
||||
static RgbChannelTransform * createRgbChannelTransform(const Json::Value& colorConfig);
|
||||
static RgbChannelCorrection * createRgbChannelCorrection(const Json::Value& colorConfig);
|
||||
static RgbChannelAdjustment * createRgbChannelAdjustment(const Json::Value& colorConfig, const RgbChannel color);
|
||||
|
||||
static LedDevice * createColorSmoothing(const Json::Value & smoothingConfig, LedDevice * ledDevice);
|
||||
static MessageForwarder * createMessageForwarder(const Json::Value & forwarderConfig);
|
||||
|
||||
|
||||
signals:
|
||||
/// Signal which is emitted when a priority channel is actively cleared
|
||||
/// This signal will not be emitted when a priority channel time out
|
||||
|
@ -241,15 +266,18 @@ private:
|
|||
/// The priority muxer
|
||||
PriorityMuxer _muxer;
|
||||
|
||||
/// The transformation from corrected colors to led colors
|
||||
/// The transformation from raw colors to led colors
|
||||
MultiColorTransform * _raw2ledTransform;
|
||||
|
||||
/// The correction from raw colors to led colors
|
||||
MultiColorCorrection * _raw2ledCorrection;
|
||||
|
||||
/// The temperature from corrected colors to led colors
|
||||
/// The temperature from raw colors to led colors
|
||||
MultiColorCorrection * _raw2ledTemperature;
|
||||
|
||||
/// The adjustment from raw colors to led colors
|
||||
MultiColorAdjustment * _raw2ledAdjustment;
|
||||
|
||||
/// The actual LedDevice
|
||||
LedDevice * _device;
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
// STL includes
|
||||
#include <cstdint>
|
||||
|
||||
/// Correction for a single color byte value
|
||||
/// All configuration values are unsigned int and assume the color value to be between 0 and 255
|
||||
class RgbChannelAdjustment
|
||||
{
|
||||
public:
|
||||
/// Default constructor
|
||||
RgbChannelAdjustment();
|
||||
|
||||
/// Constructor
|
||||
/// @param adjustR
|
||||
/// @param adjustG
|
||||
/// @param adjustB
|
||||
|
||||
RgbChannelAdjustment(int adjustR, int adjustG, int adjustB);
|
||||
|
||||
/// Destructor
|
||||
~RgbChannelAdjustment();
|
||||
|
||||
/// @return The current adjustR value
|
||||
uint8_t getadjustmentR() const;
|
||||
|
||||
/// @param threshold New adjustR value
|
||||
void setadjustmentR(uint8_t adjustR);
|
||||
|
||||
/// @return The current adjustG value
|
||||
uint8_t getadjustmentG() const;
|
||||
|
||||
/// @param gamma New adjustG value
|
||||
void setadjustmentG(uint8_t adjustG);
|
||||
|
||||
/// @return The current adjustB value
|
||||
uint8_t getadjustmentB() const;
|
||||
|
||||
/// @param blacklevel New adjustB value
|
||||
void setadjustmentB(uint8_t adjustB);
|
||||
|
||||
/// Transform the given array value
|
||||
/// @param input The input color bytes
|
||||
/// @return The corrected byte value
|
||||
uint8_t adjustmentR(uint8_t inputR) const;
|
||||
uint8_t adjustmentG(uint8_t inputG) const;
|
||||
uint8_t adjustmentB(uint8_t inputB) const;
|
||||
|
||||
|
||||
private:
|
||||
/// (re)-initilize the color mapping
|
||||
void initializeMapping();
|
||||
|
||||
private:
|
||||
/// The adjustment of R channel
|
||||
int _adjustR;
|
||||
/// The adjustment of G channel
|
||||
int _adjustG;
|
||||
/// The adjustment of B channel
|
||||
int _adjustB;
|
||||
|
||||
/// The mapping from input color to output color
|
||||
int _mappingR[256];
|
||||
int _mappingG[256];
|
||||
int _mappingB[256];
|
||||
};
|
|
@ -20,6 +20,12 @@ public:
|
|||
virtual void run();
|
||||
|
||||
int getPriority() const;
|
||||
|
||||
std::string getScript() const { return _script; }
|
||||
|
||||
int getTimeout() const {return _timeout; }
|
||||
|
||||
Json::Value getArgs() const { return _args; }
|
||||
|
||||
bool isAbortRequested() const;
|
||||
|
||||
|
|
|
@ -73,6 +73,23 @@ const std::list<EffectDefinition> &EffectEngine::getEffects() const
|
|||
return _availableEffects;
|
||||
}
|
||||
|
||||
const std::list<ActiveEffectDefinition> &EffectEngine::getActiveEffects()
|
||||
{
|
||||
_availableActiveEffects.clear();
|
||||
|
||||
for (Effect * effect : _activeEffects)
|
||||
{
|
||||
ActiveEffectDefinition activeEffectDefinition;
|
||||
activeEffectDefinition.script = effect->getScript();
|
||||
activeEffectDefinition.priority = effect->getPriority();
|
||||
activeEffectDefinition.timeout = effect->getTimeout();
|
||||
activeEffectDefinition.args = effect->getArgs();
|
||||
_availableActiveEffects.push_back(activeEffectDefinition);
|
||||
}
|
||||
|
||||
return _availableActiveEffects;
|
||||
}
|
||||
|
||||
bool EffectEngine::loadEffectDefinition(const std::string &path, const std::string &effectConfigFile, EffectDefinition & effectDefinition)
|
||||
{
|
||||
#ifdef ENABLE_QT5
|
||||
|
|
|
@ -19,6 +19,7 @@ SET(Hyperion_HEADERS
|
|||
|
||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.h
|
||||
${CURRENT_SOURCE_DIR}/MultiColorCorrection.h
|
||||
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.h
|
||||
${CURRENT_HEADER_DIR}/MessageForwarder.h
|
||||
)
|
||||
|
||||
|
@ -32,6 +33,7 @@ SET(Hyperion_SOURCES
|
|||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorCorrection.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.cpp
|
||||
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp
|
||||
${CURRENT_SOURCE_DIR}/MessageForwarder.cpp
|
||||
)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ColorTransform.h>
|
||||
#include <hyperion/ColorCorrection.h>
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
|
||||
// Leddevice includes
|
||||
#include <leddevice/LedDevice.h>
|
||||
|
@ -24,6 +25,7 @@
|
|||
|
||||
#include "MultiColorTransform.h"
|
||||
#include "MultiColorCorrection.h"
|
||||
#include "MultiColorAdjustment.h"
|
||||
#include "LinearColorSmoothing.h"
|
||||
|
||||
// effect engine includes
|
||||
|
@ -101,6 +103,7 @@ ColorTransform * Hyperion::createColorTransform(const Json::Value & transformCon
|
|||
return transform;
|
||||
}
|
||||
|
||||
|
||||
ColorCorrection * Hyperion::createColorCorrection(const Json::Value & correctionConfig)
|
||||
{
|
||||
const std::string id = correctionConfig.get("id", "default").asString();
|
||||
|
@ -117,6 +120,30 @@ ColorCorrection * Hyperion::createColorCorrection(const Json::Value & correction
|
|||
return correction;
|
||||
}
|
||||
|
||||
|
||||
ColorAdjustment * Hyperion::createColorAdjustment(const Json::Value & adjustmentConfig)
|
||||
{
|
||||
const std::string id = adjustmentConfig.get("id", "default").asString();
|
||||
|
||||
RgbChannelAdjustment * redAdjustment = createRgbChannelAdjustment(adjustmentConfig["pureRed"],RED);
|
||||
RgbChannelAdjustment * greenAdjustment = createRgbChannelAdjustment(adjustmentConfig["pureGreen"],GREEN);
|
||||
RgbChannelAdjustment * blueAdjustment = createRgbChannelAdjustment(adjustmentConfig["pureBlue"],BLUE);
|
||||
|
||||
ColorAdjustment * adjustment = new ColorAdjustment();
|
||||
adjustment->_id = id;
|
||||
adjustment->_rgbRedAdjustment = *redAdjustment;
|
||||
adjustment->_rgbGreenAdjustment = *greenAdjustment;
|
||||
adjustment->_rgbBlueAdjustment = *blueAdjustment;
|
||||
|
||||
// Cleanup the allocated individual adjustments
|
||||
delete redAdjustment;
|
||||
delete greenAdjustment;
|
||||
delete blueAdjustment;
|
||||
|
||||
return adjustment;
|
||||
}
|
||||
|
||||
|
||||
MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorConfig)
|
||||
{
|
||||
// Create the result, the transforms are added to this
|
||||
|
@ -206,7 +233,7 @@ MultiColorCorrection * Hyperion::createLedColorsCorrection(const unsigned ledCnt
|
|||
}
|
||||
else if (!correctionConfig.isArray())
|
||||
{
|
||||
ColorCorrection * colorCorrection = createColorCorrection(colorConfig);
|
||||
ColorCorrection * colorCorrection = createColorCorrection(correctionConfig);
|
||||
correction->addCorrection(colorCorrection);
|
||||
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
|
||||
}
|
||||
|
@ -280,7 +307,7 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn
|
|||
}
|
||||
else if (!correctionConfig.isArray())
|
||||
{
|
||||
ColorCorrection * colorCorrection = createColorCorrection(colorConfig);
|
||||
ColorCorrection * colorCorrection = createColorCorrection(correctionConfig);
|
||||
correction->addCorrection(colorCorrection);
|
||||
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
|
||||
}
|
||||
|
@ -339,6 +366,80 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn
|
|||
return correction;
|
||||
}
|
||||
|
||||
MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorConfig)
|
||||
{
|
||||
// Create the result, the transforms are added to this
|
||||
MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt);
|
||||
|
||||
const Json::Value adjustmentConfig = colorConfig.get("channelAdjustment", Json::nullValue);
|
||||
if (adjustmentConfig.isNull())
|
||||
{
|
||||
// Old style color transformation config (just one for all leds)
|
||||
ColorAdjustment * colorAdjustment = createColorAdjustment(colorConfig);
|
||||
adjustment->addAdjustment(colorAdjustment);
|
||||
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
|
||||
}
|
||||
else if (!adjustmentConfig.isArray())
|
||||
{
|
||||
ColorAdjustment * colorAdjustment = createColorAdjustment(adjustmentConfig);
|
||||
adjustment->addAdjustment(colorAdjustment);
|
||||
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
|
||||
|
||||
for (Json::UInt i = 0; i < adjustmentConfig.size(); ++i)
|
||||
{
|
||||
const Json::Value & config = adjustmentConfig[i];
|
||||
ColorAdjustment * colorAdjustment = createColorAdjustment(config);
|
||||
adjustment->addAdjustment(colorAdjustment);
|
||||
|
||||
const QString ledIndicesStr = QString(config.get("leds", "").asCString()).trimmed();
|
||||
if (ledIndicesStr.compare("*") == 0)
|
||||
{
|
||||
// Special case for indices '*' => all leds
|
||||
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
|
||||
std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!overallExp.exactMatch(ledIndicesStr))
|
||||
{
|
||||
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => [";
|
||||
|
||||
const QStringList ledIndexList = ledIndicesStr.split(",");
|
||||
for (int i=0; i<ledIndexList.size(); ++i) {
|
||||
if (i > 0)
|
||||
{
|
||||
std::cout << ", ";
|
||||
}
|
||||
if (ledIndexList[i].contains("-"))
|
||||
{
|
||||
QStringList ledIndices = ledIndexList[i].split("-");
|
||||
int startInd = ledIndices[0].toInt();
|
||||
int endInd = ledIndices[1].toInt();
|
||||
|
||||
adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
|
||||
std::cout << startInd << "-" << endInd;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = ledIndexList[i].toInt();
|
||||
adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
|
||||
std::cout << index;
|
||||
}
|
||||
}
|
||||
std::cout << "]" << std::endl;
|
||||
}
|
||||
}
|
||||
return adjustment;
|
||||
}
|
||||
|
||||
HsvTransform * Hyperion::createHsvTransform(const Json::Value & hsvConfig)
|
||||
{
|
||||
const double saturationGain = hsvConfig.get("saturationGain", 1.0).asDouble();
|
||||
|
@ -376,6 +477,32 @@ RgbChannelCorrection* Hyperion::createRgbChannelCorrection(const Json::Value& co
|
|||
return correction;
|
||||
}
|
||||
|
||||
RgbChannelAdjustment* Hyperion::createRgbChannelAdjustment(const Json::Value& colorConfig, const RgbChannel color)
|
||||
{
|
||||
int varR, varG, varB;
|
||||
if (color == RED)
|
||||
{
|
||||
varR = colorConfig.get("redChannel", 255).asInt();
|
||||
varG = colorConfig.get("greenChannel", 0).asInt();
|
||||
varB = colorConfig.get("blueChannel", 0).asInt();
|
||||
}
|
||||
else if (color == GREEN)
|
||||
{
|
||||
varR = colorConfig.get("redChannel", 0).asInt();
|
||||
varG = colorConfig.get("greenChannel", 255).asInt();
|
||||
varB = colorConfig.get("blueChannel", 0).asInt();
|
||||
}
|
||||
else if (color == BLUE)
|
||||
{
|
||||
varR = colorConfig.get("redChannel", 0).asInt();
|
||||
varG = colorConfig.get("greenChannel", 0).asInt();
|
||||
varB = colorConfig.get("blueChannel", 255).asInt();
|
||||
}
|
||||
|
||||
RgbChannelAdjustment* adjustment = new RgbChannelAdjustment(varR, varG, varB);
|
||||
return adjustment;
|
||||
}
|
||||
|
||||
LedString Hyperion::createLedString(const Json::Value& ledsConfig, const ColorOrder deviceOrder)
|
||||
{
|
||||
LedString ledString;
|
||||
|
@ -490,6 +617,7 @@ MessageForwarder * Hyperion::getForwarder()
|
|||
Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
||||
_ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))),
|
||||
_muxer(_ledString.leds().size()),
|
||||
_raw2ledAdjustment(createLedColorsAdjustment(_ledString.leds().size(), jsonConfig["color"])),
|
||||
_raw2ledCorrection(createLedColorsCorrection(_ledString.leds().size(), jsonConfig["color"])),
|
||||
_raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), jsonConfig["color"])),
|
||||
_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])),
|
||||
|
@ -498,6 +626,10 @@ Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
|||
_messageForwarder(createMessageForwarder(jsonConfig["forwarder"])),
|
||||
_timer()
|
||||
{
|
||||
if (!_raw2ledAdjustment->verifyAdjustments())
|
||||
{
|
||||
throw std::runtime_error("HYPERION ERROR: Color adjustment incorrectly set");
|
||||
}
|
||||
if (!_raw2ledCorrection->verifyCorrections())
|
||||
{
|
||||
throw std::runtime_error("HYPERION ERROR: Color correction incorrectly set");
|
||||
|
@ -551,6 +683,9 @@ Hyperion::~Hyperion()
|
|||
|
||||
// delete the color temperature correction
|
||||
delete _raw2ledTemperature;
|
||||
|
||||
// delete the color adjustment
|
||||
delete _raw2ledAdjustment;
|
||||
|
||||
// delete the message forwarder
|
||||
delete _messageForwarder;
|
||||
|
@ -609,6 +744,11 @@ const std::vector<std::string> & Hyperion::getTemperatureIds() const
|
|||
return _raw2ledTemperature->getCorrectionIds();
|
||||
}
|
||||
|
||||
const std::vector<std::string> & Hyperion::getAdjustmentIds() const
|
||||
{
|
||||
return _raw2ledAdjustment->getAdjustmentIds();
|
||||
}
|
||||
|
||||
ColorTransform * Hyperion::getTransform(const std::string& id)
|
||||
{
|
||||
return _raw2ledTransform->getTransform(id);
|
||||
|
@ -624,6 +764,11 @@ ColorCorrection * Hyperion::getTemperature(const std::string& id)
|
|||
return _raw2ledTemperature->getCorrection(id);
|
||||
}
|
||||
|
||||
ColorAdjustment * Hyperion::getAdjustment(const std::string& id)
|
||||
{
|
||||
return _raw2ledAdjustment->getAdjustment(id);
|
||||
}
|
||||
|
||||
void Hyperion::transformsUpdated()
|
||||
{
|
||||
update();
|
||||
|
@ -639,6 +784,11 @@ void Hyperion::temperaturesUpdated()
|
|||
update();
|
||||
}
|
||||
|
||||
void Hyperion::adjustmentsUpdated()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void Hyperion::clear(int priority)
|
||||
{
|
||||
if (_muxer.hasPriority(priority))
|
||||
|
@ -683,6 +833,11 @@ const std::list<EffectDefinition> & Hyperion::getEffects() const
|
|||
return _effectEngine->getEffects();
|
||||
}
|
||||
|
||||
const std::list<ActiveEffectDefinition> & Hyperion::getActiveEffects()
|
||||
{
|
||||
return _effectEngine->getActiveEffects();
|
||||
}
|
||||
|
||||
int Hyperion::setEffect(const std::string &effectName, int priority, int timeout)
|
||||
{
|
||||
return _effectEngine->runEffect(effectName, priority, timeout);
|
||||
|
@ -703,9 +858,11 @@ void Hyperion::update()
|
|||
const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority);
|
||||
|
||||
// Apply the correction and the transform to each led and color-channel
|
||||
std::vector<ColorRgb> correctedColors = _raw2ledCorrection->applyCorrection(priorityInfo.ledColors);
|
||||
std::vector<ColorRgb> temperatureColors = _raw2ledTemperature->applyCorrection(correctedColors);
|
||||
std::vector<ColorRgb> ledColors =_raw2ledTransform->applyTransform(temperatureColors);
|
||||
// Avoid applying correction, the same task is performed by adjustment
|
||||
// std::vector<ColorRgb> correctedColors = _raw2ledCorrection->applyCorrection(priorityInfo.ledColors);
|
||||
std::vector<ColorRgb> adjustedColors = _raw2ledAdjustment->applyAdjustment(priorityInfo.ledColors);
|
||||
std::vector<ColorRgb> transformColors =_raw2ledTransform->applyTransform(adjustedColors);
|
||||
std::vector<ColorRgb> ledColors = _raw2ledTemperature->applyCorrection(transformColors);
|
||||
const std::vector<Led>& leds = _ledString.leds();
|
||||
int i = 0;
|
||||
for (ColorRgb& color : ledColors)
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
|
||||
// STL includes
|
||||
#include <cassert>
|
||||
|
||||
// Hyperion includes
|
||||
#include "MultiColorAdjustment.h"
|
||||
|
||||
MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt) :
|
||||
_ledAdjustments(ledCnt, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MultiColorAdjustment::~MultiColorAdjustment()
|
||||
{
|
||||
// Clean up all the transforms
|
||||
for (ColorAdjustment * adjustment : _adjustment)
|
||||
{
|
||||
delete adjustment;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiColorAdjustment::addAdjustment(ColorAdjustment * adjustment)
|
||||
{
|
||||
_adjustmentIds.push_back(adjustment->_id);
|
||||
_adjustment.push_back(adjustment);
|
||||
}
|
||||
|
||||
void MultiColorAdjustment::setAdjustmentForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
|
||||
{
|
||||
assert(startLed <= endLed);
|
||||
assert(endLed < _ledAdjustments.size());
|
||||
|
||||
// Get the identified adjustment (don't care if is nullptr)
|
||||
ColorAdjustment * adjustment = getAdjustment(id);
|
||||
for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
|
||||
{
|
||||
_ledAdjustments[iLed] = adjustment;
|
||||
}
|
||||
}
|
||||
|
||||
bool MultiColorAdjustment::verifyAdjustments() const
|
||||
{
|
||||
bool allLedsSet = true;
|
||||
for (unsigned iLed=0; iLed<_ledAdjustments.size(); ++iLed)
|
||||
{
|
||||
if (_ledAdjustments[iLed] == nullptr)
|
||||
{
|
||||
std::cerr << "HYPERION (C.adjustment) ERROR: No adjustment set for " << iLed << std::endl;
|
||||
allLedsSet = false;
|
||||
}
|
||||
}
|
||||
return allLedsSet;
|
||||
}
|
||||
|
||||
const std::vector<std::string> & MultiColorAdjustment::getAdjustmentIds()
|
||||
{
|
||||
return _adjustmentIds;
|
||||
}
|
||||
|
||||
ColorAdjustment* MultiColorAdjustment::getAdjustment(const std::string& id)
|
||||
{
|
||||
// Iterate through the unique adjustments until we find the one with the given id
|
||||
for (ColorAdjustment* adjustment : _adjustment)
|
||||
{
|
||||
if (adjustment->_id == id)
|
||||
{
|
||||
return adjustment;
|
||||
}
|
||||
}
|
||||
|
||||
// The ColorAdjustment was not found
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<ColorRgb>& rawColors)
|
||||
{
|
||||
// Create a copy, as we will do the rest of the adjustment in place
|
||||
std::vector<ColorRgb> ledColors(rawColors);
|
||||
|
||||
const size_t itCnt = std::min(_ledAdjustments.size(), rawColors.size());
|
||||
for (size_t i=0; i<itCnt; ++i)
|
||||
{
|
||||
ColorAdjustment* adjustment = _ledAdjustments[i];
|
||||
if (adjustment == nullptr)
|
||||
{
|
||||
// No transform set for this led (do nothing)
|
||||
continue;
|
||||
}
|
||||
ColorRgb& color = ledColors[i];
|
||||
|
||||
int RR = adjustment->_rgbRedAdjustment.adjustmentR(color.red);
|
||||
int RG = adjustment->_rgbRedAdjustment.adjustmentG(color.red);
|
||||
int RB = adjustment->_rgbRedAdjustment.adjustmentB(color.red);
|
||||
int GR = adjustment->_rgbGreenAdjustment.adjustmentR(color.green);
|
||||
int GG = adjustment->_rgbGreenAdjustment.adjustmentG(color.green);
|
||||
int GB = adjustment->_rgbGreenAdjustment.adjustmentB(color.green);
|
||||
int BR = adjustment->_rgbBlueAdjustment.adjustmentR(color.blue);
|
||||
int BG = adjustment->_rgbBlueAdjustment.adjustmentG(color.blue);
|
||||
int BB = adjustment->_rgbBlueAdjustment.adjustmentB(color.blue);
|
||||
|
||||
int ledR = RR + GR + BR;
|
||||
int maxR = (int)adjustment->_rgbRedAdjustment.getadjustmentR();
|
||||
int ledG = RG + GG + BG;
|
||||
int maxG = (int)adjustment->_rgbGreenAdjustment.getadjustmentG();
|
||||
int ledB = RB + GB + BB;
|
||||
int maxB = (int)adjustment->_rgbBlueAdjustment.getadjustmentB();
|
||||
|
||||
if (ledR > maxR)
|
||||
color.red = (uint8_t)maxR;
|
||||
else
|
||||
color.red = (uint8_t)ledR;
|
||||
|
||||
if (ledG > maxG)
|
||||
color.green = (uint8_t)maxG;
|
||||
else
|
||||
color.green = (uint8_t)ledG;
|
||||
|
||||
if (ledB > maxB)
|
||||
color.blue = (uint8_t)maxB;
|
||||
else
|
||||
color.blue = (uint8_t)ledB;
|
||||
}
|
||||
return ledColors;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
// STL includes
|
||||
#include <vector>
|
||||
|
||||
// Utils includes
|
||||
#include <utils/ColorRgb.h>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
|
||||
///
|
||||
/// The LedColorTransform is responsible for performing color transformation from 'raw' colors
|
||||
/// received as input to colors mapped to match the color-properties of the leds.
|
||||
///
|
||||
class MultiColorAdjustment
|
||||
{
|
||||
public:
|
||||
MultiColorAdjustment(const unsigned ledCnt);
|
||||
~MultiColorAdjustment();
|
||||
|
||||
/**
|
||||
* Adds a new ColorAdjustment to this MultiColorTransform
|
||||
*
|
||||
* @param adjustment The new ColorAdjustment (ownership is transfered)
|
||||
*/
|
||||
void addAdjustment(ColorAdjustment * adjustment);
|
||||
|
||||
void setAdjustmentForLed(const std::string& id, const unsigned startLed, const unsigned endLed);
|
||||
|
||||
bool verifyAdjustments() const;
|
||||
|
||||
///
|
||||
/// Returns the identifier of all the unique ColorAdjustment
|
||||
///
|
||||
/// @return The list with unique id's of the ColorAdjustment
|
||||
const std::vector<std::string> & getAdjustmentIds();
|
||||
|
||||
///
|
||||
/// Returns the pointer to the ColorAdjustment with the given id
|
||||
///
|
||||
/// @param id The identifier of the ColorAdjustment
|
||||
///
|
||||
/// @return The ColorAdjustment with the given id (or nullptr if it does not exist)
|
||||
///
|
||||
ColorAdjustment* getAdjustment(const std::string& id);
|
||||
|
||||
///
|
||||
/// Performs the color adjustment from raw-color to led-color
|
||||
///
|
||||
/// @param rawColors The list with raw colors
|
||||
///
|
||||
/// @return The list with led-colors
|
||||
///
|
||||
std::vector<ColorRgb> applyAdjustment(const std::vector<ColorRgb>& rawColors);
|
||||
|
||||
private:
|
||||
/// List with transform ids
|
||||
std::vector<std::string> _adjustmentIds;
|
||||
|
||||
/// List with unique ColorTransforms
|
||||
std::vector<ColorAdjustment*> _adjustment;
|
||||
|
||||
/// List with a pointer to the ColorAdjustment for each individual led
|
||||
std::vector<ColorAdjustment*> _ledAdjustments;
|
||||
};
|
|
@ -19,6 +19,7 @@
|
|||
#include <hyperion/MessageForwarder.h>
|
||||
#include <hyperion/ColorTransform.h>
|
||||
#include <hyperion/ColorCorrection.h>
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
|
||||
// project includes
|
||||
|
@ -252,6 +253,8 @@ void JsonClientConnection::handleMessage(const std::string &messageString)
|
|||
handleCorrectionCommand(message);
|
||||
else if (command == "temperature")
|
||||
handleTemperatureCommand(message);
|
||||
else if (command == "adjustment")
|
||||
handleAdjustmentCommand(message);
|
||||
else
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
@ -470,6 +473,34 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
|
|||
whitelevel.append(colorTransform->_rgbGreenTransform.getWhitelevel());
|
||||
whitelevel.append(colorTransform->_rgbBlueTransform.getWhitelevel());
|
||||
}
|
||||
|
||||
// collect adjustment information
|
||||
Json::Value & adjustmentArray = info["adjustment"];
|
||||
for (const std::string& adjustmentId : _hyperion->getAdjustmentIds())
|
||||
{
|
||||
const ColorAdjustment * colorAdjustment = _hyperion->getAdjustment(adjustmentId);
|
||||
if (colorAdjustment == nullptr)
|
||||
{
|
||||
std::cerr << "JSONCLIENT ERROR: Incorrect color adjustment id: " << adjustmentId << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
Json::Value & adjustment = adjustmentArray.append(Json::Value());
|
||||
adjustment["id"] = adjustmentId;
|
||||
|
||||
Json::Value & redAdjust = adjustment["redAdjust"];
|
||||
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentR());
|
||||
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentG());
|
||||
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentB());
|
||||
Json::Value & greenAdjust = adjustment["greenAdjust"];
|
||||
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentR());
|
||||
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentG());
|
||||
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentB());
|
||||
Json::Value & blueAdjust = adjustment["blueAdjust"];
|
||||
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentR());
|
||||
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentG());
|
||||
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentB());
|
||||
}
|
||||
|
||||
// collect effect info
|
||||
Json::Value & effects = info["effects"] = Json::Value(Json::arrayValue);
|
||||
|
@ -483,6 +514,20 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
|
|||
|
||||
effects.append(effect);
|
||||
}
|
||||
|
||||
// collect active effect info
|
||||
Json::Value & activeEffects = info["activeEffects"] = Json::Value(Json::arrayValue);
|
||||
const std::list<ActiveEffectDefinition> & activeEffectsDefinitions = _hyperion->getActiveEffects();
|
||||
for (const ActiveEffectDefinition & activeEffectDefinition : activeEffectsDefinitions)
|
||||
{
|
||||
Json::Value activeEffect;
|
||||
activeEffect["script"] = activeEffectDefinition.script;
|
||||
activeEffect["priority"] = activeEffectDefinition.priority;
|
||||
activeEffect["timeout"] = activeEffectDefinition.timeout;
|
||||
activeEffect["args"] = activeEffectDefinition.args;
|
||||
|
||||
activeEffects.append(activeEffect);
|
||||
}
|
||||
|
||||
// send the result
|
||||
sendMessage(result);
|
||||
|
@ -634,6 +679,47 @@ void JsonClientConnection::handleTemperatureCommand(const Json::Value &message)
|
|||
|
||||
sendSuccessReply();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleAdjustmentCommand(const Json::Value &message)
|
||||
{
|
||||
const Json::Value & adjustment = message["adjustment"];
|
||||
|
||||
const std::string adjustmentId = adjustment.get("id", _hyperion->getAdjustmentIds().front()).asString();
|
||||
ColorAdjustment * colorAdjustment = _hyperion->getAdjustment(adjustmentId);
|
||||
if (colorAdjustment == nullptr)
|
||||
{
|
||||
//sendErrorReply(std::string("Incorrect transform identifier: ") + transformId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (adjustment.isMember("redAdjust"))
|
||||
{
|
||||
const Json::Value & values = adjustment["redAdjust"];
|
||||
colorAdjustment->_rgbRedAdjustment.setadjustmentR(values[0u].asInt());
|
||||
colorAdjustment->_rgbRedAdjustment.setadjustmentG(values[1u].asInt());
|
||||
colorAdjustment->_rgbRedAdjustment.setadjustmentB(values[2u].asInt());
|
||||
}
|
||||
|
||||
if (adjustment.isMember("greenAdjust"))
|
||||
{
|
||||
const Json::Value & values = adjustment["greenAdjust"];
|
||||
colorAdjustment->_rgbGreenAdjustment.setadjustmentR(values[0u].asInt());
|
||||
colorAdjustment->_rgbGreenAdjustment.setadjustmentG(values[1u].asInt());
|
||||
colorAdjustment->_rgbGreenAdjustment.setadjustmentB(values[2u].asInt());
|
||||
}
|
||||
|
||||
if (adjustment.isMember("blueAdjust"))
|
||||
{
|
||||
const Json::Value & values = adjustment["blueAdjust"];
|
||||
colorAdjustment->_rgbBlueAdjustment.setadjustmentR(values[0u].asInt());
|
||||
colorAdjustment->_rgbBlueAdjustment.setadjustmentG(values[1u].asInt());
|
||||
colorAdjustment->_rgbBlueAdjustment.setadjustmentB(values[2u].asInt());
|
||||
}
|
||||
// commit the changes
|
||||
_hyperion->adjustmentsUpdated();
|
||||
|
||||
sendSuccessReply();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleNotImplemented()
|
||||
{
|
||||
|
@ -712,7 +798,6 @@ void JsonClientConnection::sendMessage(const Json::Value & message, QTcpSocket *
|
|||
|
||||
}
|
||||
|
||||
|
||||
void JsonClientConnection::sendSuccessReply()
|
||||
{
|
||||
// create reply
|
||||
|
|
|
@ -126,6 +126,13 @@ private:
|
|||
/// @param message the incoming message
|
||||
///
|
||||
void handleTemperatureCommand(const Json::Value & message);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Adjustment message
|
||||
///
|
||||
/// @param message the incoming message
|
||||
///
|
||||
void handleAdjustmentCommand(const Json::Value & message);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON message of unknown type
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<file alias="schema-transform">schema/schema-transform.json</file>
|
||||
<file alias="schema-correction">schema/schema-correction.json</file>
|
||||
<file alias="schema-temperature">schema/schema-temperature.json</file>
|
||||
<file alias="schema-adjustment">schema/schema-adjustment.json</file>
|
||||
<file alias="schema-effect">schema/schema-effect.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["adjustment"]
|
||||
},
|
||||
"adjustment": {
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"id" : {
|
||||
"type" : "string",
|
||||
"required" : false
|
||||
},
|
||||
"redAdjust": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"greenAdjust": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"blueAdjust": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" : {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["color", "image", "effect", "serverinfo", "clear", "clearall", "transform", "correction", "temperature"]
|
||||
"enum" : ["color", "image", "effect", "serverinfo", "clear", "clearall", "transform", "correction", "temperature", "adjustment"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ AtmoOrbLight::AtmoOrbLight(unsigned int id) {
|
|||
// Not implemented
|
||||
}
|
||||
|
||||
LedDeviceAtmoOrb::LedDeviceAtmoOrb(const std::string &output, bool switchOffOnBlack,
|
||||
int transitiontime, int port, int numLeds, std::vector<unsigned int> orbIds) :
|
||||
multicastGroup(output.c_str()), switchOffOnBlack(switchOffOnBlack), transitiontime(transitiontime),
|
||||
LedDeviceAtmoOrb::LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing,
|
||||
int transitiontime, int skipSmoothingDiff, int port, int numLeds, std::vector<unsigned int> orbIds) :
|
||||
multicastGroup(output.c_str()), useOrbSmoothing(useOrbSmoothing), transitiontime(transitiontime), skipSmoothingDiff(skipSmoothingDiff),
|
||||
multiCastGroupPort(port), numLeds(numLeds), orbIds(orbIds) {
|
||||
manager = new QNetworkAccessManager();
|
||||
groupAddress = QHostAddress(multicastGroup);
|
||||
|
@ -35,37 +35,64 @@ int LedDeviceAtmoOrb::write(const std::vector <ColorRgb> &ledValues) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Command options:
|
||||
//
|
||||
// 1 = force off
|
||||
// 2 = use lamp smoothing and validate by Orb ID
|
||||
// 4 = validate by Orb ID
|
||||
|
||||
// When setting useOrbSmoothing = true it's recommended to disable Hyperion's own smoothing as it will conflict (double smoothing)
|
||||
int commandType = 4;
|
||||
if(useOrbSmoothing)
|
||||
{
|
||||
commandType = 2;
|
||||
}
|
||||
|
||||
// Iterate through colors and set Orb color
|
||||
// Start off with idx 1 as 0 is reserved for controlling all orbs at once
|
||||
unsigned int idx = 1;
|
||||
for (const ColorRgb &color : ledValues) {
|
||||
// Options parameter:
|
||||
//
|
||||
// 1 = force off
|
||||
// 2 = use lamp smoothing and validate by Orb ID
|
||||
// 4 = validate by Orb ID
|
||||
//
|
||||
|
||||
if (switchOffOnBlack && color.red == 0 && color.green == 0 && color.blue == 0) {
|
||||
// Force to black
|
||||
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
||||
if (orbIds[i] == idx) {
|
||||
setColor(idx, color, 1);
|
||||
}
|
||||
}
|
||||
for (const ColorRgb &color : ledValues) {
|
||||
// Retrieve last send colors
|
||||
int lastRed = lastColorRedMap[idx];
|
||||
int lastGreen = lastColorGreenMap[idx];
|
||||
int lastBlue = lastColorBlueMap[idx];
|
||||
|
||||
// If last colors send are identical than last send return
|
||||
if(lastRed == color.red && lastGreen == color.green && lastBlue == color.blue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
// Default send color
|
||||
|
||||
// If color difference is higher than skipSmoothingDiff than we skip Orb smoothing (if enabled) and send it right away
|
||||
if ((skipSmoothingDiff != 0 && useOrbSmoothing) && (abs(color.red - lastRed) >= skipSmoothingDiff || abs(color.blue - lastBlue) >= skipSmoothingDiff ||
|
||||
abs(color.green - lastGreen) >= skipSmoothingDiff))
|
||||
{
|
||||
// Skip Orb smoothing when using (command type 4)
|
||||
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
||||
if (orbIds[i] == idx) {
|
||||
setColor(idx, color, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Send color
|
||||
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
||||
if (orbIds[i] == idx) {
|
||||
setColor(idx, color, commandType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store last colors send for light id
|
||||
lastColorRedMap[idx] = color.red;
|
||||
lastColorGreenMap[idx] = color.green;
|
||||
lastColorBlueMap[idx] = color.blue;
|
||||
|
||||
// Next light id.
|
||||
idx++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -80,7 +107,7 @@ void LedDeviceAtmoOrb::setColor(unsigned int orbId, const ColorRgb &color, int c
|
|||
bytes[2] = 0xEE;
|
||||
|
||||
// Command type
|
||||
bytes[3] = 2;
|
||||
bytes[3] = commandType;
|
||||
|
||||
// Orb ID
|
||||
bytes[4] = orbId;
|
||||
|
|
|
@ -35,10 +35,10 @@ public:
|
|||
class LedDeviceAtmoOrb : public QObject, public LedDevice {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Last color sent
|
||||
int lastRed;
|
||||
int lastGreen;
|
||||
int lastBlue;
|
||||
// Last send color map
|
||||
QMap<int, int> lastColorRedMap;
|
||||
QMap<int, int> lastColorGreenMap;
|
||||
QMap<int, int> lastColorBlueMap;
|
||||
|
||||
// Multicast status
|
||||
bool joinedMulticastgroup;
|
||||
|
@ -48,21 +48,21 @@ public:
|
|||
///
|
||||
/// @param output is the multicast address of Orbs
|
||||
///
|
||||
/// @param switchOffOnBlack turn off Orbs on black (default: false)
|
||||
///
|
||||
/// @param transitiontime is optional and not used at the moment
|
||||
///
|
||||
/// @param useOrbSmoothing use Orbs own (external) smoothing algorithm (default: false)
|
||||
///
|
||||
/// @param skipSmoothingDiff minimal color (0-255) difference to override smoothing so that if current and previously received colors are higher than set dif we override smoothing
|
||||
///
|
||||
/// @param port is the multicast port.
|
||||
///
|
||||
/// @param numLeds is the total amount of leds per Orb
|
||||
///
|
||||
/// @param array containing orb ids
|
||||
///
|
||||
LedDeviceAtmoOrb(const std::string &output, bool switchOffOnBlack =
|
||||
false, int transitiontime = 0, int port = 49692, int numLeds = 24,
|
||||
std::vector<unsigned int> orbIds = std::vector < unsigned int
|
||||
|
||||
>());
|
||||
LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing =
|
||||
false, int transitiontime = 0, int skipSmoothingDiff = 0, int port = 49692, int numLeds = 24,
|
||||
std::vector<unsigned int> orbIds = std::vector < unsigned int>());
|
||||
|
||||
///
|
||||
/// Destructor of this device
|
||||
|
@ -87,12 +87,15 @@ private:
|
|||
/// String containing multicast group IP address
|
||||
QString multicastGroup;
|
||||
|
||||
/// Switch off when detecting black
|
||||
bool switchOffOnBlack;
|
||||
/// use Orbs own (external) smoothing algorithm
|
||||
bool useOrbSmoothing;
|
||||
|
||||
/// Transition time between colors (not implemented)
|
||||
int transitiontime;
|
||||
|
||||
// Maximum allowed color difference, will skip Orb (external) smoothing once reached
|
||||
int skipSmoothingDiff;
|
||||
|
||||
/// Multicast port to send data to
|
||||
int multiCastGroupPort;
|
||||
|
||||
|
@ -126,4 +129,4 @@ private:
|
|||
/// @param bytes the byte array containing command to send over multicast
|
||||
///
|
||||
void sendCommand(const QByteArray &bytes);
|
||||
};
|
||||
};
|
|
@ -206,11 +206,21 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
|||
{
|
||||
const std::string output = deviceConfig.get("output", "").asString();
|
||||
const std::string assignment = deviceConfig.get("assignment", "").asString();
|
||||
const Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue);
|
||||
|
||||
LedDevicePiBlaster * devicePiBlaster = new LedDevicePiBlaster(output, assignment);
|
||||
devicePiBlaster->open();
|
||||
if (assignment.length() > 0) {
|
||||
std::cout << "ERROR: Sorry, the configuration syntax has changed in this version." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (! gpioMapping.isNull() ) {
|
||||
LedDevicePiBlaster * devicePiBlaster = new LedDevicePiBlaster(output, gpioMapping);
|
||||
devicePiBlaster->open();
|
||||
|
||||
device = devicePiBlaster;
|
||||
device = devicePiBlaster;
|
||||
} else {
|
||||
std::cout << "ERROR: no gpiomap defined." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (type == "sedu")
|
||||
{
|
||||
|
@ -246,35 +256,36 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
|||
}
|
||||
device = new LedDevicePhilipsHue(output, username, switchOffOnBlack, transitiontime, lightIds);
|
||||
}
|
||||
else if (type == "atmoorb")
|
||||
{
|
||||
else if (type == "atmoorb")
|
||||
{
|
||||
const std::string output = deviceConfig["output"].asString();
|
||||
const bool switchOffOnBlack = deviceConfig.get("switchOffOnBlack", true).asBool();
|
||||
const bool useOrbSmoothing = deviceConfig.get("useOrbSmoothing", false).asBool();
|
||||
const int transitiontime = deviceConfig.get("transitiontime", 1).asInt();
|
||||
const int skipSmoothingDiff = deviceConfig.get("skipSmoothingDiff", 0).asInt();
|
||||
const int port = deviceConfig.get("port", 1).asInt();
|
||||
const int numLeds = deviceConfig.get("numLeds", 1).asInt();
|
||||
const std::string orbId = deviceConfig["orbIds"].asString();
|
||||
const std::string orbId = deviceConfig["orbIds"].asString();
|
||||
std::vector<unsigned int> orbIds;
|
||||
|
||||
// If we find multiple Orb ids separate them and add to list
|
||||
const std::string separator (",");
|
||||
if (orbId.find(separator) != std::string::npos) {
|
||||
std::stringstream ss(orbId);
|
||||
std::vector<int> output;
|
||||
unsigned int i;
|
||||
while (ss >> i) {
|
||||
orbIds.push_back(i);
|
||||
if (ss.peek() == ',' || ss.peek() == ' ')
|
||||
ss.ignore();
|
||||
}
|
||||
std::stringstream ss(orbId);
|
||||
std::vector<int> output;
|
||||
unsigned int i;
|
||||
while (ss >> i) {
|
||||
orbIds.push_back(i);
|
||||
if (ss.peek() == ',' || ss.peek() == ' ')
|
||||
ss.ignore();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
orbIds.push_back(atoi(orbId.c_str()));
|
||||
orbIds.push_back(atoi(orbId.c_str()));
|
||||
}
|
||||
|
||||
device = new LedDeviceAtmoOrb(output, switchOffOnBlack, transitiontime, port, numLeds, orbIds);
|
||||
}
|
||||
device = new LedDeviceAtmoOrb(output, useOrbSmoothing, transitiontime, skipSmoothingDiff, port, numLeds, orbIds);
|
||||
}
|
||||
else if (type == "file")
|
||||
{
|
||||
const std::string output = deviceConfig.get("output", "/dev/null").asString();
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
// STL includes
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <csignal>
|
||||
|
||||
|
||||
// jsoncpp includes
|
||||
#include <json/json.h>
|
||||
|
||||
// QT includes
|
||||
#include <QFile>
|
||||
|
@ -9,12 +14,40 @@
|
|||
// Local LedDevice includes
|
||||
#include "LedDevicePiBlaster.h"
|
||||
|
||||
LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const std::string & channelAssignment) :
|
||||
LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const Json::Value & gpioMapping) :
|
||||
_deviceName(deviceName),
|
||||
_channelAssignment(channelAssignment),
|
||||
_fid(nullptr)
|
||||
{
|
||||
// empty
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
// initialise the mapping tables
|
||||
// -1 is invalid
|
||||
// z is also meaningless
|
||||
// { "gpio" : 4, "ledindex" : 0, "ledcolor" : "r" },
|
||||
#define TABLE_SZ sizeof(_gpio_to_led)/sizeof(_gpio_to_led[0])
|
||||
|
||||
for (int i=0; i < TABLE_SZ; i++ )
|
||||
{
|
||||
_gpio_to_led[i] = -1;
|
||||
_gpio_to_color[i] = 'z';
|
||||
}
|
||||
|
||||
// walk through the json config and populate the mapping tables
|
||||
for (const Json::Value& gpioMap : gpioMapping)
|
||||
{
|
||||
const int gpio = gpioMap.get("gpio",-1).asInt();
|
||||
const int ledindex = gpioMap.get("ledindex",-1).asInt();
|
||||
const std::string ledcolor = gpioMap.get("ledcolor","z").asString();
|
||||
// printf ("got gpio %d ledindex %d color %c\n", gpio,ledindex, ledcolor[0]);
|
||||
// ignore missing/invalid settings
|
||||
if ( (gpio >= 0) && (gpio < TABLE_SZ) && (ledindex >= 0) ){
|
||||
_gpio_to_led[gpio] = ledindex;
|
||||
_gpio_to_color[gpio] = ledcolor[0]; // 1st char of string
|
||||
} else {
|
||||
printf ("IGNORING gpio %d ledindex %d color %c\n", gpio,ledindex, ledcolor[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LedDevicePiBlaster::~LedDevicePiBlaster()
|
||||
|
@ -63,15 +96,6 @@ int LedDevicePiBlaster::open(bool report)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//Channel number GPIO number Pin in P1 header
|
||||
// 0 4 P1-7
|
||||
// 1 17 P1-11
|
||||
// 2 18 P1-12
|
||||
// 3 21 P1-13
|
||||
// 4 22 P1-15
|
||||
// 5 23 P1-16
|
||||
// 6 24 P1-18
|
||||
// 7 25 P1-22
|
||||
int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
|
||||
{
|
||||
// Attempt to open if not yet opened
|
||||
|
@ -80,32 +104,47 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::vector<int> iPins = {4, 17, 18, 27, 21, 22, 23, 24, 25};
|
||||
|
||||
unsigned colorIdx = 0;
|
||||
for (unsigned iPin=0; iPin<iPins.size(); ++iPin)
|
||||
int valueIdx = -1;
|
||||
for (unsigned int i=0; i < TABLE_SZ; i++ )
|
||||
{
|
||||
double pwmDutyCycle = 0.0;
|
||||
switch (_channelAssignment[iPin])
|
||||
valueIdx = _gpio_to_led[ i ];
|
||||
if ( (valueIdx >= 0) && (valueIdx < (signed) ledValues.size()) )
|
||||
{
|
||||
case 'r':
|
||||
pwmDutyCycle = ledValues[colorIdx].red / 255.0;
|
||||
++colorIdx;
|
||||
break;
|
||||
case 'g':
|
||||
pwmDutyCycle = ledValues[colorIdx].green / 255.0;
|
||||
++colorIdx;
|
||||
break;
|
||||
case 'b':
|
||||
pwmDutyCycle = ledValues[colorIdx].blue / 255.0;
|
||||
++colorIdx;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
double pwmDutyCycle = 0.0;
|
||||
// printf ("iPin %d valueIdx %d color %c\n", iPin, valueIdx, _gpio_to_color[ iPins[iPin] ] ) ;
|
||||
switch (_gpio_to_color[ i ])
|
||||
{
|
||||
case 'r':
|
||||
pwmDutyCycle = ledValues[valueIdx].red / 255.0;
|
||||
break;
|
||||
case 'g':
|
||||
pwmDutyCycle = ledValues[valueIdx].green / 255.0;
|
||||
break;
|
||||
case 'b':
|
||||
pwmDutyCycle = ledValues[valueIdx].blue / 255.0;
|
||||
break;
|
||||
case 'w':
|
||||
pwmDutyCycle = ledValues[valueIdx].red;
|
||||
pwmDutyCycle += ledValues[valueIdx].green;
|
||||
pwmDutyCycle += ledValues[valueIdx].blue;
|
||||
pwmDutyCycle /= (3.0*255.0);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(_fid, "%i=%f\n", iPins[iPin], pwmDutyCycle);
|
||||
fflush(_fid);
|
||||
// fprintf(_fid, "%i=%f\n", iPins[iPin], pwmDutyCycle);
|
||||
|
||||
if ( (fprintf(_fid, "%i=%f\n", i, pwmDutyCycle) < 0)
|
||||
|| (fflush(_fid) < 0)) {
|
||||
if (_fid != nullptr)
|
||||
{
|
||||
fclose(_fid);
|
||||
_fid = nullptr;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -119,13 +158,13 @@ int LedDevicePiBlaster::switchOff()
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::vector<int> iPins = {4, 17, 18, 21, 22, 23, 24, 25};
|
||||
|
||||
for (unsigned iPin=0; iPin<iPins.size(); ++iPin)
|
||||
int valueIdx = -1;
|
||||
for (unsigned int i=0; i < TABLE_SZ; i++ )
|
||||
{
|
||||
if (_channelAssignment[iPin] != ' ')
|
||||
valueIdx = _gpio_to_led[ i ];
|
||||
if (valueIdx >= 0)
|
||||
{
|
||||
fprintf(_fid, "%i=%f\n", iPins[iPin], 0.0);
|
||||
fprintf(_fid, "%i=%f\n", i, 0.0);
|
||||
fflush(_fid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
// STL includes
|
||||
#include <cstdio>
|
||||
|
||||
// jsoncpp includes
|
||||
#include <json/json.h>
|
||||
|
||||
// Hyperion-Leddevice includes
|
||||
#include <leddevice/LedDevice.h>
|
||||
|
||||
|
@ -14,9 +17,9 @@ public:
|
|||
/// Constructs the PiBlaster device which writes to the indicated device and for the assigned
|
||||
/// channels
|
||||
/// @param deviceName The name of the output device
|
||||
/// @param channelAssignment The RGB-Channel assignment (8 characters long)
|
||||
/// @param gpioMapping The RGB-Channel assignment json object
|
||||
///
|
||||
LedDevicePiBlaster(const std::string & deviceName, const std::string & channelAssignment);
|
||||
LedDevicePiBlaster(const std::string & deviceName, const Json::Value & gpioMapping);
|
||||
|
||||
virtual ~LedDevicePiBlaster();
|
||||
|
||||
|
@ -50,9 +53,8 @@ private:
|
|||
/// The name of the output device (very likely '/dev/pi-blaster')
|
||||
const std::string _deviceName;
|
||||
|
||||
/// String with eight characters with the rgb-channel assignment per pwm-channel
|
||||
/// ('r' = red, 'g' = green, 'b' = blue, ' ' = empty)
|
||||
const std::string _channelAssignment;
|
||||
int _gpio_to_led[64];
|
||||
char _gpio_to_color[64];
|
||||
|
||||
/// File-Pointer to the PiBlaster device
|
||||
FILE * _fid;
|
||||
|
|
|
@ -29,6 +29,8 @@ add_library(hyperion-utils
|
|||
${CURRENT_SOURCE_DIR}/RgbChannelTransform.cpp
|
||||
${CURRENT_HEADER_DIR}/RgbChannelCorrection.h
|
||||
${CURRENT_SOURCE_DIR}/RgbChannelCorrection.cpp
|
||||
${CURRENT_HEADER_DIR}/RgbChannelAdjustment.h
|
||||
${CURRENT_SOURCE_DIR}/RgbChannelAdjustment.cpp
|
||||
|
||||
${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h
|
||||
${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
// STL includes
|
||||
#include <cmath>
|
||||
|
||||
// Utils includes
|
||||
#include <utils/RgbChannelAdjustment.h>
|
||||
|
||||
RgbChannelAdjustment::RgbChannelAdjustment() :
|
||||
_adjustR(255),
|
||||
_adjustG(255),
|
||||
_adjustB(255)
|
||||
{
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
RgbChannelAdjustment::RgbChannelAdjustment(int adjustR, int adjustG, int adjustB) :
|
||||
_adjustR(adjustR),
|
||||
_adjustG(adjustG),
|
||||
_adjustB(adjustB)
|
||||
{
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
RgbChannelAdjustment::~RgbChannelAdjustment()
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t RgbChannelAdjustment::getadjustmentR() const
|
||||
{
|
||||
return _adjustR;
|
||||
}
|
||||
|
||||
void RgbChannelAdjustment::setadjustmentR(uint8_t adjustR)
|
||||
{
|
||||
_adjustR = adjustR;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
uint8_t RgbChannelAdjustment::getadjustmentG() const
|
||||
{
|
||||
return _adjustG;
|
||||
}
|
||||
|
||||
void RgbChannelAdjustment::setadjustmentG(uint8_t adjustG)
|
||||
{
|
||||
_adjustG = adjustG;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
uint8_t RgbChannelAdjustment::getadjustmentB() const
|
||||
{
|
||||
return _adjustB;
|
||||
}
|
||||
|
||||
void RgbChannelAdjustment::setadjustmentB(uint8_t adjustB)
|
||||
{
|
||||
_adjustB = adjustB;
|
||||
initializeMapping();
|
||||
}
|
||||
|
||||
uint8_t RgbChannelAdjustment::adjustmentR(uint8_t inputR) const
|
||||
{
|
||||
return _mappingR[inputR];
|
||||
}
|
||||
|
||||
uint8_t RgbChannelAdjustment::adjustmentG(uint8_t inputG) const
|
||||
{
|
||||
return _mappingG[inputG];
|
||||
}
|
||||
|
||||
uint8_t RgbChannelAdjustment::adjustmentB(uint8_t inputB) const
|
||||
{
|
||||
return _mappingB[inputB];
|
||||
}
|
||||
|
||||
void RgbChannelAdjustment::initializeMapping()
|
||||
{
|
||||
// initialize the mapping
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
int outputR = (i * _adjustR) / 255;
|
||||
if (outputR > 255)
|
||||
{
|
||||
outputR = 255;
|
||||
}
|
||||
_mappingR[i] = outputR;
|
||||
}
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
int outputG = (i * _adjustG) / 255;
|
||||
if (outputG > 255)
|
||||
{
|
||||
outputG = 255;
|
||||
}
|
||||
_mappingG[i] = outputG;
|
||||
}
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
int outputB = (i * _adjustB) / 255;
|
||||
if (outputB > 255)
|
||||
{
|
||||
outputB = 255;
|
||||
}
|
||||
_mappingB[i] = outputB;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
/// Simple structure to contain the values of a color transformation
|
||||
struct ColorAdjustmentValues
|
||||
{
|
||||
/// The value for the red color-channel
|
||||
int valueRed;
|
||||
/// The value for the green color-channel
|
||||
int valueGreen;
|
||||
/// The value for the blue color-channel
|
||||
int valueBlue;
|
||||
};
|
|
@ -13,6 +13,7 @@
|
|||
// hyperion-remote includes
|
||||
#include "ColorTransformValues.h"
|
||||
#include "ColorCorrectionValues.h"
|
||||
#include "ColorAdjustmentValues.h"
|
||||
|
||||
/// Data parameter for a color
|
||||
typedef vlofgren::PODParameter<std::vector<QColor>> ColorParameter;
|
||||
|
@ -26,6 +27,9 @@ typedef vlofgren::PODParameter<ColorTransformValues> TransformParameter;
|
|||
/// Data parameter for color correction values (list of three values)
|
||||
typedef vlofgren::PODParameter<ColorCorrectionValues> CorrectionParameter;
|
||||
|
||||
/// Data parameter for color correction values (list of three values)
|
||||
typedef vlofgren::PODParameter<ColorAdjustmentValues> AdjustmentParameter;
|
||||
|
||||
namespace vlofgren {
|
||||
///
|
||||
/// Translates a string (as passed on the commandline) to a vector of colors
|
||||
|
@ -161,4 +165,33 @@ namespace vlofgren {
|
|||
|
||||
return correction;
|
||||
}
|
||||
|
||||
template<>
|
||||
ColorAdjustmentValues AdjustmentParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||
{
|
||||
ColorAdjustmentValues adjustment;
|
||||
|
||||
// s should be split in 3 parts
|
||||
// seperators are either a ',' or a space
|
||||
QStringList components = QString(s.c_str()).split(" ", QString::SkipEmptyParts);
|
||||
|
||||
if (components.size() == 3)
|
||||
{
|
||||
bool ok1, ok2, ok3;
|
||||
adjustment.valueRed = components[0].toInt(&ok1);
|
||||
adjustment.valueGreen = components[1].toInt(&ok2);
|
||||
adjustment.valueBlue = components[2].toInt(&ok3);
|
||||
|
||||
if (ok1 && ok2 && ok3)
|
||||
{
|
||||
return adjustment;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream errorMessage;
|
||||
errorMessage << "Argument " << s << " can not be parsed to 3 integer values";
|
||||
throw Parameter::ParameterRejected(errorMessage.str());
|
||||
|
||||
return adjustment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -322,6 +322,51 @@ void JsonConnection::setTemperature(std::string * temperatureId, ColorCorrection
|
|||
parseReply(reply);
|
||||
}
|
||||
|
||||
void JsonConnection::setAdjustment(std::string * adjustmentId, ColorAdjustmentValues * redAdjustment, ColorAdjustmentValues * greenAdjustment, ColorAdjustmentValues * blueAdjustment)
|
||||
{
|
||||
std::cout << "Set color adjustments" << std::endl;
|
||||
|
||||
// create command
|
||||
Json::Value command;
|
||||
command["command"] = "adjustment";
|
||||
Json::Value & adjust = command["adjustment"];
|
||||
|
||||
if (adjustmentId != nullptr)
|
||||
{
|
||||
adjust["id"] = *adjustmentId;
|
||||
}
|
||||
|
||||
if (redAdjustment != nullptr)
|
||||
{
|
||||
Json::Value & v = adjust["redAdjust"];
|
||||
v.append(redAdjustment->valueRed);
|
||||
v.append(redAdjustment->valueGreen);
|
||||
v.append(redAdjustment->valueBlue);
|
||||
}
|
||||
|
||||
if (greenAdjustment != nullptr)
|
||||
{
|
||||
Json::Value & v = adjust["greenAdjust"];
|
||||
v.append(greenAdjustment->valueRed);
|
||||
v.append(greenAdjustment->valueGreen);
|
||||
v.append(greenAdjustment->valueBlue);
|
||||
}
|
||||
|
||||
if (blueAdjustment != nullptr)
|
||||
{
|
||||
Json::Value & v = adjust["blueAdjust"];
|
||||
v.append(blueAdjustment->valueRed);
|
||||
v.append(blueAdjustment->valueGreen);
|
||||
v.append(blueAdjustment->valueBlue);
|
||||
}
|
||||
|
||||
// send command message
|
||||
Json::Value reply = sendMessage(command);
|
||||
|
||||
// parse reply message
|
||||
parseReply(reply);
|
||||
}
|
||||
|
||||
Json::Value JsonConnection::sendMessage(const Json::Value & message)
|
||||
{
|
||||
// serialize message (FastWriter already appends a newline)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
// hyperion-remote includes
|
||||
#include "ColorTransformValues.h"
|
||||
#include "ColorCorrectionValues.h"
|
||||
#include "ColorAdjustmentValues.h"
|
||||
|
||||
///
|
||||
/// Connection class to setup an connection to the hyperion server and execute commands
|
||||
|
@ -130,6 +131,21 @@ public:
|
|||
std::string * temperatureId,
|
||||
ColorCorrectionValues * temperature);
|
||||
|
||||
///
|
||||
/// Set the color adjustment of the leds
|
||||
///
|
||||
/// @note Note that providing a NULL will leave the settings on the server unchanged
|
||||
///
|
||||
/// @param adjustmentId The identifier of the correction to set
|
||||
/// @param redAdjustment The red channel adjustment values
|
||||
/// @param greenAdjustment The green channel adjustment values
|
||||
/// @param blueAdjustment The blue channel adjustment values
|
||||
void setAdjustment(
|
||||
std::string * adjustmentId,
|
||||
ColorAdjustmentValues * redAdjustment,
|
||||
ColorAdjustmentValues * greenAdjustment,
|
||||
ColorAdjustmentValues * blueAdjustment);
|
||||
|
||||
private:
|
||||
///
|
||||
/// Send a json command message and receive its reply
|
||||
|
|
|
@ -63,24 +63,28 @@ int main(int argc, char * argv[])
|
|||
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
|
||||
StringParameter & argEffect = parameters.add<StringParameter> ('e', "effect" , "Enable the effect with the given name");
|
||||
StringParameter & argEffectArgs = parameters.add<StringParameter> (0x0, "effectArgs", "Arguments to use in combination with the specified effect. Should be a Json object string.");
|
||||
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "List server info");
|
||||
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "List server info and active effects with priority and duration");
|
||||
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
|
||||
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clearall" , "Clear data for all active priority channels");
|
||||
StringParameter & argId = parameters.add<StringParameter> ('q', "qualifier" , "Identifier(qualifier) of the transform to set");
|
||||
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "Set the HSV saturation gain of the leds");
|
||||
DoubleParameter & argValue = parameters.add<DoubleParameter> ('v', "value" , "Set the HSV value gain of the leds");
|
||||
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "!DEPRECATED! Will be removed soon! Set the HSV saturation gain of the leds");
|
||||
DoubleParameter & argValue = parameters.add<DoubleParameter> ('v', "value" , "!DEPRECATED! Will be removed soon! Set the HSV value gain of the leds");
|
||||
DoubleParameter & argSaturationL = parameters.add<DoubleParameter> ('u', "saturationL", "Set the HSL saturation gain of the leds");
|
||||
DoubleParameter & argLuminance = parameters.add<DoubleParameter> ('m', "luminance" , "Set the HSL luminance gain of the leds");
|
||||
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)");
|
||||
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
|
||||
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||
TransformParameter & argWhitelevel = parameters.add<TransformParameter>('w', "whitelevel", "Set the whitelevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "!DEPRECATED! Will be removed soon! Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||
TransformParameter & argWhitelevel = parameters.add<TransformParameter>('w', "whitelevel", "!DEPRECATED! Will be removed soon! Set the whitelevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||
SwitchParameter<> & argPrint = parameters.add<SwitchParameter<> >(0x0, "print" , "Print the json input and output messages on stdout");
|
||||
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> >('h', "help" , "Show this help message and exit");
|
||||
StringParameter & argIdC = parameters.add<StringParameter> ('y', "qualifier" , "Identifier(qualifier) of the correction to set");
|
||||
CorrectionParameter & argCorrection = parameters.add<CorrectionParameter>('Y', "correction" , "Set the correction of the leds (requires 3 space seperated values between 0 and 255)");
|
||||
StringParameter & argIdC = parameters.add<StringParameter> ('y', "qualifier" , "!DEPRECATED! Will be removed soon! Identifier(qualifier) of the correction to set");
|
||||
CorrectionParameter & argCorrection = parameters.add<CorrectionParameter>('Y', "correction" , "!DEPRECATED! Will be removed soon! Set the correction of the leds (requires 3 space seperated values between 0 and 255)");
|
||||
StringParameter & argIdT = parameters.add<StringParameter> ('z', "qualifier" , "Identifier(qualifier) of the temperature correction to set");
|
||||
CorrectionParameter & argTemperature = parameters.add<CorrectionParameter>('Z', "temperature" , "Set the temperature correction of the leds (requires 3 space seperated values between 0 and 255)");
|
||||
StringParameter & argIdA = parameters.add<StringParameter> ('j', "qualifier" , "Identifier(qualifier) of the adjustment to set");
|
||||
AdjustmentParameter & argRAdjust = parameters.add<AdjustmentParameter>('R', "redAdjustment" , "Set the adjustment of the red color (requires 3 space seperated values between 0 and 255)");
|
||||
AdjustmentParameter & argGAdjust = parameters.add<AdjustmentParameter>('G', "greenAdjustment", "Set the adjustment of the green color (requires 3 space seperated values between 0 and 255)");
|
||||
AdjustmentParameter & argBAdjust = parameters.add<AdjustmentParameter>('B', "blueAdjustment", "Set the adjustment of the blue color (requires 3 space seperated values between 0 and 255)");
|
||||
|
||||
// set the default values
|
||||
argAddress.setDefault(defaultServerAddress.toStdString());
|
||||
|
@ -100,10 +104,11 @@ int main(int argc, char * argv[])
|
|||
|
||||
// check if at least one of the available color transforms is set
|
||||
bool colorTransform = argSaturation.isSet() || argValue.isSet() || argSaturationL.isSet() || argLuminance.isSet() || argThreshold.isSet() || argGamma.isSet() || argBlacklevel.isSet() || argWhitelevel.isSet();
|
||||
bool colorModding = colorTransform || argCorrection.isSet() || argTemperature.isSet();
|
||||
bool colorAdjust = argRAdjust.isSet() || argGAdjust.isSet() || argBAdjust.isSet();
|
||||
bool colorModding = colorTransform || colorAdjust || argCorrection.isSet() || argTemperature.isSet();
|
||||
|
||||
// check that exactly one command was given
|
||||
int commandCount = count({argColor.isSet(), argImage.isSet(), argEffect.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), colorModding});
|
||||
int commandCount = count({argColor.isSet(), argImage.isSet(), argEffect.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), colorModding});
|
||||
if (commandCount != 1)
|
||||
{
|
||||
std::cerr << (commandCount == 0 ? "No command found." : "Multiple commands found.") << " Provide exactly one of the following options:" << std::endl;
|
||||
|
@ -127,6 +132,10 @@ int main(int argc, char * argv[])
|
|||
std::cerr << " " << argCorrection.usageLine() << std::endl;
|
||||
std::cerr << " " << argIdT.usageLine() << std::endl;
|
||||
std::cerr << " " << argTemperature.usageLine() << std::endl;
|
||||
std::cerr << " " << argIdA.usageLine() << std::endl;
|
||||
std::cerr << " " << argRAdjust.usageLine() << std::endl;
|
||||
std::cerr << " " << argGAdjust.usageLine() << std::endl;
|
||||
std::cerr << " " << argBAdjust.usageLine() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -186,6 +195,24 @@ int main(int argc, char * argv[])
|
|||
argIdT.isSet() ? &tempId : nullptr,
|
||||
argTemperature.isSet() ? &temperature : nullptr);
|
||||
}
|
||||
|
||||
if (colorAdjust)
|
||||
{
|
||||
std::string adjustId;
|
||||
ColorAdjustmentValues redChannel, greenChannel, blueChannel;
|
||||
|
||||
if (argIdA.isSet()) adjustId = argIdA.getValue();
|
||||
if (argRAdjust.isSet()) redChannel = argRAdjust.getValue();
|
||||
if (argGAdjust.isSet()) greenChannel = argGAdjust.getValue();
|
||||
if (argBAdjust.isSet()) blueChannel = argBAdjust.getValue();
|
||||
|
||||
connection.setAdjustment(
|
||||
argIdA.isSet() ? &adjustId : nullptr,
|
||||
argRAdjust.isSet() ? &redChannel : nullptr,
|
||||
argGAdjust.isSet() ? &greenChannel : nullptr,
|
||||
argBAdjust.isSet() ? &blueChannel : nullptr);
|
||||
|
||||
}
|
||||
if (colorTransform)
|
||||
{
|
||||
std::string transId;
|
||||
|
|
Loading…
Reference in New Issue