mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	even more changes
Signed-off-by: Paulchen-Panther <Paulchen--Panter@gmx.net>
This commit is contained in:
		| @@ -23,6 +23,7 @@ SET ( DEFAULT_X11        OFF ) | |||||||
| SET ( DEFAULT_WS281XPWM  OFF ) | SET ( DEFAULT_WS281XPWM  OFF ) | ||||||
| SET ( DEFAULT_USE_SHARED_AVAHI_LIBS  ON ) | SET ( DEFAULT_USE_SHARED_AVAHI_LIBS  ON ) | ||||||
| SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF ) | SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF ) | ||||||
|  | SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF ) | ||||||
| SET ( DEFAULT_TESTS      OFF ) | SET ( DEFAULT_TESTS      OFF ) | ||||||
|  |  | ||||||
| IF ( ${CMAKE_SYSTEM} MATCHES "Linux" ) | IF ( ${CMAKE_SYSTEM} MATCHES "Linux" ) | ||||||
| @@ -163,6 +164,9 @@ message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}") | |||||||
| SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto ) | SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto ) | ||||||
| SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto ) | SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto ) | ||||||
|  |  | ||||||
|  | SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf ) | ||||||
|  | SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf ) | ||||||
|  |  | ||||||
| # check all  json files | # check all  json files | ||||||
| FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json ) | FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json ) | ||||||
| SET( JSON_FILES | SET( JSON_FILES | ||||||
| @@ -246,7 +250,7 @@ if (UNIX AND NOT APPLE) | |||||||
| endif () | endif () | ||||||
|  |  | ||||||
| # add QT5 dependency | # add QT5 dependency | ||||||
| SET(QT_MIN_VERSION "5.2.0") | SET(QT_MIN_VERSION "5.5.0") | ||||||
| find_package(Qt5 COMPONENTS Core Gui Network SerialPort REQUIRED) | find_package(Qt5 COMPONENTS Core Gui Network SerialPort REQUIRED) | ||||||
| message( STATUS "Found Qt Version: ${Qt5Core_VERSION}" ) | message( STATUS "Found Qt Version: ${Qt5Core_VERSION}" ) | ||||||
| IF ( "${Qt5Core_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" ) | IF ( "${Qt5Core_VERSION}" VERSION_LESS "${QT_MIN_VERSION}" ) | ||||||
|   | |||||||
| @@ -6,24 +6,13 @@ | |||||||
| sudo apt-get update | sudo apt-get update | ||||||
| sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev | sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev | ||||||
| ``` | ``` | ||||||
| ### Ubuntu 14.04 specific |  | ||||||
| You need a newer version of cmake (minimum 3.0.0). Install it from the ppa or website |  | ||||||
| ``` |  | ||||||
| sudo apt-get install software-properties-common |  | ||||||
| sudo add-apt-repository ppa:george-edison55/cmake-3.x |  | ||||||
| sudo apt-get update && sudo apt-get upgrade |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| **on RPI you need the videocore IV headers** | **on RPI you need the videocore IV headers** | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
| sudo apt-get install libraspberrypi-dev | sudo apt-get install libraspberrypi-dev | ||||||
| ``` | ``` | ||||||
| **OSMC** |  | ||||||
| libraspberrypi-dev is not available, use this instead |  | ||||||
| ``` |  | ||||||
| sudo apt-get install rbp-userland-dev-osmc |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| **ATTENTION Win10LinuxSubsystem** we do not (/we can't) support using hyperion in linux subsystem of MS Windows 10, albeit some users tested it with success. Keep in mind to disable | **ATTENTION Win10LinuxSubsystem** we do not (/we can't) support using hyperion in linux subsystem of MS Windows 10, albeit some users tested it with success. Keep in mind to disable | ||||||
| all linux specific led and grabber hardware via cmake. Because we use QT as framework in hyperion, serialport leds and network driven devices could work. | all linux specific led and grabber hardware via cmake. Because we use QT as framework in hyperion, serialport leds and network driven devices could work. | ||||||
| @@ -71,7 +60,7 @@ sudo make install/strip | |||||||
| sudo make uninstall | sudo make uninstall | ||||||
| # ... or run it from compile directory | # ... or run it from compile directory | ||||||
| bin/hyperiond | bin/hyperiond | ||||||
| # webui is located on localhost:8090 | # webui is located on localhost:8099 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ If you need further support please open a topic at the our new forum! | |||||||
| [Hyperion webpage/forum](https://www.hyperion-project.org). | [Hyperion webpage/forum](https://www.hyperion-project.org). | ||||||
|  |  | ||||||
| ## Requirements | ## Requirements | ||||||
| * Debian 8, Ubuntu 14.04 or higher. Windows is not supported currently. | * Debian 9, Ubuntu 16.04 or higher. Windows is not supported currently. | ||||||
|  |  | ||||||
| ## Building | ## Building | ||||||
| See [Compilehowto](CompileHowto.md) and [CrossCompileHowto](CrossCompileHowto.txt). | See [Compilehowto](CompileHowto.md) and [CrossCompileHowto](CrossCompileHowto.txt). | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ | |||||||
| 	"general_col_green" : "grün", | 	"general_col_green" : "grün", | ||||||
| 	"general_col_blue" : "blau", | 	"general_col_blue" : "blau", | ||||||
| 	"general_button_savesettings" : "Einstellungen speichern", | 	"general_button_savesettings" : "Einstellungen speichern", | ||||||
|  | 	"general_btn_yes" : "Ja", | ||||||
| 	"general_btn_ok" : "OK", | 	"general_btn_ok" : "OK", | ||||||
| 	"general_btn_cancel" : "Abbrechen", | 	"general_btn_cancel" : "Abbrechen", | ||||||
| 	"general_btn_continue" : "Fortfahren", | 	"general_btn_continue" : "Fortfahren", | ||||||
| @@ -346,7 +347,7 @@ | |||||||
| 	"edt_dev_enum_sub_min_warm_adjust" : "Minimale Anpassung: warm", | 	"edt_dev_enum_sub_min_warm_adjust" : "Minimale Anpassung: warm", | ||||||
| 	"edt_dev_enum_white_off" : "Weiß ist aus", | 	"edt_dev_enum_white_off" : "Weiß ist aus", | ||||||
| 	"edt_dev_general_heading_title" : "Allgemeine Einstellungen", | 	"edt_dev_general_heading_title" : "Allgemeine Einstellungen", | ||||||
| 	"edt_dev_general_ledCount_title" : "Anzahl Hardware LEDs", | 	"edt_dev_general_hardwareLedCount_title" : "Anzahl Hardware LEDs", | ||||||
| 	"edt_dev_general_colorOrder_title" : "RGB Byte Reihenfolge", | 	"edt_dev_general_colorOrder_title" : "RGB Byte Reihenfolge", | ||||||
| 	"edt_dev_general_rewriteTime_title" : "Aktualisierungszeit", | 	"edt_dev_general_rewriteTime_title" : "Aktualisierungszeit", | ||||||
| 	"edt_dev_spec_header_title" : "Spezifische Einstellungen", | 	"edt_dev_spec_header_title" : "Spezifische Einstellungen", | ||||||
| @@ -482,13 +483,11 @@ | |||||||
| 	"edt_conf_smooth_continuousOutput_expl" : "Aktualisiere die LEDs, auch wenn das Bild sich nicht geändert hat.", | 	"edt_conf_smooth_continuousOutput_expl" : "Aktualisiere die LEDs, auch wenn das Bild sich nicht geändert hat.", | ||||||
| 	"edt_conf_v4l2_heading_title" : "USB Aufnahme", | 	"edt_conf_v4l2_heading_title" : "USB Aufnahme", | ||||||
| 	"edt_conf_v4l2_device_title" : "Gerät", | 	"edt_conf_v4l2_device_title" : "Gerät", | ||||||
| 	"edt_conf_v4l2_device_expl" : "Der Pfad zum USB Aufnahmegerät.", | 	"edt_conf_v4l2_device_expl" : "Der Pfad zum USB (v4l) Aufnahmegerät. Wähle 'auto' für automatische Erkennung. Beispiel: '/dev/video0'", | ||||||
| 	"edt_conf_v4l2_input_title" : "Eingang", |  | ||||||
| 	"edt_conf_v4l2_input_expl" : "Der Eingang des Pfades.", |  | ||||||
| 	"edt_conf_v4l2_standard_title" : "Videoformat", | 	"edt_conf_v4l2_standard_title" : "Videoformat", | ||||||
| 	"edt_conf_v4l2_standard_expl" : "Wähle das passende Videoformat deiner Region.", | 	"edt_conf_v4l2_standard_expl" : "Wähle das passende Videoformat deiner Region. Auf 'Auto' wird der gewählte Modus vom v4l interface beibehalten.", | ||||||
| 	"edt_conf_v4l2_sizeDecimation_title" : "Bildverkleinerung Faktor", | 	"edt_conf_v4l2_sizeDecimation_title" : "Bildverkleinerung Faktor", | ||||||
| 	"edt_conf_v4l2_sizeDecimation_expl" : "Der Faktor der Bildverkleinerung ausgehend der von der ursprünglichen Größe, 1 bedeutet keine Änderung (originales Bild).", | 	"edt_conf_v4l2_sizeDecimation_expl" : "Der Faktor der Bildverkleinerung ausgehend von der ursprünglichen Größe, 1 bedeutet keine Änderung (originales Bild).", | ||||||
| 	"edt_conf_v4l2_cropLeft_title" : "Entferne links", | 	"edt_conf_v4l2_cropLeft_title" : "Entferne links", | ||||||
| 	"edt_conf_v4l2_cropLeft_expl" : "Anzahl der Pixel auf der linken Seite die vom Bild entfernt werden.", | 	"edt_conf_v4l2_cropLeft_expl" : "Anzahl der Pixel auf der linken Seite die vom Bild entfernt werden.", | ||||||
| 	"edt_conf_v4l2_cropRight_title" : "Entferne rechts", | 	"edt_conf_v4l2_cropRight_title" : "Entferne rechts", | ||||||
| @@ -498,7 +497,7 @@ | |||||||
| 	"edt_conf_v4l2_cropBottom_title" : "Entferne unten", | 	"edt_conf_v4l2_cropBottom_title" : "Entferne unten", | ||||||
| 	"edt_conf_v4l2_cropBottom_expl" : "Anzahl der Pixel auf der unteren Seite die vom Bild entfernt werden.", | 	"edt_conf_v4l2_cropBottom_expl" : "Anzahl der Pixel auf der unteren Seite die vom Bild entfernt werden.", | ||||||
| 	"edt_conf_v4l2_signalDetection_title" : "Signal Erkennung", | 	"edt_conf_v4l2_signalDetection_title" : "Signal Erkennung", | ||||||
| 	"edt_conf_v4l2_signalDetection_expl" : "Wenn aktiviert, wird die USB Aufnahme temporär bei \"kein Signal\" abgeschalten.", | 	"edt_conf_v4l2_signalDetection_expl" : "Wenn aktiviert, wird die USB Aufnahme temporär bei \"kein Signal\" abgeschalten. Das Bild muss dazu 4 Sekunden lang unter die Schwellwerte fallen.", | ||||||
| 	"edt_conf_v4l2_redSignalThreshold_title" : "Rote Signalschwelle", | 	"edt_conf_v4l2_redSignalThreshold_title" : "Rote Signalschwelle", | ||||||
| 	"edt_conf_v4l2_redSignalThreshold_expl" : "Je höher die rote Schwelle je eher wird abgeschalten bei entsprechendem rot-Anteil.", | 	"edt_conf_v4l2_redSignalThreshold_expl" : "Je höher die rote Schwelle je eher wird abgeschalten bei entsprechendem rot-Anteil.", | ||||||
| 	"edt_conf_v4l2_greenSignalThreshold_title" : "Grüne Signalschwelle", | 	"edt_conf_v4l2_greenSignalThreshold_title" : "Grüne Signalschwelle", | ||||||
| @@ -513,6 +512,11 @@ | |||||||
| 	"edt_conf_v4l2_sDVOffsetMax_expl" : "Signal Erkennungs-Bereich vertikal maximum (0.0-1.0)", | 	"edt_conf_v4l2_sDVOffsetMax_expl" : "Signal Erkennungs-Bereich vertikal maximum (0.0-1.0)", | ||||||
| 	"edt_conf_v4l2_sDHOffsetMax_title" : "Signal Erkennung HMax", | 	"edt_conf_v4l2_sDHOffsetMax_title" : "Signal Erkennung HMax", | ||||||
| 	"edt_conf_v4l2_sDHOffsetMax_expl" : "Signal Erkennungs-Bereich horizontal maximum (0.0-1.0)", | 	"edt_conf_v4l2_sDHOffsetMax_expl" : "Signal Erkennungs-Bereich horizontal maximum (0.0-1.0)", | ||||||
|  | 	"edt_conf_instCapture_heading_title" : "Instance Aufnahme", | ||||||
|  | 	"edt_conf_instC_systemEnable_title" : "Aktiviere Plattform Aufnahme", | ||||||
|  | 	"edt_conf_instC_systemEnable_expl" : "Aktiviert die Plattform Aufnahme für diese LED Hardware Instanz", | ||||||
|  | 	"edt_conf_instC_v4lEnable_title" : "Aktiviere USB Aufnahme", | ||||||
|  | 	"edt_conf_instC_v4lEnable_expl" : "Aktiviert die USB Aufnahme für diese LED Hardware Instanz", | ||||||
| 	"edt_conf_fg_heading_title" : "Plattform Aufnahme", | 	"edt_conf_fg_heading_title" : "Plattform Aufnahme", | ||||||
| 	"edt_conf_fg_type_title" : "Typ", | 	"edt_conf_fg_type_title" : "Typ", | ||||||
| 	"edt_conf_fg_type_expl" : "Art der Plattform Aufnahme, standard ist 'auto'", | 	"edt_conf_fg_type_expl" : "Art der Plattform Aufnahme, standard ist 'auto'", | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ | |||||||
| 	"general_col_green" : "green", | 	"general_col_green" : "green", | ||||||
| 	"general_col_blue" : "blue", | 	"general_col_blue" : "blue", | ||||||
| 	"general_button_savesettings" : "Save settings", | 	"general_button_savesettings" : "Save settings", | ||||||
|  | 	"general_btn_yes" : "Yes", | ||||||
| 	"general_btn_ok" : "OK", | 	"general_btn_ok" : "OK", | ||||||
| 	"general_btn_cancel" : "Cancel", | 	"general_btn_cancel" : "Cancel", | ||||||
| 	"general_btn_continue" : "Continue", | 	"general_btn_continue" : "Continue", | ||||||
| @@ -347,7 +348,7 @@ | |||||||
| 	"edt_dev_enum_white_off" : "White off", | 	"edt_dev_enum_white_off" : "White off", | ||||||
| 	"edt_dev_general_heading_title" : "General Settings", | 	"edt_dev_general_heading_title" : "General Settings", | ||||||
| 	"edt_dev_general_name_title" : "Configuration name", | 	"edt_dev_general_name_title" : "Configuration name", | ||||||
| 	"edt_dev_general_ledCount_title" : "Count of all hardware LEDs", | 	"edt_dev_general_hardwareLedCount_title" : "Hardware LED count", | ||||||
| 	"edt_dev_general_colorOrder_title" : "RGB byte order", | 	"edt_dev_general_colorOrder_title" : "RGB byte order", | ||||||
| 	"edt_dev_general_rewriteTime_title" : "Refresh time", | 	"edt_dev_general_rewriteTime_title" : "Refresh time", | ||||||
| 	"edt_dev_spec_header_title" : "Specific Settings", | 	"edt_dev_spec_header_title" : "Specific Settings", | ||||||
| @@ -483,17 +484,9 @@ | |||||||
| 	"edt_conf_smooth_continuousOutput_expl" : "Update the leds even there is no changed picture.", | 	"edt_conf_smooth_continuousOutput_expl" : "Update the leds even there is no changed picture.", | ||||||
| 	"edt_conf_v4l2_heading_title" : "USB Capture", | 	"edt_conf_v4l2_heading_title" : "USB Capture", | ||||||
| 	"edt_conf_v4l2_device_title" : "Device", | 	"edt_conf_v4l2_device_title" : "Device", | ||||||
| 	"edt_conf_v4l2_device_expl" : "The path to the usb capture.", | 	"edt_conf_v4l2_device_expl" : "The path to the usb capture interface. Set to 'auto' for auto detection. Example: '/dev/video0'", | ||||||
| 	"edt_conf_v4l2_input_title" : "Input", |  | ||||||
| 	"edt_conf_v4l2_input_expl" : "Input of this path.", |  | ||||||
| 	"edt_conf_v4l2_standard_title" : "Video standard", | 	"edt_conf_v4l2_standard_title" : "Video standard", | ||||||
| 	"edt_conf_v4l2_standard_expl" : "Select the video standard for your region.", | 	"edt_conf_v4l2_standard_expl" : "Select the video standard for your region. 'Auto' keeps the chosen one from v4l interface", | ||||||
| 	"edt_conf_v4l2_width_title" : "Width", |  | ||||||
| 	"edt_conf_v4l2_width_expl" : "The width of the picture. (-1 = auto width)", |  | ||||||
| 	"edt_conf_v4l2_height_title" : "Height", |  | ||||||
| 	"edt_conf_v4l2_height_expl" : "The height of the picture. (-1 = auto height)", |  | ||||||
| 	"edt_conf_v4l2_frameDecimation_title" : "Frame decimation", |  | ||||||
| 	"edt_conf_v4l2_frameDecimation_expl" : "The factor of frame decimation", |  | ||||||
| 	"edt_conf_v4l2_sizeDecimation_title" : "Size decimation", | 	"edt_conf_v4l2_sizeDecimation_title" : "Size decimation", | ||||||
| 	"edt_conf_v4l2_sizeDecimation_expl" : "The factor of size decimation. 1 means no decimation (keep original size)", | 	"edt_conf_v4l2_sizeDecimation_expl" : "The factor of size decimation. 1 means no decimation (keep original size)", | ||||||
| 	"edt_conf_v4l2_cropLeft_title" : "Crop left", | 	"edt_conf_v4l2_cropLeft_title" : "Crop left", | ||||||
| @@ -505,7 +498,7 @@ | |||||||
| 	"edt_conf_v4l2_cropBottom_title" : "Crop bottom", | 	"edt_conf_v4l2_cropBottom_title" : "Crop bottom", | ||||||
| 	"edt_conf_v4l2_cropBottom_expl" : "Count of pixels on the bottom side that are removed from the picture.", | 	"edt_conf_v4l2_cropBottom_expl" : "Count of pixels on the bottom side that are removed from the picture.", | ||||||
| 	"edt_conf_v4l2_signalDetection_title" : "Signal detection", | 	"edt_conf_v4l2_signalDetection_title" : "Signal detection", | ||||||
| 	"edt_conf_v4l2_signalDetection_expl" : "If enabled, usb capture will be temporarily disabled when no signal was found.", | 	"edt_conf_v4l2_signalDetection_expl" : "If enabled, usb capture will be temporarily disabled when no signal was found. This will happen when the picture fall below the threshold value for a period of 4 seconds.", | ||||||
| 	"edt_conf_v4l2_redSignalThreshold_title" : "Red signal threshold", | 	"edt_conf_v4l2_redSignalThreshold_title" : "Red signal threshold", | ||||||
| 	"edt_conf_v4l2_redSignalThreshold_expl" : "Darkens low red values (recognized as black)", | 	"edt_conf_v4l2_redSignalThreshold_expl" : "Darkens low red values (recognized as black)", | ||||||
| 	"edt_conf_v4l2_greenSignalThreshold_title" : "Green signal threshold", | 	"edt_conf_v4l2_greenSignalThreshold_title" : "Green signal threshold", | ||||||
| @@ -520,6 +513,11 @@ | |||||||
| 	"edt_conf_v4l2_sDVOffsetMax_expl" : "Signal detection area vertical maximum (0.0-1.0)", | 	"edt_conf_v4l2_sDVOffsetMax_expl" : "Signal detection area vertical maximum (0.0-1.0)", | ||||||
| 	"edt_conf_v4l2_sDHOffsetMax_title" : "Signal Detection HMax", | 	"edt_conf_v4l2_sDHOffsetMax_title" : "Signal Detection HMax", | ||||||
| 	"edt_conf_v4l2_sDHOffsetMax_expl" : "Signal detection area horizontal maximum (0.0-1.0)", | 	"edt_conf_v4l2_sDHOffsetMax_expl" : "Signal detection area horizontal maximum (0.0-1.0)", | ||||||
|  | 	"edt_conf_instCapture_heading_title" : "Instance Capture", | ||||||
|  | 	"edt_conf_instC_systemEnable_title" : "Enable platform capture", | ||||||
|  | 	"edt_conf_instC_systemEnable_expl" : "Enables the platform capture for this led hardware instance", | ||||||
|  | 	"edt_conf_instC_v4lEnable_title" : "Enable USB capture", | ||||||
|  | 	"edt_conf_instC_v4lEnable_expl" : "Enables the USB capture for this led hardware instance", | ||||||
| 	"edt_conf_fg_heading_title" : "Platform Capture", | 	"edt_conf_fg_heading_title" : "Platform Capture", | ||||||
| 	"edt_conf_fg_type_title" : "Type", | 	"edt_conf_fg_type_title" : "Type", | ||||||
| 	"edt_conf_fg_type_expl" : "Type of platform capture, default is 'auto'", | 	"edt_conf_fg_type_expl" : "Type of platform capture, default is 'auto'", | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ $(document).ready( function() { | |||||||
| 	var conf_editor_net = null; | 	var conf_editor_net = null; | ||||||
| 	var conf_editor_json = null; | 	var conf_editor_json = null; | ||||||
| 	var conf_editor_proto = null; | 	var conf_editor_proto = null; | ||||||
|  | 	var conf_editor_fbs = null; | ||||||
| 	var conf_editor_bobl = null; | 	var conf_editor_bobl = null; | ||||||
| 	var conf_editor_udpl = null; | 	var conf_editor_udpl = null; | ||||||
| 	var conf_editor_forw = null; | 	var conf_editor_forw = null; | ||||||
| @@ -20,6 +21,11 @@ $(document).ready( function() { | |||||||
| 		$('#conf_cont_proto').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); | 		$('#conf_cont_proto').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); | ||||||
| 		$('#conf_cont_proto').append(createHelpTable(schema.protoServer.properties, $.i18n("edt_conf_ps_heading_title"))); | 		$('#conf_cont_proto').append(createHelpTable(schema.protoServer.properties, $.i18n("edt_conf_ps_heading_title"))); | ||||||
|  |  | ||||||
|  | 		//flatbufserver | ||||||
|  | 		$('#conf_cont').append(createRow('conf_cont_flatbuf')) | ||||||
|  | 		$('#conf_cont_flatbuf').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver')); | ||||||
|  | 		$('#conf_cont_flatbuf').append(createHelpTable(schema.flatbufServer.properties, $.i18n("edt_conf_fbs_heading_title"))); | ||||||
|  |  | ||||||
| 		//boblight | 		//boblight | ||||||
| 		$('#conf_cont').append(createRow('conf_cont_bobl')) | 		$('#conf_cont').append(createRow('conf_cont_bobl')) | ||||||
| 		$('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); | 		$('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); | ||||||
| @@ -43,6 +49,7 @@ $(document).ready( function() { | |||||||
| 		$('#conf_cont').addClass('row'); | 		$('#conf_cont').addClass('row'); | ||||||
| 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver')); | 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver')); | ||||||
| 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); | 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); | ||||||
|  | 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver')); | ||||||
| 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); | 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); | ||||||
| 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener')); | 		$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener')); | ||||||
| 		if(storedAccess != 'default') | 		if(storedAccess != 'default') | ||||||
| @@ -62,7 +69,7 @@ $(document).ready( function() { | |||||||
| 		requestWriteConfig(conf_editor_json.getValue()); | 		requestWriteConfig(conf_editor_json.getValue()); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	//proto | 	//protobuffer | ||||||
| 	conf_editor_proto = createJsonEditor('editor_container_protoserver', { | 	conf_editor_proto = createJsonEditor('editor_container_protoserver', { | ||||||
| 		protoServer        : schema.protoServer | 		protoServer        : schema.protoServer | ||||||
| 	}, true, true); | 	}, true, true); | ||||||
| @@ -75,6 +82,19 @@ $(document).ready( function() { | |||||||
| 		requestWriteConfig(conf_editor_proto.getValue()); | 		requestWriteConfig(conf_editor_proto.getValue()); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | 	//flatbuffer | ||||||
|  | 	conf_editor_fbs = createJsonEditor('editor_container_fbserver', { | ||||||
|  | 		flatbufServer        : schema.flatbufServer | ||||||
|  | 	}, true, true); | ||||||
|  |  | ||||||
|  | 	conf_editor_fbs.on('change',function() { | ||||||
|  | 		conf_editor_fbs.validate().length ? $('#btn_submit_fbserver').attr('disabled', true) : $('#btn_submit_fbserver').attr('disabled', false); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	$('#btn_submit_fbserver').off().on('click',function() { | ||||||
|  | 		requestWriteConfig(conf_editor_fbs.getValue()); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
| 	//boblight | 	//boblight | ||||||
| 	conf_editor_bobl = createJsonEditor('editor_container_boblightserver', { | 	conf_editor_bobl = createJsonEditor('editor_container_boblightserver', { | ||||||
| 		boblightServer     : schema.boblightServer | 		boblightServer     : schema.boblightServer | ||||||
| @@ -122,6 +142,7 @@ $(document).ready( function() { | |||||||
| 	{ | 	{ | ||||||
| 		createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver"); | 		createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver"); | ||||||
| 		createHint("intro", $.i18n('conf_network_proto_intro'), "editor_container_protoserver"); | 		createHint("intro", $.i18n('conf_network_proto_intro'), "editor_container_protoserver"); | ||||||
|  | 		createHint("intro", $.i18n('conf_network_fbs_intro'), "editor_container_fbserver"); | ||||||
| 		createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver"); | 		createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver"); | ||||||
| 		createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener"); | 		createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener"); | ||||||
| 		createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder"); | 		createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder"); | ||||||
|   | |||||||
| @@ -173,7 +173,7 @@ function sendToHyperion(command, subcommand, msg) | |||||||
| // also used for watchdog | // also used for watchdog | ||||||
| function requestServerInfo() | function requestServerInfo() | ||||||
| { | { | ||||||
| 	sendToHyperion("serverinfo","",'"subscribe":["components-update","sessions-update","priorities-update", "imageToLedMapping-update", "adjustment-update", "videomode-update", "effects-update"]'); | 	sendToHyperion("serverinfo","",'"subscribe":["components-update","sessions-update","priorities-update", "imageToLedMapping-update", "adjustment-update", "videomode-update", "effects-update", "settings-update"]'); | ||||||
| } | } | ||||||
|  |  | ||||||
| function requestSysInfo() | function requestSysInfo() | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,13 +1,14 @@ | |||||||
| [Unit] | [Unit] | ||||||
| Description=Hyperion ambient light systemd service | Description=Hyperion ambient light systemd service  for user %i | ||||||
| After=network.target | After=network.target | ||||||
|  |  | ||||||
| [Service] | [Service] | ||||||
| ExecStart=/usr/bin/hyperiond | ExecStart=/usr/bin/hyperiond | ||||||
| WorkingDirectory=/usr/share/hyperion/bin | WorkingDirectory=/usr/share/hyperion/bin | ||||||
|  | User=%i | ||||||
| TimeoutStopSec=5 | TimeoutStopSec=5 | ||||||
| KillMode=mixed | KillMode=mixed | ||||||
| Restart=always | Restart=on-failure | ||||||
| RestartSec=2 | RestartSec=2 | ||||||
|  |  | ||||||
| [Install] | [Install] | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ install_file() | |||||||
| 	dest="$2" | 	dest="$2" | ||||||
|  |  | ||||||
| 	if [ ! -e "$dest" ] | 	if [ ! -e "$dest" ] | ||||||
|  | 	then | ||||||
| 		cp "$src" "${dest}" | 		cp "$src" "${dest}" | ||||||
| 		return 1 | 		return 1 | ||||||
| 	else | 	else | ||||||
| @@ -15,10 +16,7 @@ install_file() | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| echo "--- hyperion ambient light postinstall ---" | echo "---Hyperion ambient light postinstall ---" | ||||||
| echo "- install configuration template" |  | ||||||
| mkdir -p /etc/hyperion |  | ||||||
| mkdir -p /usr/share/hyperion/custom-effects |  | ||||||
|  |  | ||||||
| #check system | #check system | ||||||
| CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835' /proc/cpuinfo` | CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835' /proc/cpuinfo` | ||||||
| @@ -27,25 +25,29 @@ CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l` | |||||||
| #Check for a bootloader as Berryboot | #Check for a bootloader as Berryboot | ||||||
| BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab) | BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab) | ||||||
|  |  | ||||||
| #get current system ip + add default port | #get current system ip | ||||||
| address=$(ip -o -4 a | awk '$2 == "eth0" { gsub(/\/.*/, "", $4); print $4 }')":8099" | NET_IF=`netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}'` | ||||||
|  | NET_IP=`ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'` | ||||||
|  |  | ||||||
| #check if hyperion is running | #check if hyperion is running | ||||||
| HYPERION_RUNNING=false | HYPERION_RUNNING=false | ||||||
| pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true | pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true | ||||||
|  |  | ||||||
|  | # search for users in system, returns first entry | ||||||
|  | FOUND_USR=`who | grep -o '^\w*\b'` || "root" | ||||||
|  |  | ||||||
| start_msg="" | start_msg="" | ||||||
| restart_msg="" | restart_msg="" | ||||||
| SERVICE_POSTFIX="" |  | ||||||
|  |  | ||||||
| if grep -m1 systemd /proc/1/comm > /dev/null | if grep -m1 systemd /proc/1/comm > /dev/null | ||||||
| then | then | ||||||
| 	echo "--> init deamon: systemd" | 	echo "--> init deamon: systemd" | ||||||
| 	# systemd | 	# systemd | ||||||
| 	$HYPERION_RUNNING && systemctl stop hyperiond 2> /dev/null | 	$HYPERION_RUNNING && systemctl stop hyperiond 2> /dev/null | ||||||
| 	install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond.service && systemctl -q enable hyperiond.service | 	install_file /usr/share/hyperion/service/hyperion.systemd /etc/systemd/system/hyperiond@.service | ||||||
| 	start_msg="--> systemctl start hyperiond" | 	systemctl enable hyperiond"@${FOUND_USR}".service | ||||||
| 	systemctl start hyperiond | 	start_msg="--> systemctl start hyperiond for user ${FOUND_USR}" | ||||||
|  | 	systemctl start hyperiond"@${FOUND_USR}" | ||||||
|  |  | ||||||
| elif [ -e /sbin/initctl ] | elif [ -e /sbin/initctl ] | ||||||
| then | then | ||||||
| @@ -100,9 +102,12 @@ if [ $CPU_RPI -eq 1 ]; then | |||||||
| 	fi | 	fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | echo ${start_msg} | ||||||
|  |  | ||||||
| echo "-----------------------------------------------------------------------------" | echo "-----------------------------------------------------------------------------" | ||||||
| echo "--> Hyperion has been installed/updated!" | echo "--> Hyperion has been installed/updated!" | ||||||
| echo "--> For configuration, visit with your browser: ${address}" | echo "--> For configuration, visit with your browser: ${NET_IP}:8090" | ||||||
|  | echo "--> or if already used by another service try: ${NET_IP}:8091" | ||||||
| $REBOOTMESSAGE | $REBOOTMESSAGE | ||||||
| echo "-----------------------------------------------------------------------------" | echo "-----------------------------------------------------------------------------" | ||||||
| echo "Webpage: www.hyperion-project.org" | echo "Webpage: www.hyperion-project.org" | ||||||
| @@ -110,28 +115,12 @@ echo "Wiki: wiki.hyperion-project.org" | |||||||
| echo "Forum: forum.hyperion-project.org" | echo "Forum: forum.hyperion-project.org" | ||||||
| echo "-----------------------------------------------------------------------------" | echo "-----------------------------------------------------------------------------" | ||||||
|  |  | ||||||
| # try to open the browser for desktops. TODO: add headless detection(?) |  | ||||||
| if	[ $CPU_X32X64 -eq 1] |  | ||||||
| echo "--> Will open browser with target: ${address}" |  | ||||||
| 	if [[ -e /usr/bin/xdg-open ]] |  | ||||||
| 		then |  | ||||||
| 		xdg-open http://"$address" |  | ||||||
| 	elif [[ -e /usr/bin/x-www-browser ]] |  | ||||||
| 		then |  | ||||||
| 		x-www-browser http://"$address" |  | ||||||
| 	elif [[ -e /usr/bin/www-browser ]] |  | ||||||
| 		then |  | ||||||
| 		www-browser http://"$address" |  | ||||||
| 	fi |  | ||||||
| fi |  | ||||||
|  |  | ||||||
|  |  | ||||||
| if [ -e /opt/hyperion/ ] | if [ -e /opt/hyperion/ ] | ||||||
| then | then | ||||||
| 	echo | 	echo | ||||||
| 	echo "---------------------------------------------------------------------------------" | 	echo "---------------------------------------------------------------------------------" | ||||||
| 	echo "- It seemd that you have an older version of hyperion installed in /opt/hyerion -" | 	echo "- It seemd that you have an older version of hyperion installed in /opt/hyperion -" | ||||||
| 	echo "- please remove it and check your config to avoid problems                      -" | 	echo "- please remove it to avoid problems                                            -" | ||||||
| 	echo "---------------------------------------------------------------------------------" | 	echo "---------------------------------------------------------------------------------" | ||||||
| fi | fi | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,51 +1,56 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
|  |  | ||||||
| # check which init script we should use | echo "---Hyperion ambient light preinst ---" | ||||||
| USE_SYSTEMD=`grep -m1 -c systemd /proc/1/comm` |  | ||||||
| USE_INITCTL=`which /sbin/initctl | wc -l` |  | ||||||
| USE_SERVICE=`which /usr/sbin/service | wc -l` |  | ||||||
|  |  | ||||||
| #check for hyperion install | # search for users in system, returns first entry | ||||||
| if [ -d /usr/share/hyperion/bin ];then | FOUND_USR=`who | grep -o '^\w*\b'` || "root" | ||||||
| 	if [ -e /etc/hyperion/hyperion.config.json ];then |  | ||||||
| 		file=`grep -m1 -c '"general"' /etc/hyperion/hyperion.config.json` |  | ||||||
| 		if [ $file -ne 1 ]; then |  | ||||||
| 			echo "--> It seems you are running an old version of Hyperion (1.X). Will create a backup at /usr/share/hyperion/Backup_Hyperion_1.0 and reset configuration / system service" |  | ||||||
|  |  | ||||||
| 			# Stop hyperion daemon if it is running | # stop running daemon before we install | ||||||
| 			echo '---> Stop Hyperion, if necessary' | if pgrep hyperiond > /dev/null 2>&1 | ||||||
| 			if [ $USE_SYSTEMD -eq 1 ]; then | then | ||||||
| 				service hyperion stop 2>/dev/null | 	if grep -m1 systemd /proc/1/comm > /dev/null | ||||||
| 			elif [ $USE_INITCTL -eq 1 ]; then | 	then | ||||||
| 				/sbin/initctl stop hyperion 2>/dev/null | 		echo "--> stop init deamon: systemd" | ||||||
| 			elif [ $USE_SERVICE -eq 1 ]; then | 		# systemd | ||||||
| 				/usr/sbin/service hyperion stop 2>/dev/null | 		systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null | ||||||
| 			fi |  | ||||||
|  |  | ||||||
| 			#Backup | 	elif [ -e /sbin/initctl ] | ||||||
| 			echo "--> Move old config(s) and files to /usr/share/hyperion/Backup_Hyperion_1.0" | 	then | ||||||
| 			mkdir  /usr/share/hyperion/Backup_Hyperion_1.0 | 		echo "--> stop init deamon: upstart" | ||||||
| 			mv /usr/share/hyperion /usr/share/hyperion/Backup_Hyperion_1.0 | 		# upstart | ||||||
| 			mv /etc/hyperion/* /usr/share/hyperion/Backup_Hyperion_1.0 | 		initctl stop hyperiond | ||||||
|  |  | ||||||
| 			#Disabling and delete service files | 	else | ||||||
| 			if [ $USE_SYSTEMD -eq 1 ]; then | 		echo "--> stop init deamon: sysV" | ||||||
| 				# Delete and disable Hyperion systemd script | 		# sysV | ||||||
| 				echo '---> Delete and disable Hyperion systemd service' | 		service hyperiond stop 2>/dev/null | ||||||
| 				systemctl disable hyperion.service |  | ||||||
| 				rm -v /etc/systemd/system/hyperion* 2>/dev/null |  | ||||||
| 			elif [ $USE_INITCTL -eq 1 ]; then |  | ||||||
| 				echo '---> Delete and disable Hyperion initctl script' |  | ||||||
| 				rm -v /etc/init/hyperion* 2>/dev/null |  | ||||||
| 				initctl reload-configuration |  | ||||||
| 			elif [ $USE_SERVICE -eq 1 ]; then |  | ||||||
| 				# Delete and disable Hyperion init.d script |  | ||||||
| 				echo '---> Delete and disable Hyperion init.d script' |  | ||||||
| 				update-rc.d -f hyperion remove |  | ||||||
| 				rm /etc/init.d/hyperion* 2>/dev/null |  | ||||||
| 			fi |  | ||||||
| 		 |  | ||||||
| 			echo "--> Hyperion 1.0 installation has been moved" |  | ||||||
| 		fi |  | ||||||
| 	fi | 	fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #$USR=hyperionIS; | ||||||
|  |  | ||||||
|  | #addToGroup() | ||||||
|  | ##{ | ||||||
|  | #	getent group $1 && adduser $USR $1; | ||||||
|  | #} | ||||||
|  |  | ||||||
|  | #check if user exists | ||||||
|  | #if id $USR >/dev/null 2>&1; then | ||||||
|  | #    echo "--> hyperion user exists, skip creation"; | ||||||
|  | #else | ||||||
|  | 	## create user | ||||||
|  | #	echo "--> Create Hyperion user"; | ||||||
|  | #	adduser --system --group $USR; | ||||||
|  | #fi | ||||||
|  |  | ||||||
|  | # add user to groups if required | ||||||
|  | ## secondary user groups that are required to access system things | ||||||
|  | #addToGroup(dialout); | ||||||
|  | #addToGroup(video); | ||||||
|  | #addToGroup(audio); | ||||||
|  | #addToGroup(systemd-journal); | ||||||
|  | # platform specific groups | ||||||
|  | #addToGroup(i2c); | ||||||
|  | #addToGroup(spi); | ||||||
|  | #addToGroup(gpio); | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								cmake/debian/prerm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								cmake/debian/prerm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | #!/bin/sh | ||||||
|  |  | ||||||
|  | echo "---Hyperion ambient light prerm ---" | ||||||
|  |  | ||||||
|  | # search for users in system, returns first entry | ||||||
|  | FOUND_USR=`who | grep -o '^\w*\b'` || "root" | ||||||
|  |  | ||||||
|  | # stop running daemon before we delete it | ||||||
|  | HYPERION_RUNNING=false | ||||||
|  | pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true | ||||||
|  |  | ||||||
|  | if grep -m1 systemd /proc/1/comm > /dev/null | ||||||
|  | then | ||||||
|  | 	echo "--> stop init deamon: systemd" | ||||||
|  | 	# systemd | ||||||
|  | 	$HYPERION_RUNNING && systemctl stop hyperiond"@${FOUND_USR}" 2> /dev/null | ||||||
|  | 	# disable user specific symlink | ||||||
|  | 	echo "--> Disable service and remove entry" | ||||||
|  | 	systemctl -q disable hyperiond"@${FOUND_USR}" | ||||||
|  | 	rm -v /etc/systemd/system/hyperiond@.service 2>/dev/null | ||||||
|  |  | ||||||
|  | elif [ -e /sbin/initctl ] | ||||||
|  | then | ||||||
|  | 	echo "--> stop init deamon: upstart" | ||||||
|  | 	# upstart | ||||||
|  | 	$HYPERION_RUNNING && initctl stop hyperiond | ||||||
|  | 	echo "--> Remove upstart service" | ||||||
|  | 	rm -v /etc/init/hyperion* 2>/dev/null | ||||||
|  | 	initctl reload-configuration | ||||||
|  |  | ||||||
|  | else | ||||||
|  | 	echo "--> stop init deamon: sysV" | ||||||
|  | 	# sysV | ||||||
|  | 	$HYPERION_RUNNING && service hyperiond stop 2>/dev/null | ||||||
|  | 	echo "--> Remove sysV service" | ||||||
|  | 	update-rc.d -f hyperion remove | ||||||
|  | 	rm /etc/init.d/hyperion* 2>/dev/null | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | return 0 | ||||||
| @@ -13,9 +13,9 @@ SET ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" ) | |||||||
|  |  | ||||||
| SET ( CPACK_DEBIAN_PACKAGE_MAINTAINER "Hyperion Team") | SET ( CPACK_DEBIAN_PACKAGE_MAINTAINER "Hyperion Team") | ||||||
| SET ( CPACK_DEBIAN_PACKAGE_NAME "Hyperion" ) | SET ( CPACK_DEBIAN_PACKAGE_NAME "Hyperion" ) | ||||||
| SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst" ) | SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/preinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/prerm" ) | ||||||
| SET ( CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.hyperion-project.org" ) | SET ( CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.hyperion-project.org" ) | ||||||
| SET ( CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a (>= 5.2.0), libqt5network5 (>= 5.2.0), libqt5gui5 (>= 5.2.0), libqt5serialport5 (>= 5.2.0), libavahi-core7 (>= 0.6.31), libavahi-compat-libdnssd1 (>= 0.6.31), libusb-1.0-0, libpython3.4, libc6" ) | SET ( CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a (>= 5.5.0), libqt5network5 (>= 5.5.0), libqt5gui5 (>= 5.5.0), libqt5serialport5 (>= 5.5.0), libqt5sql5 (>= 5.5.0), libavahi-core7 (>= 0.6.31), libavahi-compat-libdnssd1 (>= 0.6.31), libusb-1.0-0, libpython3.5, libc6" ) | ||||||
| SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) | SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" ) | ||||||
|  |  | ||||||
| SET ( CPACK_RPM_PACKAGE_NAME "Hyperion" ) | SET ( CPACK_RPM_PACKAGE_NAME "Hyperion" ) | ||||||
|   | |||||||
| @@ -20,14 +20,14 @@ | |||||||
|  |  | ||||||
| 	/// Device configuration contains the following fields: | 	/// Device configuration contains the following fields: | ||||||
| 	/// * 'name'       : The user friendly name of the device (only used for display purposes) | 	/// * 'name'       : The user friendly name of the device (only used for display purposes) | ||||||
| 	/// * 'type'       : The type of the device or leds (known types for now are | 	/// * 'type'       : The type of the device | ||||||
| 	///  APA102, WS2801, P9813, LPD6803, LPD8806, ---------PWM---------, WS2812b (just RPi1), WS281X (RPi1, RPi2, RPi3), --------OTHER--------, PhilipsHUE, AtmoOrb, PiBlaster, Tinkerforge, FadeCandy, RawHID (USB), UDP, SEDU, TPM2, USBASP-WS2801, USBASP-WS2812, ------3rd PARTY------, Adalight, AdalightAPA102, Atmo, Lightpack, Multi-Lightpack, Paintpack, Test (file), None) |  | ||||||
| 	/// * [device type specific configuration] | 	/// * [device type specific configuration] | ||||||
| 	/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.). | 	/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.). | ||||||
| 	/// * 'rewriteTime': in ms. Data is resend to leds, if no new data is available in thistime. 0 means no refresh | 	/// * 'rewriteTime': in ms. Data is resend to leds, if no new data is available in thistime. 0 means no refresh | ||||||
| 	"device" : | 	"device" : | ||||||
| 	{ | 	{ | ||||||
| 		"type"       : "file", | 		"type"       : "file", | ||||||
|  | 		"hardwareLedCount" : 1, | ||||||
| 		"output"     : "/dev/null", | 		"output"     : "/dev/null", | ||||||
| 		"rate"     : 1000000, | 		"rate"     : 1000000, | ||||||
| 		"colorOrder" : "rgb", | 		"colorOrder" : "rgb", | ||||||
| @@ -98,8 +98,7 @@ | |||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	/// Configuration for the embedded V4L2 grabber | 	/// Configuration for the embedded V4L2 grabber | ||||||
| 	///  * device               : V4L2 Device to use [default="/dev/video0"] | 	///  * device               : V4L2 Device to use [default="auto"] (Auto detection) | ||||||
| 	///  * input                : V4L2 input to use [default=0] |  | ||||||
| 	///  * standard             : Video standard (PAL/NTSC/SECAM/NO_CHANGE) [default="NO_CHANGE"] | 	///  * standard             : Video standard (PAL/NTSC/SECAM/NO_CHANGE) [default="NO_CHANGE"] | ||||||
| 	///  * sizeDecimation       : Size decimation factor [default=8] | 	///  * sizeDecimation       : Size decimation factor [default=8] | ||||||
| 	///  * cropLeft             : Cropping from the left [default=0] | 	///  * cropLeft             : Cropping from the left [default=0] | ||||||
| @@ -118,7 +117,6 @@ | |||||||
| 	[ | 	[ | ||||||
| 		{ | 		{ | ||||||
| 			"device"   : "auto", | 			"device"   : "auto", | ||||||
| 			"input"    : 0, |  | ||||||
| 			"standard" : "NO_CHANGE", | 			"standard" : "NO_CHANGE", | ||||||
| 			"sizeDecimation"  : 8, | 			"sizeDecimation"  : 8, | ||||||
| 			"priority"    : 240, | 			"priority"    : 240, | ||||||
| @@ -233,13 +231,22 @@ | |||||||
| 		"port" : 19444 | 		"port" : 19444 | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	/// The configuration of the Proto server which enables the protobuffer remote interface | 	/// The configuration of the Protobuffer server which enables the Protobuffer remote interface | ||||||
| 	///  * port : Port at which the protobuffer server is started | 	///  * port : Port at which the protobuffer server is started | ||||||
| 	"protoServer" : | 	"protoServer" : | ||||||
| 	{ | 	{ | ||||||
| 		"port" : 19445 | 		"port" : 19445 | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | 	/// The configuration of the Flatbuffer server which enables the Flatbuffer remote interface | ||||||
|  | 	///  * port : Port at which the flatbuffer server is started | ||||||
|  | 	"flatbufServer" : | ||||||
|  | 	{ | ||||||
|  | 		"enable" : true, | ||||||
|  | 		"port" : 19400, | ||||||
|  | 		"timeout" : 5 | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	/// The configuration of the boblight server which enables the boblight remote interface | 	/// The configuration of the boblight server which enables the boblight remote interface | ||||||
| 	///  * enable   : Enable or disable the boblight server (true/false) | 	///  * enable   : Enable or disable the boblight server (true/false) | ||||||
| 	///  * port     : Port at which the boblight server is started | 	///  * port     : Port at which the boblight server is started | ||||||
| @@ -269,12 +276,10 @@ | |||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	/// Configuration of the Hyperion webserver | 	/// Configuration of the Hyperion webserver | ||||||
| 	///  * enable        : enable or disable the webserver (true/false) |  | ||||||
| 	///  * document_root : path to hyperion webapp files (webconfig developer only) | 	///  * document_root : path to hyperion webapp files (webconfig developer only) | ||||||
| 	///  * port          : the port where hyperion webapp is accasible | 	///  * port          : the port where hyperion webapp is accasible | ||||||
| 	"webConfig" : | 	"webConfig" : | ||||||
| 	{ | 	{ | ||||||
| 		"enable"        : true, |  | ||||||
| 		"document_root" : "/path/to/files", | 		"document_root" : "/path/to/files", | ||||||
| 		"port"          : 8090 | 		"port"          : 8090 | ||||||
| 	}, | 	}, | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
| 	"device" : | 	"device" : | ||||||
| 	{ | 	{ | ||||||
| 		"type"       : "file", | 		"type"       : "file", | ||||||
|  | 		"hardwareLedCount" : 1, | ||||||
| 		"output"     : "/dev/null", | 		"output"     : "/dev/null", | ||||||
| 		"rate"       : 1000000, | 		"rate"       : 1000000, | ||||||
| 		"colorOrder" : "rgb", | 		"colorOrder" : "rgb", | ||||||
| @@ -58,7 +59,6 @@ | |||||||
| 	[ | 	[ | ||||||
| 		{ | 		{ | ||||||
| 			"device"   : "auto", | 			"device"   : "auto", | ||||||
| 			"input"    : 0, |  | ||||||
| 			"standard" : "NO_CHANGE", | 			"standard" : "NO_CHANGE", | ||||||
| 			"sizeDecimation"  : 8, | 			"sizeDecimation"  : 8, | ||||||
| 			"cropLeft"    : 0, | 			"cropLeft"    : 0, | ||||||
| @@ -135,6 +135,13 @@ | |||||||
| 		"port" : 19445 | 		"port" : 19445 | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | 	"flatbufServer" : | ||||||
|  | 	{ | ||||||
|  | 		"enable" : true, | ||||||
|  | 		"port" : 19400, | ||||||
|  | 		"timeout" : 5 | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	"boblightServer" : | 	"boblightServer" : | ||||||
| 	{ | 	{ | ||||||
| 		"enable"   : false, | 		"enable"   : false, | ||||||
| @@ -154,7 +161,6 @@ | |||||||
|  |  | ||||||
| 	"webConfig" : | 	"webConfig" : | ||||||
| 	{ | 	{ | ||||||
| 		"enable"        : true, |  | ||||||
| 		"document_root" : "", | 		"document_root" : "", | ||||||
| 		"port"          : 8090 | 		"port"          : 8090 | ||||||
| 	}, | 	}, | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								dependencies/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								dependencies/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -9,6 +9,48 @@ if(ENABLE_WS281XPWM) | |||||||
| 		external/rpi_ws281x/rpihw.c) | 		external/rpi_ws281x/rpihw.c) | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
|  | set(USE_SYSTEM_FLATBUFFERS_LIBS ${DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS} CACHE BOOL "use flatbuffers library from system") | ||||||
|  |  | ||||||
|  | if (USE_SYSTEM_FLATBUFFERS_LIBS) | ||||||
|  | 	find_package(flatbuffers REQUIRED) | ||||||
|  | 	include_directories(${FLATBUFFERS_INCLUDE_DIRS}) | ||||||
|  | else () | ||||||
|  | 	set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared flatbuffers library") | ||||||
|  | 	set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "Build Flatbuffers with tests") | ||||||
|  | 	add_subdirectory(external/flatbuffers) | ||||||
|  |  | ||||||
|  | 	if(CMAKE_CROSSCOMPILING) | ||||||
|  | 		# when crosscompiling import the flatc executable targets from a file generated by a native build | ||||||
|  | 		option(IMPORT_FLATC "flatc export file (flatc_export.cmake) from a native build" "IMPORT_FLATC-FILE_NOT_FOUND") | ||||||
|  | 		include(${IMPORT_FLATC}) | ||||||
|  | 	else() | ||||||
|  | 		# export the flatc compiler so it can be used when cross compiling | ||||||
|  | 		export(TARGETS flatc FILE "${CMAKE_BINARY_DIR}/flatc_export.cmake") | ||||||
|  | 	endif() | ||||||
|  |  | ||||||
|  | 	# define the include for the flatbuffers library at the parent scope | ||||||
|  | 	set(FLATBUFFERS_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/flatbuffers/include") | ||||||
|  | 	set(FLATBUFFERS_INCLUDE_DIRS ${FLATBUFFERS_INCLUDE_DIRS} PARENT_SCOPE) | ||||||
|  |  | ||||||
|  | 	# define the flatc executable at the parent scope | ||||||
|  | 	get_property(FLATBUFFERS_FLATC_EXECUTABLE TARGET flatc PROPERTY LOCATION) | ||||||
|  | 	set(FLATBUFFERS_FLATC_EXECUTABLE ${FLATBUFFERS_FLATC_EXECUTABLE} PARENT_SCOPE) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | message(STATUS "Using flatbuffers compiler: " ${FLATBUFFERS_FLATC_EXECUTABLE}) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR) | ||||||
|  |   string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS}) | ||||||
|  |   add_custom_command( | ||||||
|  |     OUTPUT ${GEN_HEADER} | ||||||
|  |     COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable | ||||||
|  | 			--gen-object-api | ||||||
|  | 			-o "${OUTPUT_DIR}" | ||||||
|  | 			"${SRC_FBS}" | ||||||
|  |     DEPENDS flatc) | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
| set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system") | set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system") | ||||||
|  |  | ||||||
| if (USE_SYSTEM_PROTO_LIBS) | if (USE_SYSTEM_PROTO_LIBS) | ||||||
|   | |||||||
							
								
								
									
										254
									
								
								include/api/JsonAPI.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								include/api/JsonAPI.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | // hyperion includes | ||||||
|  | #include <utils/Logger.h> | ||||||
|  | #include <utils/jsonschema/QJsonSchemaChecker.h> | ||||||
|  | #include <utils/Components.h> | ||||||
|  | #include <hyperion/Hyperion.h> | ||||||
|  |  | ||||||
|  | // qt includess | ||||||
|  | #include <QTimer> | ||||||
|  | #include <QJsonObject> | ||||||
|  | #include <QMutex> | ||||||
|  | #include <QString> | ||||||
|  |  | ||||||
|  | // createEffect helper | ||||||
|  | struct find_schema: std::unary_function<EffectSchema, bool> | ||||||
|  | { | ||||||
|  | 	QString pyFile; | ||||||
|  | 	find_schema(QString pyFile):pyFile(pyFile) { } | ||||||
|  | 	bool operator()(EffectSchema const& schema) const | ||||||
|  | 	{ | ||||||
|  | 		return schema.pyFile == pyFile; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // deleteEffect helper | ||||||
|  | struct find_effect: std::unary_function<EffectDefinition, bool> | ||||||
|  | { | ||||||
|  | 	QString effectName; | ||||||
|  | 	find_effect(QString effectName) :effectName(effectName) { } | ||||||
|  | 	bool operator()(EffectDefinition const& effectDefinition) const | ||||||
|  | 	{ | ||||||
|  | 		return effectDefinition.name == effectName; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class JsonCB; | ||||||
|  |  | ||||||
|  | class JsonAPI : public QObject | ||||||
|  | { | ||||||
|  | 	Q_OBJECT | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	/// | ||||||
|  | 	/// Constructor | ||||||
|  | 	/// | ||||||
|  | 	/// @param peerAddress provide the Address of the peer | ||||||
|  | 	/// @param log         The Logger class of the creator | ||||||
|  | 	/// @param parent      Parent QObject | ||||||
|  | 	/// @param noListener  if true, this instance won't listen for hyperion push events | ||||||
|  | 	/// | ||||||
|  | 	JsonAPI(QString peerAddress, Logger* log, QObject* parent, bool noListener = false); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message as string | ||||||
|  | 	/// | ||||||
|  | 	void handleMessage(const QString & message, const QString& httpAuthHeader = ""); | ||||||
|  |  | ||||||
|  | public slots: | ||||||
|  | 	/// _timer_ledcolors requests ledcolor updates (if enabled) | ||||||
|  | 	void streamLedcolorsUpdate(); | ||||||
|  |  | ||||||
|  | 	/// push images whenever hyperion emits (if enabled) | ||||||
|  | 	void setImage(const Image<ColorRgb> & image); | ||||||
|  |  | ||||||
|  | 	/// process and push new log messages from logger (if enabled) | ||||||
|  | 	void incommingLogMessage(Logger::T_LOG_MESSAGE); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  | 	/// | ||||||
|  | 	/// Signal emits with the reply message provided with handleMessage() | ||||||
|  | 	/// | ||||||
|  | 	void callbackMessage(QJsonObject); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Signal emits whenever a jsonmessage should be forwarded | ||||||
|  | 	/// | ||||||
|  | 	void forwardJsonMessage(QJsonObject); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |  | ||||||
|  | 	// The JsonCB instance which handles data subscription/notifications | ||||||
|  | 	JsonCB* _jsonCB; | ||||||
|  | 	// true if further callbacks are forbidden (http) | ||||||
|  | 	bool _noListener; | ||||||
|  |     /// The peer address of the client | ||||||
|  |     QString _peerAddress; | ||||||
|  |  | ||||||
|  | 	/// Log instance | ||||||
|  | 	Logger* _log; | ||||||
|  |  | ||||||
|  | 	/// Hyperion instance | ||||||
|  | 	Hyperion* _hyperion; | ||||||
|  |  | ||||||
|  | 	/// timer for ledcolors streaming | ||||||
|  | 	QTimer _timer_ledcolors; | ||||||
|  |  | ||||||
|  | 	// streaming buffers | ||||||
|  | 	QJsonObject _streaming_leds_reply; | ||||||
|  | 	QJsonObject _streaming_image_reply; | ||||||
|  | 	QJsonObject _streaming_logging_reply; | ||||||
|  |  | ||||||
|  | 	/// flag to determine state of log streaming | ||||||
|  | 	bool _streaming_logging_activated; | ||||||
|  |  | ||||||
|  | 	/// mutex to determine state of image streaming | ||||||
|  | 	QMutex _image_stream_mutex; | ||||||
|  |  | ||||||
|  | 	/// timeout for live video refresh | ||||||
|  | 	volatile qint64 _image_stream_timeout; | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Color message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleColorCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Image message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleImageCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Effect message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleEffectCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Effect message (Write JSON Effect) | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleCreateEffectCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Effect message (Delete JSON Effect) | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleDeleteEffectCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON System info message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleSysInfoCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Server info message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleServerInfoCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Clear message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleClearCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Adjustment message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleAdjustmentCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON SourceSelect message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleSourceSelectCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON GetConfig message and check subcommand | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleConfigCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON GetConfig message from handleConfigCommand() | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleSchemaGetCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON SetConfig message from handleConfigCommand() | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleConfigSetCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON Component State message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleComponentStateCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON Led Colors message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleLedColorsCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON Logging message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleLoggingCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON Proccessing message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleProcessingCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// Handle an incoming JSON VideoMode message | ||||||
|  | 	/// | ||||||
|  | 	/// @param message the incoming message | ||||||
|  | 	/// | ||||||
|  | 	void handleVideoModeCommand(const QJsonObject & message, const QString &command, const int tan); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Handle an incoming JSON message of unknown type | ||||||
|  | 	/// | ||||||
|  | 	void handleNotImplemented(); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Send a standard reply indicating success | ||||||
|  | 	/// | ||||||
|  | 	void sendSuccessReply(const QString &command="", const int tan=0); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Send a standard reply indicating success with data | ||||||
|  | 	/// | ||||||
|  | 	void sendSuccessDataReply(const QJsonDocument &doc, const QString &command="", const int &tan=0); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// Send an error message back to the client | ||||||
|  | 	/// | ||||||
|  | 	/// @param error String describing the error | ||||||
|  | 	/// | ||||||
|  | 	void sendErrorReply(const QString & error, const QString &command="", const int tan=0); | ||||||
|  | }; | ||||||
							
								
								
									
										112
									
								
								include/api/JsonCB.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								include/api/JsonCB.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | // qt incl | ||||||
|  | #include <QObject> | ||||||
|  | #include <QJsonObject> | ||||||
|  |  | ||||||
|  | // components def | ||||||
|  | #include <utils/Components.h> | ||||||
|  | // bonjour | ||||||
|  | #include <bonjour/bonjourrecord.h> | ||||||
|  | // videModes | ||||||
|  | #include <utils/VideoMode.h> | ||||||
|  | // settings | ||||||
|  | #include <utils/settings.h> | ||||||
|  |  | ||||||
|  | class Hyperion; | ||||||
|  | class ComponentRegister; | ||||||
|  | class BonjourBrowserWrapper; | ||||||
|  | class PriorityMuxer; | ||||||
|  |  | ||||||
|  | class JsonCB : public QObject | ||||||
|  | { | ||||||
|  | 	Q_OBJECT | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	JsonCB(QObject* parent); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Subscribe to future data updates given by cmd | ||||||
|  | 	/// @param cmd   The cmd which will be subscribed for | ||||||
|  | 	/// @return      True on success, false if not found | ||||||
|  | 	/// | ||||||
|  | 	bool subscribeFor(const QString& cmd); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Get all possible commands to subscribe for | ||||||
|  | 	/// @return  The list of commands | ||||||
|  | 	/// | ||||||
|  | 	QStringList getCommands() { return _availableCommands; }; | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Get all subscribed commands | ||||||
|  | 	/// @return  The list of commands | ||||||
|  | 	/// | ||||||
|  | 	QStringList getSubscribedCommands() { return _subscribedCommands; }; | ||||||
|  | signals: | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Emits whenever a new json mesage callback is ready to send | ||||||
|  | 	/// @param The JsonObject message | ||||||
|  | 	/// | ||||||
|  | 	void newCallback(QJsonObject); | ||||||
|  |  | ||||||
|  | private slots: | ||||||
|  | 	/// | ||||||
|  | 	/// @brief handle component state changes | ||||||
|  | 	/// | ||||||
|  | 	void handleComponentState(const hyperion::Components comp, const bool state); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief handle emits from bonjour wrapper | ||||||
|  | 	/// @param  bRegisters   The full register map | ||||||
|  | 	/// | ||||||
|  | 	void handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief handle emits from PriorityMuxer | ||||||
|  | 	/// | ||||||
|  | 	void handlePriorityUpdate(); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Handle imageToLedsMapping updates | ||||||
|  | 	/// | ||||||
|  | 	void handleImageToLedsMappingChange(const int& mappingType); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Handle the adjustment update | ||||||
|  | 	/// | ||||||
|  | 	void handleAdjustmentChange(); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Handle video mode change | ||||||
|  | 	/// @param mode  The new videoMode | ||||||
|  | 	/// | ||||||
|  | 	void handleVideoModeChange(const VideoMode& mode); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Handle effect list change | ||||||
|  | 	/// | ||||||
|  | 	void handleEffectListChange(); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Handle a config part change. This does NOT include (global) changes from other hyperion instances | ||||||
|  | 	/// @param type   The settings type from enum | ||||||
|  | 	/// @param data   The data as QJsonDocument | ||||||
|  | 	/// | ||||||
|  | 	void handleSettingsChange(const settings::type& type, const QJsonDocument& data); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	/// pointer of Hyperion instance | ||||||
|  | 	Hyperion* _hyperion; | ||||||
|  | 	/// pointer of comp register | ||||||
|  | 	ComponentRegister* _componentRegister; | ||||||
|  | 	/// Bonjour instance | ||||||
|  | 	BonjourBrowserWrapper* _bonjour; | ||||||
|  | 	/// priority muxer instance | ||||||
|  | 	PriorityMuxer* _prioMuxer; | ||||||
|  | 	/// contains all available commands | ||||||
|  | 	QStringList _availableCommands; | ||||||
|  | 	/// contains active subscriptions | ||||||
|  | 	QStringList _subscribedCommands; | ||||||
|  | 	/// construct callback msg | ||||||
|  | 	void doCallback(const QString& cmd, const QVariant& data); | ||||||
|  | }; | ||||||
| @@ -31,7 +31,7 @@ public: | |||||||
| 	/// @param hyperion Hyperion instance | 	/// @param hyperion Hyperion instance | ||||||
| 	/// @param port port number on which to start listening for connections | 	/// @param port port number on which to start listening for connections | ||||||
| 	/// | 	/// | ||||||
| 	BoblightServer(const QJsonDocument& config); | 	BoblightServer(Hyperion* hyperion, const QJsonDocument& config); | ||||||
| 	~BoblightServer(); | 	~BoblightServer(); | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
|   | |||||||
| @@ -47,6 +47,8 @@ public: | |||||||
|     void registerService(const BonjourRecord &record, quint16 servicePort, std::vector<std::pair<std::string, std::string>> txt = std::vector<std::pair<std::string, std::string>>()); |     void registerService(const BonjourRecord &record, quint16 servicePort, std::vector<std::pair<std::string, std::string>> txt = std::vector<std::pair<std::string, std::string>>()); | ||||||
|     inline BonjourRecord registeredRecord() const {return finalRecord; } |     inline BonjourRecord registeredRecord() const {return finalRecord; } | ||||||
|  |  | ||||||
|  | 	const quint16 & getPort() { return _port; }; | ||||||
|  |  | ||||||
| signals: | signals: | ||||||
|     void error(DNSServiceErrorType error); |     void error(DNSServiceErrorType error); | ||||||
|     void serviceRegistered(const BonjourRecord &record); |     void serviceRegistered(const BonjourRecord &record); | ||||||
| @@ -62,6 +64,9 @@ private: | |||||||
|     DNSServiceRef dnssref; |     DNSServiceRef dnssref; | ||||||
|     QSocketNotifier *bonjourSocket; |     QSocketNotifier *bonjourSocket; | ||||||
|     BonjourRecord finalRecord; |     BonjourRecord finalRecord; | ||||||
|  |  | ||||||
|  | 	// current port | ||||||
|  | 	quint16 _port = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // BONJOURSERVICEREGISTER_H | #endif // BONJOURSERVICEREGISTER_H | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ | |||||||
| #include "hyperion_request_generated.h" | #include "hyperion_request_generated.h" | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// Connection class to setup an connection to the hyperion server and execute commands. Used from standalone capture binaries (x11/dispamnx/...) | /// Connection class to setup an connection to the hyperion server and execute commands. | ||||||
| /// | /// | ||||||
| class FlatBufferConnection : public QObject | class FlatBufferConnection : public QObject | ||||||
| { | { | ||||||
| @@ -40,7 +40,7 @@ public: | |||||||
| 	~FlatBufferConnection(); | 	~FlatBufferConnection(); | ||||||
|  |  | ||||||
| 	/// Do not read reply messages from Hyperion if set to true | 	/// Do not read reply messages from Hyperion if set to true | ||||||
| 	void setSkipReply(bool skip); | 	void setSkipReply(const bool& skip); | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// Set all leds to the specified color | 	/// Set all leds to the specified color | ||||||
| @@ -116,8 +116,8 @@ private: | |||||||
| 	/// Host port | 	/// Host port | ||||||
| 	uint16_t _port; | 	uint16_t _port; | ||||||
|  |  | ||||||
| 	/// Skip receiving reply messages from Hyperion if set | 	/// buffer for reply | ||||||
| 	bool _skipReply; | 	QByteArray _receiveBuffer; | ||||||
|  |  | ||||||
| 	QTimer _timer; | 	QTimer _timer; | ||||||
| 	QAbstractSocket::SocketState  _prevSocketState; | 	QAbstractSocket::SocketState  _prevSocketState; | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ | |||||||
|  |  | ||||||
| class QTcpServer; | class QTcpServer; | ||||||
| class FlatBufferClient; | class FlatBufferClient; | ||||||
| class NetOrigin; |  | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// @brief A TcpServer to receive images of different formats with Google Flatbuffer | /// @brief A TcpServer to receive images of different formats with Google Flatbuffer | ||||||
| @@ -57,7 +56,6 @@ private: | |||||||
|  |  | ||||||
| private: | private: | ||||||
| 	QTcpServer* _server; | 	QTcpServer* _server; | ||||||
| 	NetOrigin* _netOrigin; |  | ||||||
| 	Logger* _log; | 	Logger* _log; | ||||||
| 	int _timeout; | 	int _timeout; | ||||||
| 	quint16 _port; | 	quint16 _port; | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ public: | |||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	///@brief Set new width and height for dispmanx, overwrite Grabber.h impl | 	///@brief Set new width and height for dispmanx, overwrite Grabber.h impl | ||||||
| 	virtual void setWidthHeight(int width, int height); | 	virtual bool setWidthHeight(int width, int height); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	/// | 	/// | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ | |||||||
| #include <hyperion/Grabber.h> | #include <hyperion/Grabber.h> | ||||||
| #include <grabber/VideoStandard.h> | #include <grabber/VideoStandard.h> | ||||||
|  |  | ||||||
|  | class QTimer; | ||||||
|  |  | ||||||
| /// Capture class for V4L2 devices | /// Capture class for V4L2 devices | ||||||
| /// | /// | ||||||
| /// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html | /// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html | ||||||
| @@ -23,7 +25,6 @@ class V4L2Grabber : public Grabber | |||||||
|  |  | ||||||
| public: | public: | ||||||
| 	V4L2Grabber(const QString & device, | 	V4L2Grabber(const QString & device, | ||||||
| 			int input, |  | ||||||
| 			VideoStandard videoStandard, | 			VideoStandard videoStandard, | ||||||
| 			PixelFormat pixelFormat, | 			PixelFormat pixelFormat, | ||||||
| 			int pixelDecimation | 			int pixelDecimation | ||||||
| @@ -71,7 +72,7 @@ public: | |||||||
| 	/// | 	/// | ||||||
| 	/// @brief overwrite Grabber.h implementation | 	/// @brief overwrite Grabber.h implementation | ||||||
| 	///  | 	///  | ||||||
| 	virtual void setInputVideoStandard(int input, VideoStandard videoStandard); | 	virtual void setDeviceVideoStandard(QString device, VideoStandard videoStandard); | ||||||
|  |  | ||||||
| public slots: | public slots: | ||||||
|  |  | ||||||
| @@ -86,6 +87,11 @@ signals: | |||||||
| private slots: | private slots: | ||||||
| 	int read_frame(); | 	int read_frame(); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Is called whenever the _readFrameAdaptTimer emits to unlock read_frame() through _readFrame bool | ||||||
|  | 	/// | ||||||
|  | 	void unlockReadFrame() { _readFrame = true; }; | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	void getV4Ldevices(); | 	void getV4Ldevices(); | ||||||
|  |  | ||||||
| @@ -161,4 +167,6 @@ private: | |||||||
|  |  | ||||||
| 	bool _initialized; | 	bool _initialized; | ||||||
| 	bool _deviceAutoDiscoverEnabled; | 	bool _deviceAutoDiscoverEnabled; | ||||||
|  | 	QTimer* _readFrameAdaptTimer; | ||||||
|  | 	bool _readFrame = false; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ class V4L2Wrapper : public GrabberWrapper | |||||||
|  |  | ||||||
| public: | public: | ||||||
| 	V4L2Wrapper(const QString & device, | 	V4L2Wrapper(const QString & device, | ||||||
| 			int input, |  | ||||||
| 			VideoStandard videoStandard, | 			VideoStandard videoStandard, | ||||||
| 			PixelFormat pixelFormat, | 			PixelFormat pixelFormat, | ||||||
| 			int pixelDecimation ); | 			int pixelDecimation ); | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ public: | |||||||
| 	/// | 	/// | ||||||
| 	/// @brief Apply new width/height values, overwrite Grabber.h implementation as X11 doesn't use width/height, just pixelDecimation to calc dimensions | 	/// @brief Apply new width/height values, overwrite Grabber.h implementation as X11 doesn't use width/height, just pixelDecimation to calc dimensions | ||||||
| 	/// | 	/// | ||||||
| 	virtual void setWidthHeight(int width, int height); | 	virtual bool setWidthHeight(int width, int height) { return true; }; | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// @brief Apply new pixelDecimation | 	/// @brief Apply new pixelDecimation | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
| #include <utils/Image.h> | #include <utils/Image.h> | ||||||
|  |  | ||||||
| class Hyperion; | class Hyperion; | ||||||
|  | class QTimer; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// @brief Capture Control class which is a interface to the HyperionDaemon native capture classes. | /// @brief Capture Control class which is a interface to the HyperionDaemon native capture classes. | ||||||
| @@ -48,6 +49,11 @@ private slots: | |||||||
| 	/// | 	/// | ||||||
| 	void handleV4lImage(const Image<ColorRgb> & image); | 	void handleV4lImage(const Image<ColorRgb> & image); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Is called from _v4lInactiveTimer to set source after specific time to inactive | ||||||
|  | 	/// | ||||||
|  | 	void setV4lInactive(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	/// Hyperion instance | 	/// Hyperion instance | ||||||
| 	Hyperion* _hyperion; | 	Hyperion* _hyperion; | ||||||
| @@ -59,4 +65,5 @@ private: | |||||||
| 	/// Reflect state of v4l capture and prio | 	/// Reflect state of v4l capture and prio | ||||||
| 	bool _v4lCaptEnabled; | 	bool _v4lCaptEnabled; | ||||||
| 	quint8 _v4lCaptPrio; | 	quint8 _v4lCaptPrio; | ||||||
|  | 	QTimer* _v4lInactiveTimer; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -33,9 +33,9 @@ public: | |||||||
| 	/// | 	/// | ||||||
| 	/// @brief  Check if a component is currently enabled | 	/// @brief  Check if a component is currently enabled | ||||||
| 	/// @param  comp   The component from enum | 	/// @param  comp   The component from enum | ||||||
| 	/// @return        True if component is running else false | 	/// @return        True if component is running else false. Not found is -1 | ||||||
| 	/// | 	/// | ||||||
| 	bool isComponentEnabled(const hyperion::Components& comp) const; | 	int isComponentEnabled(const hyperion::Components& comp) const; | ||||||
|  |  | ||||||
| 	/// contains all components and their state | 	/// contains all components and their state | ||||||
| 	std::map<hyperion::Components, bool> getRegister() { return _componentStates; }; | 	std::map<hyperion::Components, bool> getRegister() { return _componentStates; }; | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ public: | |||||||
| 	/// | 	/// | ||||||
| 	/// @brief Apply new width/height values, on errors (collide with cropping) reject the values | 	/// @brief Apply new width/height values, on errors (collide with cropping) reject the values | ||||||
| 	/// | 	/// | ||||||
| 	virtual void setWidthHeight(int width, int height); | 	virtual bool setWidthHeight(int width, int height); | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// @brief Apply new pixelDecimation (used from x11) | 	/// @brief Apply new pixelDecimation (used from x11) | ||||||
| @@ -66,9 +66,9 @@ public: | |||||||
| 	virtual void setSignalDetectionEnable(bool enable) {}; | 	virtual void setSignalDetectionEnable(bool enable) {}; | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// @brief Apply input and videoStanded (used from v4l) | 	/// @brief Apply device and videoStanded (used from v4l) | ||||||
| 	/// | 	/// | ||||||
| 	virtual void setInputVideoStandard(int input, VideoStandard videoStandard) {}; | 	virtual void setDeviceVideoStandard(QString device, VideoStandard videoStandard) {}; | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// @brief Apply display index (used from x11) | 	/// @brief Apply display index (used from x11) | ||||||
|   | |||||||
| @@ -1,12 +1,13 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <QObject> | #include <QObject> | ||||||
|  | #include <QJsonObject> | ||||||
|  | #include <QJsonArray> | ||||||
| #include <QString> | #include <QString> | ||||||
| #include <QStringList> | #include <QStringList> | ||||||
|  |  | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
| #include <utils/Components.h> | #include <utils/Components.h> | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <utils/Image.h> | #include <utils/Image.h> | ||||||
| #include <utils/ColorRgb.h> | #include <utils/ColorRgb.h> | ||||||
| #include <utils/VideoMode.h> | #include <utils/VideoMode.h> | ||||||
| @@ -98,9 +99,6 @@ protected: | |||||||
|  |  | ||||||
| 	QString _grabberName; | 	QString _grabberName; | ||||||
|  |  | ||||||
| 	/// Pointer to Hyperion for writing led values |  | ||||||
| 	Hyperion * _hyperion; |  | ||||||
|  |  | ||||||
| 	/// The timer for generating events with the specified update rate | 	/// The timer for generating events with the specified update rate | ||||||
| 	QTimer* _timer; | 	QTimer* _timer; | ||||||
|  |  | ||||||
| @@ -110,9 +108,6 @@ protected: | |||||||
| 	/// The Logger instance | 	/// The Logger instance | ||||||
| 	Logger * _log; | 	Logger * _log; | ||||||
|  |  | ||||||
| 	// forwarding enabled |  | ||||||
| 	bool _forward; |  | ||||||
|  |  | ||||||
| 	Grabber *_ggrabber; | 	Grabber *_ggrabber; | ||||||
|  |  | ||||||
| 	/// The image used for grabbing frames | 	/// The image used for grabbing frames | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ class ColorAdjustment; | |||||||
| class SettingsManager; | class SettingsManager; | ||||||
| class BGEffectHandler; | class BGEffectHandler; | ||||||
| class CaptureCont; | class CaptureCont; | ||||||
|  | class BoblightServer; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through | /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through | ||||||
| @@ -105,6 +106,8 @@ public: | |||||||
| 	/// | 	/// | ||||||
| 	PriorityMuxer* getMuxerInstance() { return &_muxer; }; | 	PriorityMuxer* getMuxerInstance() { return &_muxer; }; | ||||||
|  |  | ||||||
|  | 	ImageProcessor* getImageProcessor() { return _imageProcessor; }; | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// @brief Get a setting by settings::type from SettingsManager | 	/// @brief Get a setting by settings::type from SettingsManager | ||||||
| 	/// @param type  The settingsType from enum | 	/// @param type  The settingsType from enum | ||||||
| @@ -145,7 +148,7 @@ public: | |||||||
| 	bool isCurrentPriority(const int priority) const; | 	bool isCurrentPriority(const int priority) const; | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// Returns a list of active priorities | 	/// Returns a list of all registered priorities | ||||||
| 	/// | 	/// | ||||||
| 	/// @return The list with priorities | 	/// @return The list with priorities | ||||||
| 	/// | 	/// | ||||||
| @@ -279,6 +282,13 @@ public slots: | |||||||
| 	/// | 	/// | ||||||
| 	const bool setInputImage(const int priority, const Image<ColorRgb>& image, int64_t timeout_ms = -1, const bool& clearEffect = true); | 	const bool setInputImage(const int priority, const Image<ColorRgb>& image, int64_t timeout_ms = -1, const bool& clearEffect = true); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Set the given priority to inactive | ||||||
|  | 	/// @param priority  The priority | ||||||
|  | 	/// @return True on success false if not found | ||||||
|  | 	/// | ||||||
|  | 	const bool setInputInactive(const quint8& priority); | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// Writes a single color to all the leds for the given time and priority | 	/// Writes a single color to all the leds for the given time and priority | ||||||
| 	/// Registers comp color or provided type against muxer | 	/// Registers comp color or provided type against muxer | ||||||
| @@ -540,4 +550,7 @@ private: | |||||||
| 	std::vector<ColorRgb> _ledBuffer; | 	std::vector<ColorRgb> _ledBuffer; | ||||||
| 	/// buffer for leds (without adjustment) | 	/// buffer for leds (without adjustment) | ||||||
| 	std::vector<ColorRgb> _rawLedBuffer; | 	std::vector<ColorRgb> _rawLedBuffer; | ||||||
|  |  | ||||||
|  | 	/// Boblight instance | ||||||
|  | 	BoblightServer* _boblightServer; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -162,6 +162,13 @@ public: | |||||||
| 	/// | 	/// | ||||||
| 	const bool setInputImage(const int priority, const Image<ColorRgb>& image, int64_t timeout_ms = -1); | 	const bool setInputImage(const int priority, const Image<ColorRgb>& image, int64_t timeout_ms = -1); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Set the given priority to inactive | ||||||
|  | 	/// @param priority  The priority | ||||||
|  | 	/// @return True on success false if not found | ||||||
|  | 	/// | ||||||
|  | 	const bool setInputInactive(const quint8& priority); | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// Clears the specified priority channel and update _currentPriority on success | 	/// Clears the specified priority channel and update _currentPriority on success | ||||||
| 	/// | 	/// | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ | |||||||
| // qt incl | // qt incl | ||||||
| #include <QJsonObject> | #include <QJsonObject> | ||||||
|  |  | ||||||
| class SettingsTable; |  | ||||||
| class Hyperion; | class Hyperion; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| @@ -63,8 +62,6 @@ private: | |||||||
| 	Hyperion* _hyperion; | 	Hyperion* _hyperion; | ||||||
| 	/// Logger instance | 	/// Logger instance | ||||||
| 	Logger* _log; | 	Logger* _log; | ||||||
| 	/// instance of database table interface |  | ||||||
| 	SettingsTable* _sTable; |  | ||||||
| 	/// the schema | 	/// the schema | ||||||
| 	static QJsonObject schemaJson; | 	static QJsonObject schemaJson; | ||||||
| 	/// the current config of this instance | 	/// the current config of this instance | ||||||
|   | |||||||
| @@ -8,12 +8,10 @@ | |||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
| #include <utils/settings.h> | #include <utils/settings.h> | ||||||
|  |  | ||||||
| class Hyperion; |  | ||||||
| class QTcpServer; | class QTcpServer; | ||||||
| class QTcpSocket; | class QTcpSocket; | ||||||
| class JsonClientConnection; | class JsonClientConnection; | ||||||
| class BonjourServiceRegister; | class BonjourServiceRegister; | ||||||
| class ComponentRegister; |  | ||||||
| class NetOrigin; | class NetOrigin; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| @@ -50,12 +48,7 @@ private slots: | |||||||
| 	/// | 	/// | ||||||
| 	void closedConnection(void); | 	void closedConnection(void); | ||||||
|  |  | ||||||
| 	/// forward message to all json slaves |  | ||||||
| 	void forwardJsonMessage(const QJsonObject &message); |  | ||||||
|  |  | ||||||
| public slots: | public slots: | ||||||
| 	/// process current forwarder state |  | ||||||
| 	void componentStateChanged(const hyperion::Components component, bool enable); |  | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// forward message to a single json slaves | 	/// forward message to a single json slaves | ||||||
| @@ -75,18 +68,12 @@ private: | |||||||
| 	/// The TCP server object | 	/// The TCP server object | ||||||
| 	QTcpServer * _server; | 	QTcpServer * _server; | ||||||
|  |  | ||||||
| 	/// Link to Hyperion to get config state emiter |  | ||||||
| 	Hyperion * _hyperion; |  | ||||||
|  |  | ||||||
| 	/// List with open connections | 	/// List with open connections | ||||||
| 	QSet<JsonClientConnection *> _openConnections; | 	QSet<JsonClientConnection *> _openConnections; | ||||||
|  |  | ||||||
| 	/// the logger instance | 	/// the logger instance | ||||||
| 	Logger * _log; | 	Logger * _log; | ||||||
|  |  | ||||||
| 	/// Component Register pointer |  | ||||||
| 	ComponentRegister* _componentRegister; |  | ||||||
|  |  | ||||||
| 	NetOrigin* _netOrigin; | 	NetOrigin* _netOrigin; | ||||||
|  |  | ||||||
| 	/// port | 	/// port | ||||||
|   | |||||||
| @@ -25,8 +25,6 @@ class ProtoConnection; | |||||||
| class QTcpServer; | class QTcpServer; | ||||||
| class Hyperion; | class Hyperion; | ||||||
| class BonjourServiceRegister; | class BonjourServiceRegister; | ||||||
| class ComponentRegister; |  | ||||||
| class NetOrigin; |  | ||||||
|  |  | ||||||
| namespace proto { | namespace proto { | ||||||
| class HyperionRequest; | class HyperionRequest; | ||||||
| @@ -55,8 +53,6 @@ public: | |||||||
| 	uint16_t getPort() const; | 	uint16_t getPort() const; | ||||||
|  |  | ||||||
| public slots: | public slots: | ||||||
| 	void sendImageToProtoSlaves(int priority, const Image<ColorRgb> & image, int duration_ms); |  | ||||||
| 	void componentStateChanged(const hyperion::Components component, bool enable); |  | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor | 	/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor | ||||||
| @@ -65,12 +61,6 @@ public slots: | |||||||
| 	/// | 	/// | ||||||
| 	void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); | 	void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); | ||||||
|  |  | ||||||
| signals: |  | ||||||
| 	/// |  | ||||||
| 	/// Forwarding videoMode |  | ||||||
| 	/// |  | ||||||
| 	void videoMode(const VideoMode VideoMode); |  | ||||||
|  |  | ||||||
| private slots: | private slots: | ||||||
| 	/// | 	/// | ||||||
| 	/// Slot which is called when a client tries to create a new connection | 	/// Slot which is called when a client tries to create a new connection | ||||||
| @@ -83,8 +73,6 @@ private slots: | |||||||
| 	/// | 	/// | ||||||
| 	void closedConnection(ProtoClientConnection * connection); | 	void closedConnection(ProtoClientConnection * connection); | ||||||
|  |  | ||||||
| 	void newMessage(const proto::HyperionRequest * message); |  | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	/// Hyperion instance | 	/// Hyperion instance | ||||||
| 	Hyperion * _hyperion; | 	Hyperion * _hyperion; | ||||||
| @@ -94,26 +82,13 @@ private: | |||||||
|  |  | ||||||
| 	/// List with open connections | 	/// List with open connections | ||||||
| 	QSet<ProtoClientConnection *> _openConnections; | 	QSet<ProtoClientConnection *> _openConnections; | ||||||
| 	QStringList _forwardClients; |  | ||||||
|  |  | ||||||
| 	/// Hyperion proto connection object for forwarding |  | ||||||
| 	QList<ProtoConnection*> _proxy_connections; |  | ||||||
|  |  | ||||||
| 	/// Logger instance | 	/// Logger instance | ||||||
| 	Logger * _log; | 	Logger * _log; | ||||||
|  |  | ||||||
| 	/// Component Register |  | ||||||
| 	ComponentRegister* _componentRegister; |  | ||||||
|  |  | ||||||
| 	/// Network Origin Check |  | ||||||
| 	NetOrigin* _netOrigin; |  | ||||||
|  |  | ||||||
| 	/// Service register | 	/// Service register | ||||||
| 	BonjourServiceRegister * _serviceRegister = nullptr; | 	BonjourServiceRegister * _serviceRegister = nullptr; | ||||||
|  |  | ||||||
| 	/// flag if forwarder is enabled |  | ||||||
| 	bool _forwarder_enabled; |  | ||||||
|  |  | ||||||
| 	uint16_t _port = 0; | 	uint16_t _port = 0; | ||||||
|  |  | ||||||
| 	/// Start server | 	/// Start server | ||||||
|   | |||||||
| @@ -11,15 +11,13 @@ | |||||||
| // Hyperion includes | // Hyperion includes | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
| #include <utils/Components.h> | #include <utils/Components.h> | ||||||
|  | #include <utils/ColorRgb.h> | ||||||
|  |  | ||||||
| // settings | // settings | ||||||
| #include <utils/settings.h> | #include <utils/settings.h> | ||||||
|  |  | ||||||
| class Hyperion; |  | ||||||
| class UDPClientConnection; |  | ||||||
| class BonjourServiceRegister; | class BonjourServiceRegister; | ||||||
| class QUdpSocket; | class QUdpSocket; | ||||||
| class NetOrigin; |  | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// This class creates a UDP server which accepts connections from boblight clients. | /// This class creates a UDP server which accepts connections from boblight clients. | ||||||
| @@ -67,6 +65,22 @@ public slots: | |||||||
| 	/// | 	/// | ||||||
| 	void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); | 	void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  | 	/// | ||||||
|  | 	/// @brief forward register data to HyperionDaemon | ||||||
|  | 	/// | ||||||
|  | 	void registerGlobalInput(const int priority, const hyperion::Components& component, const QString& origin = "System", const QString& owner = "", unsigned smooth_cfg = 0); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief forward led data to HyperionDaemon | ||||||
|  | 	/// | ||||||
|  | 	const bool setGlobalInput(const int priority, const std::vector<ColorRgb>& ledColors, const int timeout_ms = -1, const bool& clearEffect = true); | ||||||
|  |  | ||||||
|  | 	/// | ||||||
|  | 	/// @brief forward clear to HyperionDaemon | ||||||
|  | 	/// | ||||||
|  | 	void clearGlobalPriority(const int& _priority, const hyperion::Components& component); | ||||||
|  |  | ||||||
| private slots: | private slots: | ||||||
| 	/// | 	/// | ||||||
| 	/// Slot which is called when a client tries to create a new connection | 	/// Slot which is called when a client tries to create a new connection | ||||||
| @@ -75,15 +89,10 @@ private slots: | |||||||
| 	void processTheDatagram(const QByteArray * datagram, const QHostAddress * sender); | 	void processTheDatagram(const QByteArray * datagram, const QHostAddress * sender); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	/// Hyperion instance |  | ||||||
| 	Hyperion * _hyperion; |  | ||||||
|  |  | ||||||
| 	/// The UDP server object | 	/// The UDP server object | ||||||
| 	QUdpSocket * _server; | 	QUdpSocket * _server; | ||||||
|  |  | ||||||
| 	/// List with open connections |  | ||||||
| 	QSet<UDPClientConnection *> _openConnections; |  | ||||||
|  |  | ||||||
| 	/// hyperion priority | 	/// hyperion priority | ||||||
| 	int _priority; | 	int _priority; | ||||||
|  |  | ||||||
| @@ -94,7 +103,7 @@ private: | |||||||
| 	Logger * _log; | 	Logger * _log; | ||||||
|  |  | ||||||
| 	/// Bonjour Service Register | 	/// Bonjour Service Register | ||||||
| 	BonjourServiceRegister* _bonjourService = nullptr; | 	BonjourServiceRegister* _serviceRegister = nullptr; | ||||||
|  |  | ||||||
| 	/// state of connection | 	/// state of connection | ||||||
| 	bool _isActive; | 	bool _isActive; | ||||||
| @@ -103,7 +112,4 @@ private: | |||||||
| 	QHostAddress              _listenAddress; | 	QHostAddress              _listenAddress; | ||||||
| 	uint16_t                  _listenPort; | 	uint16_t                  _listenPort; | ||||||
| 	QAbstractSocket::BindFlag _bondage; | 	QAbstractSocket::BindFlag _bondage; | ||||||
|  |  | ||||||
| 	/// Check Network Origin |  | ||||||
| 	NetOrigin* _netOrigin; |  | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -22,7 +22,8 @@ enum Components | |||||||
| 	COMP_IMAGE, | 	COMP_IMAGE, | ||||||
| 	COMP_EFFECT, | 	COMP_EFFECT, | ||||||
| 	COMP_PROTOSERVER, | 	COMP_PROTOSERVER, | ||||||
| 	COMP_LEDDEVICE | 	COMP_LEDDEVICE, | ||||||
|  | 	COMP_FLATBUFSERVER | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline const char* componentToString(Components c) | inline const char* componentToString(Components c) | ||||||
| @@ -42,6 +43,7 @@ inline const char* componentToString(Components c) | |||||||
| 		case COMP_IMAGE:         return "Image"; | 		case COMP_IMAGE:         return "Image"; | ||||||
| 		case COMP_PROTOSERVER:   return "Proto Server"; | 		case COMP_PROTOSERVER:   return "Proto Server"; | ||||||
| 		case COMP_LEDDEVICE:     return "LED device"; | 		case COMP_LEDDEVICE:     return "LED device"; | ||||||
|  | 		case COMP_FLATBUFSERVER:  return "Image Receiver"; | ||||||
| 		default:                 return ""; | 		default:                 return ""; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -63,6 +65,7 @@ inline const char* componentToIdString(Components c) | |||||||
| 		case COMP_IMAGE:         return "IMAGE"; | 		case COMP_IMAGE:         return "IMAGE"; | ||||||
| 		case COMP_PROTOSERVER:   return "PROTOSERVER"; | 		case COMP_PROTOSERVER:   return "PROTOSERVER"; | ||||||
| 		case COMP_LEDDEVICE:     return "LEDDEVICE"; | 		case COMP_LEDDEVICE:     return "LEDDEVICE"; | ||||||
|  | 		case COMP_FLATBUFSERVER: return "FLATBUFSERVER"; | ||||||
| 		default:                 return ""; | 		default:                 return ""; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -83,7 +86,7 @@ inline  Components stringToComponent(QString component) | |||||||
| 	if (component == "IMAGE")         return COMP_IMAGE; | 	if (component == "IMAGE")         return COMP_IMAGE; | ||||||
| 	if (component == "PROTOSERVER")   return COMP_PROTOSERVER; | 	if (component == "PROTOSERVER")   return COMP_PROTOSERVER; | ||||||
| 	if (component == "LEDDEVICE")     return COMP_LEDDEVICE; | 	if (component == "LEDDEVICE")     return COMP_LEDDEVICE; | ||||||
|  | 	if (component == "FLATBUFSERVER") return COMP_FLATBUFSERVER; | ||||||
| 	return COMP_INVALID; | 	return COMP_INVALID; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								include/utils/NetUtils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								include/utils/NetUtils.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <utils/Logger.h> | ||||||
|  |  | ||||||
|  | #include <QTcpServer> | ||||||
|  |  | ||||||
|  | namespace NetUtils { | ||||||
|  | 	/// | ||||||
|  | 	/// @brief Check if the port is available for listening | ||||||
|  | 	/// @param[in/out] port  The port to test, will be incremented if port is in use | ||||||
|  | 	/// @param         log   The logger of the caller to print | ||||||
|  | 	/// @return        True on success else false | ||||||
|  | 	/// | ||||||
|  | 	static const bool portAvailable(quint16& port, Logger* log) | ||||||
|  | 	{ | ||||||
|  | 		const quint16 prevPort = port; | ||||||
|  | 		QTcpServer server; | ||||||
|  | 		bool corrected = false; | ||||||
|  | 		while (!server.listen(QHostAddress::Any, port)) | ||||||
|  | 		{ | ||||||
|  | 			corrected = true; | ||||||
|  | 			Warning(log,"Port '%d' is already in use, will increment", port); | ||||||
|  | 			port ++; | ||||||
|  | 		} | ||||||
|  | 		server.close(); | ||||||
|  | 		if(corrected) | ||||||
|  | 		{ | ||||||
|  | 			Warning(log, "The requested Port '%d' was already in use, will use Port '%d' instead", prevPort, port); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -16,6 +16,14 @@ class Stats : public QObject | |||||||
|  |  | ||||||
| public: | public: | ||||||
| 	Stats(); | 	Stats(); | ||||||
|  | 	static Stats* getInstance() { return instance; }; | ||||||
|  | 	static Stats* instance; | ||||||
|  |  | ||||||
|  | 	void handleDataUpdate(const QJsonObject& config); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	friend class HyperionDaemon; | ||||||
|  | 	Stats(const QJsonObject& config); | ||||||
| 	~Stats(); | 	~Stats(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ enum type  { | |||||||
| 	WEBSERVER, | 	WEBSERVER, | ||||||
| 	INSTCAPTURE, | 	INSTCAPTURE, | ||||||
| 	NETWORK, | 	NETWORK, | ||||||
|  | 	FLATBUFSERVER, | ||||||
| 	INVALID | 	INVALID | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -62,6 +63,7 @@ inline QString typeToString(const type& type) | |||||||
| 		case WEBSERVER:     return "webConfig"; | 		case WEBSERVER:     return "webConfig"; | ||||||
| 		case INSTCAPTURE:   return "instCapture"; | 		case INSTCAPTURE:   return "instCapture"; | ||||||
| 		case NETWORK:       return "network"; | 		case NETWORK:       return "network"; | ||||||
|  | 		case FLATBUFSERVER: return "flatbufServer"; | ||||||
| 		default:            return "invalid"; | 		default:            return "invalid"; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -94,6 +96,7 @@ inline type stringToType(const QString& type) | |||||||
| 	else if (type == "webConfig")            return WEBSERVER; | 	else if (type == "webConfig")            return WEBSERVER; | ||||||
| 	else if (type == "instCapture")          return INSTCAPTURE; | 	else if (type == "instCapture")          return INSTCAPTURE; | ||||||
| 	else if (type == "network")              return NETWORK; | 	else if (type == "network")              return NETWORK; | ||||||
|  | 	else if (type == "flatbufServer")        return FLATBUFSERVER; | ||||||
| 	else                                    return INVALID; | 	else                                    return INVALID; | ||||||
| } | } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -5,13 +5,13 @@ | |||||||
| #include <QString> | #include <QString> | ||||||
| #include <QJsonDocument> | #include <QJsonDocument> | ||||||
|  |  | ||||||
| // hyperion / utils | // utils include | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
|  |  | ||||||
| // settings | // settings | ||||||
| #include <utils/settings.h> | #include <utils/settings.h> | ||||||
|  |  | ||||||
|  | class BonjourServiceRegister; | ||||||
| class StaticFileServing; | class StaticFileServing; | ||||||
| class QtHttpServer; | class QtHttpServer; | ||||||
|  |  | ||||||
| @@ -42,7 +42,6 @@ public slots: | |||||||
|  |  | ||||||
| private: | private: | ||||||
| 	Logger*              _log; | 	Logger*              _log; | ||||||
| 	Hyperion*            _hyperion; |  | ||||||
| 	QString              _baseUrl; | 	QString              _baseUrl; | ||||||
| 	quint16              _port; | 	quint16              _port; | ||||||
| 	StaticFileServing*   _staticFileServing; | 	StaticFileServing*   _staticFileServing; | ||||||
| @@ -50,6 +49,8 @@ private: | |||||||
|  |  | ||||||
| 	const QString        WEBSERVER_DEFAULT_PATH = ":/webconfig"; | 	const QString        WEBSERVER_DEFAULT_PATH = ":/webconfig"; | ||||||
| 	const quint16        WEBSERVER_DEFAULT_PORT = 8090; | 	const quint16        WEBSERVER_DEFAULT_PORT = 8090; | ||||||
|  |  | ||||||
|  | 	BonjourServiceRegister * _serviceRegister = nullptr; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // WEBSERVER_H | #endif // WEBSERVER_H | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ add_subdirectory(commandline) | |||||||
| add_subdirectory(blackborder) | add_subdirectory(blackborder) | ||||||
| add_subdirectory(jsonserver) | add_subdirectory(jsonserver) | ||||||
| add_subdirectory(protoserver) | add_subdirectory(protoserver) | ||||||
|  | add_subdirectory(flatbufserver) | ||||||
| add_subdirectory(bonjour) | add_subdirectory(bonjour) | ||||||
| add_subdirectory(boblightserver) | add_subdirectory(boblightserver) | ||||||
| add_subdirectory(udplistener) | add_subdirectory(udplistener) | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								libsrc/api/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								libsrc/api/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | # Define the current source locations | ||||||
|  |  | ||||||
|  | SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/api) | ||||||
|  | SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/api) | ||||||
|  |  | ||||||
|  | FILE ( GLOB_RECURSE Api_SOURCES "${CURRENT_HEADER_DIR}/*.h"  "${CURRENT_SOURCE_DIR}/*.h"  "${CURRENT_SOURCE_DIR}/*.cpp" ) | ||||||
|  |  | ||||||
|  | set(Api_RESOURCES ${CURRENT_SOURCE_DIR}/JSONRPC_schemas.qrc ) | ||||||
|  |  | ||||||
|  | add_library(hyperion-api | ||||||
|  | 	${Api_SOURCES} | ||||||
|  | 	${Api_RESOURCES} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | target_link_libraries(hyperion-api | ||||||
|  | 	hyperion | ||||||
|  | 	hyperion-utils | ||||||
|  | 	Qt5::Core | ||||||
|  | 	Qt5::Gui | ||||||
|  | 	Qt5::Network | ||||||
|  | ) | ||||||
							
								
								
									
										1069
									
								
								libsrc/api/JsonAPI.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1069
									
								
								libsrc/api/JsonAPI.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										304
									
								
								libsrc/api/JsonCB.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								libsrc/api/JsonCB.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,304 @@ | |||||||
|  | // proj incl | ||||||
|  | #include <api/JsonCB.h> | ||||||
|  |  | ||||||
|  | // hyperion | ||||||
|  | #include <hyperion/Hyperion.h> | ||||||
|  | // components | ||||||
|  | #include <hyperion/ComponentRegister.h> | ||||||
|  | // bonjour wrapper | ||||||
|  | #include <bonjour/bonjourbrowserwrapper.h> | ||||||
|  | // priorityMuxer | ||||||
|  | #include <hyperion/PriorityMuxer.h> | ||||||
|  | #include <utils/ColorSys.h> | ||||||
|  | #include <QDateTime> | ||||||
|  |  | ||||||
|  | // Image to led map helper | ||||||
|  | #include <hyperion/ImageProcessor.h> | ||||||
|  |  | ||||||
|  | using namespace hyperion; | ||||||
|  |  | ||||||
|  | JsonCB::JsonCB(QObject* parent) | ||||||
|  | 	: QObject(parent) | ||||||
|  | 	, _hyperion(Hyperion::getInstance()) | ||||||
|  | 	, _componentRegister(& _hyperion->getComponentRegister()) | ||||||
|  | 	, _bonjour(BonjourBrowserWrapper::getInstance()) | ||||||
|  | 	, _prioMuxer(_hyperion->getMuxerInstance()) | ||||||
|  | { | ||||||
|  | 	_availableCommands << "components-update" << "sessions-update" << "priorities-update" << "imageToLedMapping-update" | ||||||
|  | 	<< "adjustment-update" << "videomode-update" << "effects-update" << "settings-update"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool JsonCB::subscribeFor(const QString& type) | ||||||
|  | { | ||||||
|  | 	if(!_availableCommands.contains(type)) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	if(type == "components-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "sessions-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "priorities-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_prioMuxer, &PriorityMuxer::prioritiesChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection); | ||||||
|  | 		connect(_prioMuxer, &PriorityMuxer::autoSelectChanged, this, &JsonCB::handlePriorityUpdate, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "imageToLedMapping-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCB::handleImageToLedsMappingChange, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "adjustment-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_hyperion, &Hyperion::adjustmentChanged, this, &JsonCB::handleAdjustmentChange, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "videomode-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_hyperion, &Hyperion::newVideoMode, this, &JsonCB::handleVideoModeChange, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "effects-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCB::handleEffectListChange, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(type == "settings-update") | ||||||
|  | 	{ | ||||||
|  | 		_subscribedCommands << type; | ||||||
|  | 		connect(_hyperion, &Hyperion::settingsChanged, this, &JsonCB::handleSettingsChange, Qt::UniqueConnection); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::doCallback(const QString& cmd, const QVariant& data) | ||||||
|  | { | ||||||
|  | 	QJsonObject obj; | ||||||
|  | 	obj["command"] = cmd; | ||||||
|  |  | ||||||
|  | 	if(static_cast<QMetaType::Type>(data.type()) == QMetaType::QJsonArray) | ||||||
|  | 		obj["data"] = data.toJsonArray(); | ||||||
|  | 	else | ||||||
|  | 		obj["data"] = data.toJsonObject(); | ||||||
|  |  | ||||||
|  | 	emit newCallback(obj); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleComponentState(const hyperion::Components comp, const bool state) | ||||||
|  | { | ||||||
|  | 	QJsonObject data; | ||||||
|  | 	data["name"] = componentToIdString(comp); | ||||||
|  | 	data["enabled"] = state; | ||||||
|  |  | ||||||
|  | 	doCallback("components-update", QVariant(data)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters) | ||||||
|  | { | ||||||
|  | 	QJsonArray data; | ||||||
|  | 	for (const auto & session: bRegisters) | ||||||
|  | 	{ | ||||||
|  | 		if (session.port<0) continue; | ||||||
|  | 		QJsonObject item; | ||||||
|  | 		item["name"]   = session.serviceName; | ||||||
|  | 		item["type"]   = session.registeredType; | ||||||
|  | 		item["domain"] = session.replyDomain; | ||||||
|  | 		item["host"]   = session.hostName; | ||||||
|  | 		item["address"]= session.address; | ||||||
|  | 		item["port"]   = session.port; | ||||||
|  | 		data.append(item); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	doCallback("sessions-update", QVariant(data)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handlePriorityUpdate() | ||||||
|  | { | ||||||
|  | 	QJsonObject data; | ||||||
|  | 	QJsonArray priorities; | ||||||
|  | 	uint64_t now = QDateTime::currentMSecsSinceEpoch(); | ||||||
|  | 	QList<int> activePriorities = _prioMuxer->getPriorities(); | ||||||
|  | 	activePriorities.removeAll(255); | ||||||
|  | 	int currentPriority = _prioMuxer->getCurrentPriority(); | ||||||
|  |  | ||||||
|  | 	foreach (int priority, activePriorities) { | ||||||
|  | 		const Hyperion::InputInfo priorityInfo = _prioMuxer->getInputInfo(priority); | ||||||
|  | 		QJsonObject item; | ||||||
|  | 		item["priority"] = priority; | ||||||
|  | 		if (int(priorityInfo.timeoutTime_ms - now) > -1 ) | ||||||
|  | 		{ | ||||||
|  | 			item["duration_ms"] = int(priorityInfo.timeoutTime_ms - now); | ||||||
|  | 		} | ||||||
|  | 		// owner has optional informations to the component | ||||||
|  | 		if(!priorityInfo.owner.isEmpty()) | ||||||
|  | 			item["owner"] = priorityInfo.owner; | ||||||
|  |  | ||||||
|  | 		item["componentId"] = QString(hyperion::componentToIdString(priorityInfo.componentId)); | ||||||
|  | 		item["origin"] = priorityInfo.origin; | ||||||
|  | 		item["active"] = (priorityInfo.timeoutTime_ms >= -1); | ||||||
|  | 		item["visible"] = (priority == currentPriority); | ||||||
|  |  | ||||||
|  | 		if(priorityInfo.componentId == hyperion::COMP_COLOR && !priorityInfo.ledColors.empty()) | ||||||
|  | 		{ | ||||||
|  | 			QJsonObject LEDcolor; | ||||||
|  |  | ||||||
|  | 			// add RGB Value to Array | ||||||
|  | 			QJsonArray RGBValue; | ||||||
|  | 			RGBValue.append(priorityInfo.ledColors.begin()->red); | ||||||
|  | 			RGBValue.append(priorityInfo.ledColors.begin()->green); | ||||||
|  | 			RGBValue.append(priorityInfo.ledColors.begin()->blue); | ||||||
|  | 			LEDcolor.insert("RGB", RGBValue); | ||||||
|  |  | ||||||
|  | 			uint16_t Hue; | ||||||
|  | 			float Saturation, Luminace; | ||||||
|  |  | ||||||
|  | 			// add HSL Value to Array | ||||||
|  | 			QJsonArray HSLValue; | ||||||
|  | 			ColorSys::rgb2hsl(priorityInfo.ledColors.begin()->red, | ||||||
|  | 					priorityInfo.ledColors.begin()->green, | ||||||
|  | 					priorityInfo.ledColors.begin()->blue, | ||||||
|  | 					Hue, Saturation, Luminace); | ||||||
|  |  | ||||||
|  | 			HSLValue.append(Hue); | ||||||
|  | 			HSLValue.append(Saturation); | ||||||
|  | 			HSLValue.append(Luminace); | ||||||
|  | 			LEDcolor.insert("HSL", HSLValue); | ||||||
|  |  | ||||||
|  | 			item["value"] = LEDcolor; | ||||||
|  | 		} | ||||||
|  | 		priorities.append(item); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	data["priorities"] = priorities; | ||||||
|  | 	data["priorities_autoselect"] = _hyperion->sourceAutoSelectEnabled(); | ||||||
|  |  | ||||||
|  | 	doCallback("priorities-update", QVariant(data)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleImageToLedsMappingChange(const int& mappingType) | ||||||
|  | { | ||||||
|  | 	QJsonObject data; | ||||||
|  | 	data["imageToLedMappingType"] = ImageProcessor::mappingTypeToStr(mappingType); | ||||||
|  |  | ||||||
|  | 	doCallback("imageToLedMapping-update", QVariant(data)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleAdjustmentChange() | ||||||
|  | { | ||||||
|  | 	QJsonArray adjustmentArray; | ||||||
|  | 	for (const QString& adjustmentId : _hyperion->getAdjustmentIds()) | ||||||
|  | 	{ | ||||||
|  | 		const ColorAdjustment * colorAdjustment = _hyperion->getAdjustment(adjustmentId); | ||||||
|  | 		if (colorAdjustment == nullptr) | ||||||
|  | 		{ | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		QJsonObject adjustment; | ||||||
|  | 		adjustment["id"] = adjustmentId; | ||||||
|  |  | ||||||
|  | 		QJsonArray whiteAdjust; | ||||||
|  | 		whiteAdjust.append(colorAdjustment->_rgbWhiteAdjustment.getAdjustmentR()); | ||||||
|  | 		whiteAdjust.append(colorAdjustment->_rgbWhiteAdjustment.getAdjustmentG()); | ||||||
|  | 		whiteAdjust.append(colorAdjustment->_rgbWhiteAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("white", whiteAdjust); | ||||||
|  |  | ||||||
|  | 		QJsonArray redAdjust; | ||||||
|  | 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentR()); | ||||||
|  | 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentG()); | ||||||
|  | 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("red", redAdjust); | ||||||
|  |  | ||||||
|  | 		QJsonArray greenAdjust; | ||||||
|  | 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentR()); | ||||||
|  | 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentG()); | ||||||
|  | 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("green", greenAdjust); | ||||||
|  |  | ||||||
|  | 		QJsonArray blueAdjust; | ||||||
|  | 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentR()); | ||||||
|  | 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentG()); | ||||||
|  | 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("blue", blueAdjust); | ||||||
|  |  | ||||||
|  | 		QJsonArray cyanAdjust; | ||||||
|  | 		cyanAdjust.append(colorAdjustment->_rgbCyanAdjustment.getAdjustmentR()); | ||||||
|  | 		cyanAdjust.append(colorAdjustment->_rgbCyanAdjustment.getAdjustmentG()); | ||||||
|  | 		cyanAdjust.append(colorAdjustment->_rgbCyanAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("cyan", cyanAdjust); | ||||||
|  |  | ||||||
|  | 		QJsonArray magentaAdjust; | ||||||
|  | 		magentaAdjust.append(colorAdjustment->_rgbMagentaAdjustment.getAdjustmentR()); | ||||||
|  | 		magentaAdjust.append(colorAdjustment->_rgbMagentaAdjustment.getAdjustmentG()); | ||||||
|  | 		magentaAdjust.append(colorAdjustment->_rgbMagentaAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("magenta", magentaAdjust); | ||||||
|  |  | ||||||
|  | 		QJsonArray yellowAdjust; | ||||||
|  | 		yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentR()); | ||||||
|  | 		yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentG()); | ||||||
|  | 		yellowAdjust.append(colorAdjustment->_rgbYellowAdjustment.getAdjustmentB()); | ||||||
|  | 		adjustment.insert("yellow", yellowAdjust); | ||||||
|  |  | ||||||
|  | 		adjustment["backlightThreshold"] = colorAdjustment->_rgbTransform.getBacklightThreshold(); | ||||||
|  | 		adjustment["backlightColored"]   = colorAdjustment->_rgbTransform.getBacklightColored(); | ||||||
|  | 		adjustment["brightness"] = colorAdjustment->_rgbTransform.getBrightness(); | ||||||
|  | 		adjustment["brightnessCompensation"] = colorAdjustment->_rgbTransform.getBrightnessCompensation(); | ||||||
|  | 		adjustment["gammaRed"]   = colorAdjustment->_rgbTransform.getGammaR(); | ||||||
|  | 		adjustment["gammaGreen"] = colorAdjustment->_rgbTransform.getGammaG(); | ||||||
|  | 		adjustment["gammaBlue"]  = colorAdjustment->_rgbTransform.getGammaB(); | ||||||
|  |  | ||||||
|  | 		adjustmentArray.append(adjustment); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	doCallback("adjustment-update", QVariant(adjustmentArray)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleVideoModeChange(const VideoMode& mode) | ||||||
|  | { | ||||||
|  | 	QJsonObject data; | ||||||
|  | 	data["videomode"] = QString(videoMode2String(mode)); | ||||||
|  | 	doCallback("videomode-update", QVariant(data)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleEffectListChange() | ||||||
|  | { | ||||||
|  | 	QJsonArray effectList; | ||||||
|  | 	QJsonObject effects; | ||||||
|  | 	const std::list<EffectDefinition> & effectsDefinitions = _hyperion->getEffects(); | ||||||
|  | 	for (const EffectDefinition & effectDefinition : effectsDefinitions) | ||||||
|  | 	{ | ||||||
|  | 		QJsonObject effect; | ||||||
|  | 		effect["name"] = effectDefinition.name; | ||||||
|  | 		effect["file"] = effectDefinition.file; | ||||||
|  | 		effect["script"] = effectDefinition.script; | ||||||
|  | 		effect["args"] = effectDefinition.args; | ||||||
|  | 		effectList.append(effect); | ||||||
|  | 	}; | ||||||
|  | 	effects["effects"] = effectList; | ||||||
|  | 	doCallback("effects-update", QVariant(effects)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void JsonCB::handleSettingsChange(const settings::type& type, const QJsonDocument& data) | ||||||
|  | { | ||||||
|  | 	QJsonObject dat; | ||||||
|  | 	if(data.isObject()) | ||||||
|  | 		dat[typeToString(type)] = data.object(); | ||||||
|  | 	else | ||||||
|  | 		dat[typeToString(type)] = data.array(); | ||||||
|  |  | ||||||
|  | 	doCallback("settings-update", QVariant(dat)); | ||||||
|  | } | ||||||
| @@ -50,12 +50,16 @@ void BlackBorderProcessor::handleSettingsUpdate(const settings::type& type, cons | |||||||
| 		_maxInconsistentCnt = obj["maxInconsistentCnt"].toInt(10); | 		_maxInconsistentCnt = obj["maxInconsistentCnt"].toInt(10); | ||||||
| 		_blurRemoveCnt = obj["blurRemoveCnt"].toInt(1); | 		_blurRemoveCnt = obj["blurRemoveCnt"].toInt(1); | ||||||
| 		_detectionMode = obj["mode"].toString("default"); | 		_detectionMode = obj["mode"].toString("default"); | ||||||
|  | 		const double newThreshold = obj["threshold"].toDouble(5.0)/100.0; | ||||||
|  |  | ||||||
| 		if(_oldThreshold != obj["threshold"].toDouble(5.0/100)) | 		if(_oldThreshold != newThreshold) | ||||||
| 		{ | 		{ | ||||||
| 			_oldThreshold = obj["threshold"].toDouble(5.0/100); | 			_oldThreshold = newThreshold; | ||||||
| 			if(_detector != nullptr) delete _detector; |  | ||||||
| 			_detector = new BlackBorderDetector(obj["threshold"].toDouble(5.0/100)); | 			if(_detector != nullptr) | ||||||
|  | 				delete _detector; | ||||||
|  |  | ||||||
|  | 			_detector = new BlackBorderDetector(newThreshold); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Debug(Logger::getInstance("BLACKBORDER"), "Set mode to: %s", QSTRING_CSTR(_detectionMode)); | 		Debug(Logger::getInstance("BLACKBORDER"), "Set mode to: %s", QSTRING_CSTR(_detectionMode)); | ||||||
|   | |||||||
| @@ -15,23 +15,22 @@ | |||||||
| #include <QHostInfo> | #include <QHostInfo> | ||||||
|  |  | ||||||
| // hyperion util includes | // hyperion util includes | ||||||
| //#include "hyperion/ImageProcessorFactory.h" | #include <hyperion/ImageProcessor.h> | ||||||
| //#include "hyperion/ImageProcessor.h" |  | ||||||
| #include "utils/ColorRgb.h" |  | ||||||
| #include "HyperionConfig.h" | #include "HyperionConfig.h" | ||||||
|  | #include <hyperion/Hyperion.h> | ||||||
|  |  | ||||||
| // project includes | // project includes | ||||||
| #include "BoblightClientConnection.h" | #include "BoblightClientConnection.h" | ||||||
|  |  | ||||||
| BoblightClientConnection::BoblightClientConnection(QTcpSocket *socket, const int priority) | BoblightClientConnection::BoblightClientConnection(Hyperion* hyperion, QTcpSocket *socket, const int priority) | ||||||
| 	: QObject() | 	: QObject() | ||||||
| 	, _locale(QLocale::C) | 	, _locale(QLocale::C) | ||||||
| 	, _socket(socket) | 	, _socket(socket) | ||||||
| 	//, _imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor()) | 	, _imageProcessor(hyperion->getImageProcessor()) | ||||||
| 	, _hyperion(Hyperion::getInstance()) | 	, _hyperion(hyperion) | ||||||
| 	, _receiveBuffer() | 	, _receiveBuffer() | ||||||
| 	, _priority(priority) | 	, _priority(priority) | ||||||
| 	, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb::BLACK) | 	, _ledColors(hyperion->getLedCount(), ColorRgb::BLACK) | ||||||
| 	, _log(Logger::getInstance("BOBLIGHT")) | 	, _log(Logger::getInstance("BOBLIGHT")) | ||||||
| 	, _clientAddress(QHostInfo::fromName(socket->peerAddress().toString()).hostName()) | 	, _clientAddress(QHostInfo::fromName(socket->peerAddress().toString()).hostName()) | ||||||
| { | { | ||||||
| @@ -227,11 +226,11 @@ void BoblightClientConnection::sendLightMessage() | |||||||
| 	int n = snprintf(buffer, sizeof(buffer), "lights %d\n", _hyperion->getLedCount()); | 	int n = snprintf(buffer, sizeof(buffer), "lights %d\n", _hyperion->getLedCount()); | ||||||
| 	sendMessage(QByteArray(buffer, n)); | 	sendMessage(QByteArray(buffer, n)); | ||||||
|  |  | ||||||
| 	//double h0, h1, v0, v1; | 	double h0, h1, v0, v1; | ||||||
| 	for (unsigned i = 0; i < _hyperion->getLedCount(); ++i) | 	for (unsigned i = 0; i < _hyperion->getLedCount(); ++i) | ||||||
| 	{ | 	{ | ||||||
| 		//_imageProcessor->getScanParameters(i, h0, h1, v0, v1); | 		_imageProcessor->getScanParameters(i, h0, h1, v0, v1); | ||||||
| 		//n = snprintf(buffer, sizeof(buffer), "light %03d scan %f %f %f %f\n", i, 100*v0, 100*v1, 100*h0, 100*h1); | 		n = snprintf(buffer, sizeof(buffer), "light %03d scan %f %f %f %f\n", i, 100*v0, 100*v1, 100*h0, 100*h1); | ||||||
| 		//sendMessage(QByteArray(buffer, n)); | 		sendMessage(QByteArray(buffer, n)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,9 +5,12 @@ | |||||||
| #include <QTcpSocket> | #include <QTcpSocket> | ||||||
| #include <QLocale> | #include <QLocale> | ||||||
|  |  | ||||||
| // Hyperion includes | // utils includes | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
|  | #include <utils/ColorRgb.h> | ||||||
|  |  | ||||||
|  | class ImageProcessor; | ||||||
|  | class Hyperion; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// The Connection object created by \a BoblightServer when a new connection is establshed | /// The Connection object created by \a BoblightServer when a new connection is establshed | ||||||
| @@ -22,7 +25,7 @@ public: | |||||||
| 	/// @param socket The Socket object for this connection | 	/// @param socket The Socket object for this connection | ||||||
| 	/// @param hyperion The Hyperion server | 	/// @param hyperion The Hyperion server | ||||||
| 	/// | 	/// | ||||||
| 	BoblightClientConnection(QTcpSocket * socket, const int priority); | 	BoblightClientConnection(Hyperion* hyperion, QTcpSocket * socket, const int priority); | ||||||
|  |  | ||||||
| 	/// | 	/// | ||||||
| 	/// Destructor | 	/// Destructor | ||||||
| @@ -74,6 +77,9 @@ private: | |||||||
| 	/// The TCP-Socket that is connected tot the boblight-client | 	/// The TCP-Socket that is connected tot the boblight-client | ||||||
| 	QTcpSocket * _socket; | 	QTcpSocket * _socket; | ||||||
|  |  | ||||||
|  | 	/// The processor for translating images to led-values | ||||||
|  | 	ImageProcessor * _imageProcessor; | ||||||
|  |  | ||||||
| 	/// Link to Hyperion for writing led-values to a priority channel | 	/// Link to Hyperion for writing led-values to a priority channel | ||||||
| 	Hyperion * _hyperion; | 	Hyperion * _hyperion; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,9 +12,9 @@ | |||||||
|  |  | ||||||
| using namespace hyperion; | using namespace hyperion; | ||||||
|  |  | ||||||
| BoblightServer::BoblightServer(const QJsonDocument& config) | BoblightServer::BoblightServer(Hyperion* hyperion,const QJsonDocument& config) | ||||||
| 	: QObject() | 	: QObject() | ||||||
| 	, _hyperion(Hyperion::getInstance()) | 	, _hyperion(hyperion) | ||||||
| 	, _server(new QTcpServer(this)) | 	, _server(new QTcpServer(this)) | ||||||
| 	, _openConnections() | 	, _openConnections() | ||||||
| 	, _priority(0) | 	, _priority(0) | ||||||
| @@ -96,7 +96,7 @@ void BoblightServer::newConnection() | |||||||
| 	{ | 	{ | ||||||
| 		Info(_log, "new connection"); | 		Info(_log, "new connection"); | ||||||
| 		_hyperion->registerInput(_priority, hyperion::COMP_BOBLIGHTSERVER, QString("Boblight@%1").arg(socket->peerAddress().toString())); | 		_hyperion->registerInput(_priority, hyperion::COMP_BOBLIGHTSERVER, QString("Boblight@%1").arg(socket->peerAddress().toString())); | ||||||
| 		BoblightClientConnection * connection = new BoblightClientConnection(socket, _priority); | 		BoblightClientConnection * connection = new BoblightClientConnection(_hyperion, socket, _priority); | ||||||
| 		_openConnections.insert(connection); | 		_openConnections.insert(connection); | ||||||
|  |  | ||||||
| 		// register slot for cleaning up after the connection closed | 		// register slot for cleaning up after the connection closed | ||||||
|   | |||||||
| @@ -34,8 +34,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||||
|  |  | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
| #include <HyperionConfig.h> | #include <HyperionConfig.h> | ||||||
| #include <hyperion/Hyperion.h> | #include <utils/Stats.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| BonjourServiceRegister::BonjourServiceRegister(QObject *parent) | BonjourServiceRegister::BonjourServiceRegister(QObject *parent) | ||||||
|     : QObject(parent), dnssref(0), bonjourSocket(0) |     : QObject(parent), dnssref(0), bonjourSocket(0) | ||||||
| @@ -54,10 +53,11 @@ BonjourServiceRegister::~BonjourServiceRegister() | |||||||
|  |  | ||||||
| void BonjourServiceRegister::registerService(const QString& service, const int& port) | void BonjourServiceRegister::registerService(const QString& service, const int& port) | ||||||
| { | { | ||||||
|  | 	_port = port; | ||||||
| 	// zeroconf $configname@$hostname:port | 	// zeroconf $configname@$hostname:port | ||||||
| 	QString prettyName = Hyperion::getInstance()->getQJsonConfig()["general"].toObject()["name"].toString(); | 	// TODO add name of the main instance | ||||||
| 	registerService( | 	registerService( | ||||||
| 		BonjourRecord(prettyName+"@"+QHostInfo::localHostName()+ ":" + QString::number(port), | 		BonjourRecord(QHostInfo::localHostName()+ ":" + QString::number(port), | ||||||
| 			service, | 			service, | ||||||
| 			QString() | 			QString() | ||||||
| 		), | 		), | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| find_package(PythonLibs 3.4 REQUIRED) | find_package(PythonLibs 3.5 REQUIRED) | ||||||
|  |  | ||||||
| # Include the python directory. Also include the parent (which is for example /usr/include) | # Include the python directory. Also include the parent (which is for example /usr/include) | ||||||
| # which may be required when it is not includes by the (cross-) compiler by default. | # which may be required when it is not includes by the (cross-) compiler by default. | ||||||
|   | |||||||
| @@ -81,7 +81,7 @@ void Effect::run() | |||||||
| 	PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", _hyperion->getLedCount())); | 	PyObject_SetAttrString(module, "ledCount", Py_BuildValue("i", _hyperion->getLedCount())); | ||||||
|  |  | ||||||
| 	// add minimumWriteTime variable to the interpreter | 	// add minimumWriteTime variable to the interpreter | ||||||
| 	PyObject_SetAttrString(module, "latchTime", Py_BuildValue("i", Hyperion::getInstance()->getLatchTime())); | 	PyObject_SetAttrString(module, "latchTime", Py_BuildValue("i", _hyperion->getLatchTime())); | ||||||
|  |  | ||||||
| 	// add a args variable to the interpreter | 	// add a args variable to the interpreter | ||||||
| 	PyObject_SetAttrString(module, "args", EffectModule::json2python(_args)); | 	PyObject_SetAttrString(module, "args", EffectModule::json2python(_args)); | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ FlatBufferClient::FlatBufferClient(QTcpSocket* socket, const int &timeout, QObje | |||||||
|  |  | ||||||
| void FlatBufferClient::readyRead() | void FlatBufferClient::readyRead() | ||||||
| { | { | ||||||
| 	qDebug()<<"readyRead"; |  | ||||||
| 	_timeoutTimer->start(); | 	_timeoutTimer->start(); | ||||||
|  |  | ||||||
| 	_receiveBuffer += _socket->readAll(); | 	_receiveBuffer += _socket->readAll(); | ||||||
| @@ -37,7 +36,6 @@ void FlatBufferClient::readyRead() | |||||||
| 	// check if we can read a header | 	// check if we can read a header | ||||||
| 	while(_receiveBuffer.size() >= 4) | 	while(_receiveBuffer.size() >= 4) | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
| 		uint32_t messageSize = | 		uint32_t messageSize = | ||||||
| 			((_receiveBuffer[0]<<24) & 0xFF000000) | | 			((_receiveBuffer[0]<<24) & 0xFF000000) | | ||||||
| 			((_receiveBuffer[1]<<16) & 0x00FF0000) | | 			((_receiveBuffer[1]<<16) & 0x00FF0000) | | ||||||
| @@ -47,10 +45,11 @@ void FlatBufferClient::readyRead() | |||||||
| 		// check if we can read a complete message | 		// check if we can read a complete message | ||||||
| 		if((uint32_t) _receiveBuffer.size() < messageSize + 4) return; | 		if((uint32_t) _receiveBuffer.size() < messageSize + 4) return; | ||||||
|  |  | ||||||
| 		// remove header + msg from buffer | 		// extract message only and remove header + msg from buffer :: QByteArray::remove() does not return the removed data | ||||||
| 		const QByteArray& msg = _receiveBuffer.remove(0, messageSize + 4); | 		const QByteArray msg = _receiveBuffer.right(messageSize); | ||||||
|  | 		_receiveBuffer.remove(0, messageSize + 4); | ||||||
|  |  | ||||||
| 		const uint8_t* msgData = reinterpret_cast<const uint8_t*>(msg.mid(3, messageSize).constData()); | 		const uint8_t* msgData = reinterpret_cast<const uint8_t*>(msg.constData()); | ||||||
| 		flatbuffers::Verifier verifier(msgData, messageSize); | 		flatbuffers::Verifier verifier(msgData, messageSize); | ||||||
|  |  | ||||||
| 		if (flatbuf::VerifyHyperionRequestBuffer(verifier)) | 		if (flatbuf::VerifyHyperionRequestBuffer(verifier)) | ||||||
| @@ -59,7 +58,6 @@ void FlatBufferClient::readyRead() | |||||||
| 			handleMessage(message); | 			handleMessage(message); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		qDebug()<<"Unable to pasrse msg"; |  | ||||||
| 		sendErrorReply("Unable to parse message"); | 		sendErrorReply("Unable to parse message"); | ||||||
| 	} | 	} | ||||||
| 		//emit newMessage(msgData,messageSize); | 		//emit newMessage(msgData,messageSize); | ||||||
|   | |||||||
| @@ -7,16 +7,15 @@ | |||||||
| // protoserver includes | // protoserver includes | ||||||
| #include <flatbufserver/FlatBufferConnection.h> | #include <flatbufserver/FlatBufferConnection.h> | ||||||
|  |  | ||||||
| FlatBufferConnection::FlatBufferConnection(const QString & address) : | FlatBufferConnection::FlatBufferConnection(const QString & address) | ||||||
| 	_socket(), | 	: _socket() | ||||||
| 	_skipReply(false), | 	, _prevSocketState(QAbstractSocket::UnconnectedState) | ||||||
| 	_prevSocketState(QAbstractSocket::UnconnectedState), | 	, _log(Logger::getInstance("FLATBUFCONNECTION")) | ||||||
| 	_log(Logger::getInstance("FLATBUFCONNECTION")) | { | ||||||
| 	{ |  | ||||||
| 	QStringList parts = address.split(":"); | 	QStringList parts = address.split(":"); | ||||||
| 	if (parts.size() != 2) | 	if (parts.size() != 2) | ||||||
| 	{ | 	{ | ||||||
| 		throw std::runtime_error(QString("FLATBUFCONNECTION ERROR: Wrong address: Unable to parse address (%1)").arg(address).toStdString()); | 		throw std::runtime_error(QString("FLATBUFCONNECTION ERROR: Unable to parse address (%1)").arg(address).toStdString()); | ||||||
| 	} | 	} | ||||||
| 	_host = parts[0]; | 	_host = parts[0]; | ||||||
|  |  | ||||||
| @@ -24,19 +23,17 @@ FlatBufferConnection::FlatBufferConnection(const QString & address) : | |||||||
| 	_port = parts[1].toUShort(&ok); | 	_port = parts[1].toUShort(&ok); | ||||||
| 	if (!ok) | 	if (!ok) | ||||||
| 	{ | 	{ | ||||||
| 		throw std::runtime_error(QString("FLATBUFCONNECTION ERROR: Wrong port: Unable to parse the port number (%1)").arg(parts[1]).toStdString()); | 		throw std::runtime_error(QString("FLATBUFCONNECTION ERROR: Unable to parse the port (%1)").arg(parts[1]).toStdString()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// try to connect to host | 	// init connect | ||||||
| 	Info(_log, "Connecting to Hyperion: %s:%d", _host.toStdString().c_str(), _port); | 	Info(_log, "Connecting to Hyperion: %s:%d", _host.toStdString().c_str(), _port); | ||||||
| 	connectToHost(); | 	connectToHost(); | ||||||
|  |  | ||||||
| 	// start the connection timer | 	// start the connection timer | ||||||
| 	_timer.setInterval(5000); | 	_timer.setInterval(5000); | ||||||
| 	_timer.setSingleShot(false); |  | ||||||
|  |  | ||||||
| 	connect(&_timer,SIGNAL(timeout()), this, SLOT(connectToHost())); | 	connect(&_timer, &QTimer::timeout, this, &FlatBufferConnection::connectToHost); | ||||||
| 	connect(&_socket, SIGNAL(readyRead()), this, SLOT(readData())); |  | ||||||
| 	_timer.start(); | 	_timer.start(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -48,48 +45,43 @@ FlatBufferConnection::~FlatBufferConnection() | |||||||
|  |  | ||||||
| void FlatBufferConnection::readData() | void FlatBufferConnection::readData() | ||||||
| { | { | ||||||
| 	qint64 bytesAvail; | 	_receiveBuffer += _socket.readAll(); | ||||||
| 	while((bytesAvail = _socket.bytesAvailable())) |  | ||||||
|  | 	// check if we can read a header | ||||||
|  | 	while(_receiveBuffer.size() >= 4) | ||||||
| 	{ | 	{ | ||||||
| 		// ignore until we get 4 bytes. | 		uint32_t messageSize = | ||||||
| 		if (bytesAvail < 4) { | 			((_receiveBuffer[0]<<24) & 0xFF000000) | | ||||||
|  | 			((_receiveBuffer[1]<<16) & 0x00FF0000) | | ||||||
|  | 			((_receiveBuffer[2]<< 8) & 0x0000FF00) | | ||||||
|  | 			((_receiveBuffer[3]    ) & 0x000000FF); | ||||||
|  |  | ||||||
|  | 		// check if we can read a complete message | ||||||
|  | 		if((uint32_t) _receiveBuffer.size() < messageSize + 4) return; | ||||||
|  |  | ||||||
|  | 		// extract message only and remove header + msg from buffer :: QByteArray::remove() does not return the removed data | ||||||
|  | 		const QByteArray msg = _receiveBuffer.right(messageSize); | ||||||
|  | 		_receiveBuffer.remove(0, messageSize + 4); | ||||||
|  |  | ||||||
|  | 		const uint8_t* msgData = reinterpret_cast<const uint8_t*>(msg.constData()); | ||||||
|  | 		flatbuffers::Verifier verifier(msgData, messageSize); | ||||||
|  |  | ||||||
|  | 		if (flatbuf::VerifyHyperionReplyBuffer(verifier)) | ||||||
|  | 		{ | ||||||
|  | 			auto message = flatbuf::GetHyperionReply(msgData); | ||||||
|  | 			parseReply(message); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  | 		Error(_log, "Unable to parse reply"); | ||||||
| 		char sizeBuf[4]; |  | ||||||
| 		 _socket.read(sizeBuf, sizeof(sizeBuf)); |  | ||||||
|  |  | ||||||
| 		uint32_t messageSize = |  | ||||||
| 			((sizeBuf[0]<<24) & 0xFF000000) | |  | ||||||
| 			((sizeBuf[1]<<16) & 0x00FF0000) | |  | ||||||
| 			((sizeBuf[2]<< 8) & 0x0000FF00) | |  | ||||||
| 			((sizeBuf[3]    ) & 0x000000FF); |  | ||||||
|  |  | ||||||
| 		QByteArray buffer; |  | ||||||
| 		while((uint32_t)buffer.size() < messageSize) |  | ||||||
| 		{ |  | ||||||
| 			_socket.waitForReadyRead(); |  | ||||||
| 			buffer.append(_socket.read(messageSize - buffer.size())); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		const uint8_t* replyData = reinterpret_cast<const uint8_t*>(buffer.constData()); |  | ||||||
| 		flatbuffers::Verifier verifier(replyData, messageSize); |  | ||||||
|  |  | ||||||
| 		if (!flatbuf::VerifyHyperionReplyBuffer(verifier)) |  | ||||||
| 		{ |  | ||||||
| 			Error(_log, "Error while reading data from host"); |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		auto reply = flatbuf::GetHyperionReply(replyData); |  | ||||||
|  |  | ||||||
| 		parseReply(reply); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void FlatBufferConnection::setSkipReply(bool skip) | void FlatBufferConnection::setSkipReply(const bool& skip) | ||||||
| { | { | ||||||
| 	_skipReply = skip; | 	if(skip) | ||||||
|  | 		disconnect(&_socket, &QTcpSocket::readyRead, 0, 0); | ||||||
|  | 	else | ||||||
|  | 		connect(&_socket, &QTcpSocket::readyRead, this, &FlatBufferConnection::readData, Qt::UniqueConnection); | ||||||
| } | } | ||||||
|  |  | ||||||
| void FlatBufferConnection::setColor(const ColorRgb & color, int priority, int duration) | void FlatBufferConnection::setColor(const ColorRgb & color, int priority, int duration) | ||||||
| @@ -190,8 +182,6 @@ bool FlatBufferConnection::parseReply(const flatbuf::HyperionReply *reply) | |||||||
| 	switch (reply->type()) | 	switch (reply->type()) | ||||||
| 	{ | 	{ | ||||||
| 		case flatbuf::Type_REPLY: | 		case flatbuf::Type_REPLY: | ||||||
| 		{ |  | ||||||
| 			if (!_skipReply) |  | ||||||
| 		{ | 		{ | ||||||
| 			if (!reply->success()) | 			if (!reply->success()) | ||||||
| 			{ | 			{ | ||||||
| @@ -208,7 +198,7 @@ bool FlatBufferConnection::parseReply(const flatbuf::HyperionReply *reply) | |||||||
| 			{ | 			{ | ||||||
| 				success = true; | 				success = true; | ||||||
| 			} | 			} | ||||||
| 			} |  | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		case flatbuf::Type_VIDEO: | 		case flatbuf::Type_VIDEO: | ||||||
|   | |||||||
| @@ -6,10 +6,6 @@ | |||||||
| #include <QTcpServer> | #include <QTcpServer> | ||||||
| #include <QTcpSocket> | #include <QTcpSocket> | ||||||
|  |  | ||||||
|  |  | ||||||
| #include <QDebug> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| FlatBufferServer::FlatBufferServer(const QJsonDocument& config, QObject* parent) | FlatBufferServer::FlatBufferServer(const QJsonDocument& config, QObject* parent) | ||||||
| 	: QObject(parent) | 	: QObject(parent) | ||||||
| 	, _server(new QTcpServer(this)) | 	, _server(new QTcpServer(this)) | ||||||
| @@ -28,7 +24,6 @@ FlatBufferServer::~FlatBufferServer() | |||||||
|  |  | ||||||
| void FlatBufferServer::initServer() | void FlatBufferServer::initServer() | ||||||
| { | { | ||||||
| 	qDebug()<<"Thread in InitServer is"<<this->thread(); |  | ||||||
| 	connect(_server, &QTcpServer::newConnection, this, &FlatBufferServer::newConnection); | 	connect(_server, &QTcpServer::newConnection, this, &FlatBufferServer::newConnection); | ||||||
|  |  | ||||||
| 	// apply config | 	// apply config | ||||||
| @@ -37,7 +32,6 @@ void FlatBufferServer::initServer() | |||||||
|  |  | ||||||
| void FlatBufferServer::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | void FlatBufferServer::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | ||||||
| { | { | ||||||
| 	qDebug()<<"Thread in handleSettingsUpdate is"<<this->thread(); |  | ||||||
| 	if(type == settings::FLATBUFSERVER) | 	if(type == settings::FLATBUFSERVER) | ||||||
| 	{ | 	{ | ||||||
| 		const QJsonObject& obj = config.object(); | 		const QJsonObject& obj = config.object(); | ||||||
| @@ -60,7 +54,6 @@ void FlatBufferServer::handleSettingsUpdate(const settings::type& type, const QJ | |||||||
|  |  | ||||||
| void FlatBufferServer::newConnection() | void FlatBufferServer::newConnection() | ||||||
| { | { | ||||||
| 	qDebug()<<"Thread in newConnection is"<<this->thread(); |  | ||||||
| 	while(_server->hasPendingConnections()) | 	while(_server->hasPendingConnections()) | ||||||
| 	{ | 	{ | ||||||
| 		if(QTcpSocket* socket = _server->nextPendingConnection()) | 		if(QTcpSocket* socket = _server->nextPendingConnection()) | ||||||
|   | |||||||
| @@ -30,12 +30,19 @@ DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned | |||||||
| 	int result = vc_dispmanx_display_get_info(_vc_display, &vc_info); | 	int result = vc_dispmanx_display_get_info(_vc_display, &vc_info); | ||||||
| 	// Keep compiler happy in 'release' mode | 	// Keep compiler happy in 'release' mode | ||||||
| 	(void)result; | 	(void)result; | ||||||
| 	assert(result == 0); |  | ||||||
| 	Info(_log, "Display opened with resolution: %dx%d", vc_info.width, vc_info.height); |  | ||||||
|  |  | ||||||
| 	// Close the displaye | 	// Close the display | ||||||
| 	vc_dispmanx_display_close(_vc_display); | 	vc_dispmanx_display_close(_vc_display); | ||||||
|  |  | ||||||
|  | 	if(result != 0) | ||||||
|  | 	{ | ||||||
|  | 		Error(_log, "Failed to open display! Probably no permissions to access the capture interface"); | ||||||
|  | 		setEnabled(false); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 		Info(_log, "Display opened with resolution: %dx%d", vc_info.width, vc_info.height); | ||||||
|  |  | ||||||
| 	// init the resource and capture rectangle | 	// init the resource and capture rectangle | ||||||
| 	setWidthHeight(width, height); | 	setWidthHeight(width, height); | ||||||
| } | } | ||||||
| @@ -55,11 +62,12 @@ void DispmanxFrameGrabber::freeResources() | |||||||
| 	vc_dispmanx_resource_delete(_vc_resource); | 	vc_dispmanx_resource_delete(_vc_resource); | ||||||
| } | } | ||||||
|  |  | ||||||
| void DispmanxFrameGrabber::setWidthHeight(int width, int height) | bool DispmanxFrameGrabber::setWidthHeight(int width, int height) | ||||||
| { | { | ||||||
| 	if(_width != width || _height != height) | 	if(Grabber::setWidthHeight(width, height)) | ||||||
| 	{ | 	{ | ||||||
| 		freeResources(); | 		if(_vc_resource != 0) | ||||||
|  | 			vc_dispmanx_resource_delete(_vc_resource); | ||||||
| 		// Create the resources for capturing image | 		// Create the resources for capturing image | ||||||
| 		uint32_t vc_nativeImageHandle; | 		uint32_t vc_nativeImageHandle; | ||||||
| 		_vc_resource = vc_dispmanx_resource_create( | 		_vc_resource = vc_dispmanx_resource_create( | ||||||
| @@ -71,7 +79,9 @@ void DispmanxFrameGrabber::setWidthHeight(int width, int height) | |||||||
|  |  | ||||||
| 		// Define the capture rectangle with the same size | 		// Define the capture rectangle with the same size | ||||||
| 		vc_dispmanx_rect_set(&_rectangle, 0, 0, width, height); | 		vc_dispmanx_rect_set(&_rectangle, 0, 0, width, height); | ||||||
|  | 		return true; | ||||||
| 	} | 	} | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void DispmanxFrameGrabber::setFlags(const int vc_flags) | void DispmanxFrameGrabber::setFlags(const int vc_flags) | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHe | |||||||
| 	: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz) | 	: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz) | ||||||
| 	, _grabber(grabWidth, grabHeight) | 	, _grabber(grabWidth, grabHeight) | ||||||
| { | { | ||||||
| 	setImageProcessorEnabled(false); | 	 | ||||||
| } | } | ||||||
|  |  | ||||||
| void DispmanxWrapper::action() | void DispmanxWrapper::action() | ||||||
|   | |||||||
| @@ -82,7 +82,14 @@ void OsxFrameGrabber::setDisplayIndex(int index) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		image = CGDisplayCreateImage(_display); | 		image = CGDisplayCreateImage(_display); | ||||||
| 		assert(image != NULL); | 		if(image == NULL) | ||||||
|  | 		{ | ||||||
|  | 			Error(_log, "Failed to open main display, disable capture interface"); | ||||||
|  | 			setEnabled(false); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 			setEnabled(true); | ||||||
|  |  | ||||||
| 		Info(_log, "Display opened with resolution: %dx%d@%dbit", CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerPixel(image)); | 		Info(_log, "Display opened with resolution: %dx%d@%dbit", CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerPixel(image)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,29 +18,29 @@ | |||||||
|  |  | ||||||
| #include <QDirIterator> | #include <QDirIterator> | ||||||
| #include <QFileInfo> | #include <QFileInfo> | ||||||
|  | #include <QTimer> | ||||||
|  |  | ||||||
| #include "grabber/V4L2Grabber.h" | #include "grabber/V4L2Grabber.h" | ||||||
|  |  | ||||||
| #define CLEAR(x) memset(&(x), 0, sizeof(x)) | #define CLEAR(x) memset(&(x), 0, sizeof(x)) | ||||||
|  |  | ||||||
| V4L2Grabber::V4L2Grabber(const QString & device | V4L2Grabber::V4L2Grabber(const QString & device | ||||||
| 		, int input |  | ||||||
| 		, VideoStandard videoStandard | 		, VideoStandard videoStandard | ||||||
| 		, PixelFormat pixelFormat | 		, PixelFormat pixelFormat | ||||||
| 		, int pixelDecimation | 		, int pixelDecimation | ||||||
| 		) | 		) | ||||||
| 	: Grabber("V4L2:"+device) | 	: Grabber("V4L2:"+device) | ||||||
| 	, _deviceName(device) | 	, _deviceName() | ||||||
| 	, _input(input) | 	, _input(-1) | ||||||
| 	, _videoStandard(videoStandard) | 	, _videoStandard(videoStandard) | ||||||
| 	, _ioMethod(IO_METHOD_MMAP) | 	, _ioMethod(IO_METHOD_MMAP) | ||||||
| 	, _fileDescriptor(-1) | 	, _fileDescriptor(-1) | ||||||
| 	, _buffers() | 	, _buffers() | ||||||
| 	, _pixelFormat(pixelFormat) | 	, _pixelFormat(pixelFormat) | ||||||
| 	, _pixelDecimation(pixelDecimation) | 	, _pixelDecimation(-1) | ||||||
| 	, _lineLength(-1) | 	, _lineLength(-1) | ||||||
| 	, _frameByteSize(-1) | 	, _frameByteSize(-1) | ||||||
| 	, _noSignalCounterThreshold(50) | 	, _noSignalCounterThreshold(40) | ||||||
| 	, _noSignalThresholdColor(ColorRgb{0,0,0}) | 	, _noSignalThresholdColor(ColorRgb{0,0,0}) | ||||||
| 	, _signalDetectionEnabled(true) | 	, _signalDetectionEnabled(true) | ||||||
| 	, _noSignalDetected(false) | 	, _noSignalDetected(false) | ||||||
| @@ -52,12 +52,17 @@ V4L2Grabber::V4L2Grabber(const QString & device | |||||||
| 	, _streamNotifier(nullptr) | 	, _streamNotifier(nullptr) | ||||||
| 	, _initialized(false) | 	, _initialized(false) | ||||||
| 	, _deviceAutoDiscoverEnabled(false) | 	, _deviceAutoDiscoverEnabled(false) | ||||||
|  | 	, _readFrameAdaptTimer(new QTimer(this)) | ||||||
| { | { | ||||||
| 	//_imageResampler.setHorizontalPixelDecimation(pixelDecimation); | 	// setup stream notify locker with 10hz | ||||||
| 	//_imageResampler.setVerticalPixelDecimation(pixelDecimation); | 	connect(_readFrameAdaptTimer, &QTimer::timeout, this, &V4L2Grabber::unlockReadFrame); | ||||||
|  | 	_readFrameAdaptTimer->setInterval(100); | ||||||
|  |  | ||||||
|  | 	setPixelDecimation(pixelDecimation); | ||||||
| 	getV4Ldevices(); | 	getV4Ldevices(); | ||||||
|  |  | ||||||
|  | 	// init | ||||||
|  | 	setDeviceVideoStandard(device, videoStandard); | ||||||
| } | } | ||||||
|  |  | ||||||
| V4L2Grabber::~V4L2Grabber() | V4L2Grabber::~V4L2Grabber() | ||||||
| @@ -67,10 +72,12 @@ V4L2Grabber::~V4L2Grabber() | |||||||
|  |  | ||||||
| void V4L2Grabber::uninit() | void V4L2Grabber::uninit() | ||||||
| { | { | ||||||
| 	Debug(_log,"uninit grabber: %s", QSTRING_CSTR(_deviceName)); |  | ||||||
| 	// stop if the grabber was not stopped | 	// stop if the grabber was not stopped | ||||||
| 	if (_initialized) | 	if (_initialized) | ||||||
| 	{ | 	{ | ||||||
|  | 		Debug(_log,"uninit grabber: %s", QSTRING_CSTR(_deviceName)); | ||||||
|  |  | ||||||
|  | 		_readFrameAdaptTimer->stop(); | ||||||
| 		stop(); | 		stop(); | ||||||
| 		uninit_device(); | 		uninit_device(); | ||||||
| 		close_device(); | 		close_device(); | ||||||
| @@ -78,7 +85,6 @@ void V4L2Grabber::uninit() | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| bool V4L2Grabber::init() | bool V4L2Grabber::init() | ||||||
| { | { | ||||||
| 	if (! _initialized) | 	if (! _initialized) | ||||||
| @@ -132,11 +138,16 @@ bool V4L2Grabber::init() | |||||||
|  |  | ||||||
| 		bool opened = false; | 		bool opened = false; | ||||||
| 		try | 		try | ||||||
|  | 		{ | ||||||
|  | 			// do not init with unknown device | ||||||
|  | 			if(_deviceName != "unknown") | ||||||
| 			{ | 			{ | ||||||
| 				open_device(); | 				open_device(); | ||||||
| 				opened = true; | 				opened = true; | ||||||
| 				init_device(_videoStandard, _input); | 				init_device(_videoStandard, _input); | ||||||
| 				_initialized = true; | 				_initialized = true; | ||||||
|  | 				_readFrameAdaptTimer->start(); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		catch(std::exception& e) | 		catch(std::exception& e) | ||||||
| 		{ | 		{ | ||||||
| @@ -529,13 +540,13 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input) | |||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | // TODO Does never accept own sizes? use always _imageResampler instead | ||||||
|  | /* | ||||||
|  |  | ||||||
| 	// calc the size based on pixelDecimation | 	// calc the size based on pixelDecimation | ||||||
| 	fmt.fmt.pix.width = fmt.fmt.pix.width / _pixelDecimation; | 	fmt.fmt.pix.width = fmt.fmt.pix.width / _pixelDecimation; | ||||||
| 	fmt.fmt.pix.height = fmt.fmt.pix.height / _pixelDecimation; | 	fmt.fmt.pix.height = fmt.fmt.pix.height / _pixelDecimation; | ||||||
|  |  | ||||||
| 	// set the line length |  | ||||||
| 	_lineLength = fmt.fmt.pix.bytesperline; |  | ||||||
|  |  | ||||||
| 	// set the settings | 	// set the settings | ||||||
| 	if (-1 == xioctl(VIDIOC_S_FMT, &fmt)) | 	if (-1 == xioctl(VIDIOC_S_FMT, &fmt)) | ||||||
| 	{ | 	{ | ||||||
| @@ -550,6 +561,9 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input) | |||||||
| 		throw_errno_exception("VIDIOC_G_FMT"); | 		throw_errno_exception("VIDIOC_G_FMT"); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  | */ | ||||||
|  | 	// set the line length | ||||||
|  | 	_lineLength = fmt.fmt.pix.bytesperline; | ||||||
|  |  | ||||||
| 	// store width & height | 	// store width & height | ||||||
| 	_width = fmt.fmt.pix.width; | 	_width = fmt.fmt.pix.width; | ||||||
| @@ -701,6 +715,10 @@ void V4L2Grabber::stop_capturing() | |||||||
|  |  | ||||||
| int V4L2Grabber::read_frame() | int V4L2Grabber::read_frame() | ||||||
| { | { | ||||||
|  | 	// read_frame() is called with 25Hz, adapt to 10Hz. In the end it's up to the stream notifier if we get calls or not | ||||||
|  | 	if(!_readFrame) return -1; | ||||||
|  | 	_readFrame = false; | ||||||
|  |  | ||||||
| 	bool rc = false; | 	bool rc = false; | ||||||
|  |  | ||||||
| 	try | 	try | ||||||
| @@ -933,18 +951,30 @@ void V4L2Grabber::setPixelDecimation(int pixelDecimation) | |||||||
| { | { | ||||||
| 	if(_pixelDecimation != pixelDecimation) | 	if(_pixelDecimation != pixelDecimation) | ||||||
| 	{ | 	{ | ||||||
|  | 		_pixelDecimation = pixelDecimation; | ||||||
| 		uninit(); | 		uninit(); | ||||||
| 		init(); | 		// start if init is a success | ||||||
|  | 		if(init()) | ||||||
|  | 			start(); | ||||||
|  | 		_imageResampler.setHorizontalPixelDecimation(pixelDecimation); | ||||||
|  | 		_imageResampler.setVerticalPixelDecimation(pixelDecimation); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void V4L2Grabber::setInputVideoStandard(int input, VideoStandard videoStandard) | void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStandard) | ||||||
| { | { | ||||||
| 	if(_input != input || _videoStandard != videoStandard) | 	if(_deviceName != device || _videoStandard != videoStandard) | ||||||
| 	{ | 	{ | ||||||
| 		_input = input; | 		// extract input of device | ||||||
| 		_videoStandard = videoStandard; | 		QChar input = device.at(device.size() - 1); | ||||||
|  | 		_input = input.isNumber() ? input.digitValue() : -1; | ||||||
|  |  | ||||||
| 		uninit(); | 		uninit(); | ||||||
| 		init(); | 		_deviceName = device; | ||||||
|  | 		_videoStandard = videoStandard; | ||||||
|  |  | ||||||
|  | 		// start if init is a success | ||||||
|  | 		if(init()) | ||||||
|  | 			start(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,13 +6,11 @@ | |||||||
| #include <QTimer> | #include <QTimer> | ||||||
|  |  | ||||||
| V4L2Wrapper::V4L2Wrapper(const QString &device, | V4L2Wrapper::V4L2Wrapper(const QString &device, | ||||||
| 		int input, |  | ||||||
| 		VideoStandard videoStandard, | 		VideoStandard videoStandard, | ||||||
| 		PixelFormat pixelFormat, | 		PixelFormat pixelFormat, | ||||||
| 		int pixelDecimation ) | 		int pixelDecimation ) | ||||||
| 	: GrabberWrapper("V4L2:"+device, &_grabber, 0, 0, 10) | 	: GrabberWrapper("V4L2:"+device, &_grabber, 0, 0, 10) | ||||||
| 	, _grabber(device, | 	, _grabber(device, | ||||||
| 			input, |  | ||||||
| 			videoStandard, | 			videoStandard, | ||||||
| 			pixelFormat, | 			pixelFormat, | ||||||
| 			pixelDecimation) | 			pixelDecimation) | ||||||
| @@ -66,7 +64,7 @@ void V4L2Wrapper::readError(const char* err) | |||||||
|  |  | ||||||
| void V4L2Wrapper::action() | void V4L2Wrapper::action() | ||||||
| { | { | ||||||
|  | 	// dummy as v4l get notifications from stream | ||||||
| } | } | ||||||
|  |  | ||||||
| void V4L2Wrapper::setSignalDetectionEnable(bool enable) | void V4L2Wrapper::setSignalDetectionEnable(bool enable) | ||||||
|   | |||||||
| @@ -110,6 +110,7 @@ bool X11Grabber::Setup() | |||||||
|  |  | ||||||
| 	bool result = (updateScreenDimensions(true) >=0); | 	bool result = (updateScreenDimensions(true) >=0); | ||||||
| 	ErrorIf(!result, _log, "X11 Grabber start failed"); | 	ErrorIf(!result, _log, "X11 Grabber start failed"); | ||||||
|  | 	setEnabled(result); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -278,11 +279,6 @@ void X11Grabber::setVideoMode(VideoMode mode) | |||||||
| 	updateScreenDimensions(true); | 	updateScreenDimensions(true); | ||||||
| } | } | ||||||
|  |  | ||||||
| void X11Grabber::setWidthHeight(int width, int height) |  | ||||||
| { |  | ||||||
| 	// empty overwrite |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void X11Grabber::setPixelDecimation(int pixelDecimation) | void X11Grabber::setPixelDecimation(int pixelDecimation) | ||||||
| { | { | ||||||
| 	if(_pixelDecimation != pixelDecimation) | 	if(_pixelDecimation != pixelDecimation) | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ target_link_libraries(hyperion | |||||||
| 	hyperion-utils | 	hyperion-utils | ||||||
| 	leddevice | 	leddevice | ||||||
| 	bonjour | 	bonjour | ||||||
|  | 	boblightserver | ||||||
| 	effectengine | 	effectengine | ||||||
| 	${QT_LIBRARIES} | 	${QT_LIBRARIES} | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -1,12 +1,14 @@ | |||||||
| #include <hyperion/CaptureCont.h> | #include <hyperion/CaptureCont.h> | ||||||
|  |  | ||||||
| #include <hyperion/Hyperion.h> | #include <hyperion/Hyperion.h> | ||||||
|  | #include <QTimer> | ||||||
|  |  | ||||||
| CaptureCont::CaptureCont(Hyperion* hyperion) | CaptureCont::CaptureCont(Hyperion* hyperion) | ||||||
| 	: QObject() | 	: QObject() | ||||||
| 	, _hyperion(hyperion) | 	, _hyperion(hyperion) | ||||||
| 	, _systemCaptEnabled(false) | 	, _systemCaptEnabled(false) | ||||||
| 	, _v4lCaptEnabled(false) | 	, _v4lCaptEnabled(false) | ||||||
|  | 	, _v4lInactiveTimer(new QTimer(this)) | ||||||
| { | { | ||||||
| 	// settings changes | 	// settings changes | ||||||
| 	connect(_hyperion, &Hyperion::settingsChanged, this, &CaptureCont::handleSettingsUpdate); | 	connect(_hyperion, &Hyperion::settingsChanged, this, &CaptureCont::handleSettingsUpdate); | ||||||
| @@ -14,6 +16,11 @@ CaptureCont::CaptureCont(Hyperion* hyperion) | |||||||
| 	// comp changes | 	// comp changes | ||||||
| 	connect(_hyperion, &Hyperion::componentStateChanged, this, &CaptureCont::componentStateChanged); | 	connect(_hyperion, &Hyperion::componentStateChanged, this, &CaptureCont::componentStateChanged); | ||||||
|  |  | ||||||
|  | 	// inactive timer v4l | ||||||
|  | 	connect(_v4lInactiveTimer, &QTimer::timeout, this, &CaptureCont::setV4lInactive); | ||||||
|  | 	_v4lInactiveTimer->setSingleShot(true); | ||||||
|  | 	_v4lInactiveTimer->setInterval(1000); | ||||||
|  |  | ||||||
| 	// init | 	// init | ||||||
| 	handleSettingsUpdate(settings::INSTCAPTURE, _hyperion->getSetting(settings::INSTCAPTURE)); | 	handleSettingsUpdate(settings::INSTCAPTURE, _hyperion->getSetting(settings::INSTCAPTURE)); | ||||||
| } | } | ||||||
| @@ -25,6 +32,7 @@ CaptureCont::~CaptureCont() | |||||||
|  |  | ||||||
| void CaptureCont::handleV4lImage(const Image<ColorRgb> & image) | void CaptureCont::handleV4lImage(const Image<ColorRgb> & image) | ||||||
| { | { | ||||||
|  | 	_v4lInactiveTimer->start(); | ||||||
| 	_hyperion->setInputImage(_v4lCaptPrio, image); | 	_hyperion->setInputImage(_v4lCaptPrio, image); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -40,7 +48,7 @@ void CaptureCont::setSystemCaptureEnable(const bool& enable) | |||||||
| 	{ | 	{ | ||||||
| 		if(enable) | 		if(enable) | ||||||
| 		{ | 		{ | ||||||
| 			_hyperion->registerInput(_systemCaptPrio, hyperion::COMP_GRABBER, "System", "DoNotKnow"); | 			_hyperion->registerInput(_systemCaptPrio, hyperion::COMP_GRABBER); | ||||||
| 			connect(_hyperion, &Hyperion::systemImage, this, &CaptureCont::handleSystemImage); | 			connect(_hyperion, &Hyperion::systemImage, this, &CaptureCont::handleSystemImage); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @@ -59,13 +67,14 @@ void CaptureCont::setV4LCaptureEnable(const bool& enable) | |||||||
| 	{ | 	{ | ||||||
| 		if(enable) | 		if(enable) | ||||||
| 		{ | 		{ | ||||||
| 			_hyperion->registerInput(_v4lCaptPrio, hyperion::COMP_V4L, "System", "DoNotKnow"); | 			_hyperion->registerInput(_v4lCaptPrio, hyperion::COMP_V4L); | ||||||
| 			connect(_hyperion, &Hyperion::v4lImage, this, &CaptureCont::handleV4lImage); | 			connect(_hyperion, &Hyperion::v4lImage, this, &CaptureCont::handleV4lImage); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			disconnect(_hyperion, &Hyperion::v4lImage, this, &CaptureCont::handleV4lImage); | 			disconnect(_hyperion, &Hyperion::v4lImage, this, &CaptureCont::handleV4lImage); | ||||||
| 			_hyperion->clear(_v4lCaptPrio); | 			_hyperion->clear(_v4lCaptPrio); | ||||||
|  | 			_v4lInactiveTimer->stop(); | ||||||
| 		} | 		} | ||||||
| 		_v4lCaptEnabled = enable; | 		_v4lCaptEnabled = enable; | ||||||
| 		_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_V4L, enable); | 		_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_V4L, enable); | ||||||
| @@ -104,3 +113,8 @@ void CaptureCont::componentStateChanged(const hyperion::Components component, bo | |||||||
| 		setV4LCaptureEnable(enable); | 		setV4LCaptureEnable(enable); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CaptureCont::setV4lInactive() | ||||||
|  | { | ||||||
|  | 	_hyperion->setInputInactive(_v4lCaptPrio); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -55,9 +55,9 @@ bool ComponentRegister::setHyperionEnable(const bool& state) | |||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool ComponentRegister::isComponentEnabled(const hyperion::Components& comp) const | int ComponentRegister::isComponentEnabled(const hyperion::Components& comp) const | ||||||
| { | { | ||||||
| 	return _componentStates.at(comp); | 	return (_componentStates.count(comp)) ? _componentStates.at(comp) : -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| void ComponentRegister::componentStateChanged(const hyperion::Components comp, const bool activated) | void ComponentRegister::componentStateChanged(const hyperion::Components comp, const bool activated) | ||||||
|   | |||||||
| @@ -24,12 +24,13 @@ Grabber::~Grabber() | |||||||
|  |  | ||||||
| void Grabber::setEnabled(bool enable) | void Grabber::setEnabled(bool enable) | ||||||
| { | { | ||||||
|  | 	Info(_log,"Capture interface is now %s", enable ? "enabled" : "disabled"); | ||||||
| 	_enabled = enable; | 	_enabled = enable; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Grabber::setVideoMode(VideoMode mode) | void Grabber::setVideoMode(VideoMode mode) | ||||||
| { | { | ||||||
| 	Debug(_log,"setvideomode %d", mode); | 	Debug(_log,"Set videomode to %d", mode); | ||||||
| 	_videoMode = mode; | 	_videoMode = mode; | ||||||
| 	if ( _useImageResampler ) | 	if ( _useImageResampler ) | ||||||
| 	{ | 	{ | ||||||
| @@ -68,18 +69,20 @@ void Grabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTo | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void Grabber::setWidthHeight(int width, int height) | bool Grabber::setWidthHeight(int width, int height) | ||||||
| { | { | ||||||
| 	// eval changes with crop | 	// eval changes with crop | ||||||
| 	if (width>0 && height>0) | 	if ( (width>0 && height>0) && (_width != width || _height != height) ) | ||||||
| 	{ | 	{ | ||||||
| 		if (_cropLeft + _cropRight >= width || _cropTop + _cropBottom >= height) | 		if (_cropLeft + _cropRight >= width || _cropTop + _cropBottom >= height) | ||||||
| 		{ | 		{ | ||||||
| 			Error(_log, "Rejecting invalid width/height values as it collides with image cropping: width: %d, height: %d", width, height); | 			Error(_log, "Rejecting invalid width/height values as it collides with image cropping: width: %d, height: %d", width, height); | ||||||
| 			return; | 			return false; | ||||||
| 		} | 		} | ||||||
|  | 		Debug(_log, "Set new width: %d, height: %d for capture", width, height); | ||||||
| 		_width = width; | 		_width = width; | ||||||
| 		_height = height; | 		_height = height; | ||||||
|  | 		return true; | ||||||
| 	} | 	} | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,19 +3,14 @@ | |||||||
| #include <hyperion/Grabber.h> | #include <hyperion/Grabber.h> | ||||||
| #include <HyperionConfig.h> | #include <HyperionConfig.h> | ||||||
|  |  | ||||||
| //forwarder |  | ||||||
| #include <hyperion/MessageForwarder.h> |  | ||||||
|  |  | ||||||
| // qt | // qt | ||||||
| #include <QTimer> | #include <QTimer> | ||||||
|  |  | ||||||
| GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz) | GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz) | ||||||
| 	: _grabberName(grabberName) | 	: _grabberName(grabberName) | ||||||
| 	, _hyperion(Hyperion::getInstance()) |  | ||||||
| 	, _timer(new QTimer(this)) | 	, _timer(new QTimer(this)) | ||||||
| 	, _updateInterval_ms(1000/updateRate_Hz) | 	, _updateInterval_ms(1000/updateRate_Hz) | ||||||
| 	, _log(Logger::getInstance(grabberName)) | 	, _log(Logger::getInstance(grabberName)) | ||||||
| 	, _forward(true) |  | ||||||
| 	, _ggrabber(ggrabber) | 	, _ggrabber(ggrabber) | ||||||
| 	, _image(0,0) | 	, _image(0,0) | ||||||
| { | { | ||||||
| @@ -24,8 +19,6 @@ GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned | |||||||
|  |  | ||||||
| 	_image.resize(width, height); | 	_image.resize(width, height); | ||||||
|  |  | ||||||
| 	_forward = _hyperion->getForwarder()->protoForwardingEnabled(); |  | ||||||
|  |  | ||||||
| 	connect(_timer, &QTimer::timeout, this, &GrabberWrapper::action); | 	connect(_timer, &QTimer::timeout, this, &GrabberWrapper::action); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -105,7 +98,7 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso | |||||||
| 		else | 		else | ||||||
| 			obj = config.object(); | 			obj = config.object(); | ||||||
|  |  | ||||||
| 		if(type == settings::SYSTEMCAPTURE) | 		if(type == settings::SYSTEMCAPTURE  && !_grabberName.startsWith("V4L")) | ||||||
| 		{ | 		{ | ||||||
| 			// width/height | 			// width/height | ||||||
| 			_ggrabber->setWidthHeight(obj["width"].toInt(96), obj["height"].toInt(96)); | 			_ggrabber->setWidthHeight(obj["width"].toInt(96), obj["height"].toInt(96)); | ||||||
| @@ -138,7 +131,8 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(type == settings::V4L2) | 		// v4l instances only! | ||||||
|  | 		if(type == settings::V4L2 && _grabberName.startsWith("V4L")) | ||||||
| 		{ | 		{ | ||||||
| 			// pixel decimation for v4l | 			// pixel decimation for v4l | ||||||
| 			_ggrabber->setPixelDecimation(obj["sizeDecimation"].toInt(8)); | 			_ggrabber->setPixelDecimation(obj["sizeDecimation"].toInt(8)); | ||||||
| @@ -160,8 +154,8 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso | |||||||
| 				obj["redSignalThreshold"].toDouble(0.0)/100.0, | 				obj["redSignalThreshold"].toDouble(0.0)/100.0, | ||||||
| 				obj["greenSignalThreshold"].toDouble(0.0)/100.0, | 				obj["greenSignalThreshold"].toDouble(0.0)/100.0, | ||||||
| 				obj["blueSignalThreshold"].toDouble(0.0)/100.0); | 				obj["blueSignalThreshold"].toDouble(0.0)/100.0); | ||||||
| 			_ggrabber->setInputVideoStandard( | 			_ggrabber->setDeviceVideoStandard( | ||||||
| 				obj["input"].toInt(0), | 				obj["device"].toString("auto"), | ||||||
| 				parseVideoStandard(obj["standard"].toString("no-change"))); | 				parseVideoStandard(obj["standard"].toString("no-change"))); | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -47,6 +47,9 @@ | |||||||
| // CaptureControl (Daemon capture) | // CaptureControl (Daemon capture) | ||||||
| #include <hyperion/CaptureCont.h> | #include <hyperion/CaptureCont.h> | ||||||
|  |  | ||||||
|  | // Boblight | ||||||
|  | #include <boblightserver/BoblightServer.h> | ||||||
|  |  | ||||||
| Hyperion* Hyperion::_hyperion = nullptr; | Hyperion* Hyperion::_hyperion = nullptr; | ||||||
|  |  | ||||||
| Hyperion* Hyperion::initInstance( HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath) | Hyperion* Hyperion::initInstance( HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath) | ||||||
| @@ -122,7 +125,7 @@ Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString | |||||||
| 	const QJsonObject color = getSetting(settings::COLOR).object(); | 	const QJsonObject color = getSetting(settings::COLOR).object(); | ||||||
|  |  | ||||||
| 	// initialize leddevices | 	// initialize leddevices | ||||||
| 	const QJsonObject ledDevice = getSetting(settings::DEVICE).object(); | 	QJsonObject ledDevice = getSetting(settings::DEVICE).object(); | ||||||
| 	ledDevice["currentLedCount"] = int(_hwLedCount); // Inject led count info | 	ledDevice["currentLedCount"] = int(_hwLedCount); // Inject led count info | ||||||
|  |  | ||||||
| 	_device       = LedDeviceFactory::construct(ledDevice); | 	_device       = LedDeviceFactory::construct(ledDevice); | ||||||
| @@ -159,6 +162,11 @@ Hyperion::Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString | |||||||
|  |  | ||||||
| 	// if there is no startup / background eff and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a prioritiy change) | 	// if there is no startup / background eff and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a prioritiy change) | ||||||
| 	update(); | 	update(); | ||||||
|  |  | ||||||
|  | 	// boblight, can't live in global scope as it depends on layout | ||||||
|  |  | ||||||
|  | 	_boblightServer = new BoblightServer(this, getSetting(settings::BOBLSERVER)); | ||||||
|  | 	connect(this, &Hyperion::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate); | ||||||
| } | } | ||||||
|  |  | ||||||
| Hyperion::~Hyperion() | Hyperion::~Hyperion() | ||||||
| @@ -178,6 +186,7 @@ void Hyperion::freeObjects(bool emitCloseSignal) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// delete components on exit of hyperion core | 	// delete components on exit of hyperion core | ||||||
|  | 	delete _boblightServer; | ||||||
| 	delete _captureCont; | 	delete _captureCont; | ||||||
| 	delete _effectEngine; | 	delete _effectEngine; | ||||||
| 	//delete _deviceSmooth; | 	//delete _deviceSmooth; | ||||||
| @@ -249,7 +258,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum | |||||||
| 	else if(type == settings::DEVICE) | 	else if(type == settings::DEVICE) | ||||||
| 	{ | 	{ | ||||||
| 		_lockUpdate = true; | 		_lockUpdate = true; | ||||||
| 		const QJsonObject dev = config.object(); | 		QJsonObject dev = config.object(); | ||||||
|  |  | ||||||
| 		// handle hwLedCount update | 		// handle hwLedCount update | ||||||
| 		_hwLedCount = qMax(unsigned(dev["hardwareLedCount"].toInt(getLedCount())), getLedCount()); | 		_hwLedCount = qMax(unsigned(dev["hardwareLedCount"].toInt(getLedCount())), getLedCount()); | ||||||
| @@ -281,7 +290,7 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum | |||||||
| 			_deviceSmooth->startTimerDelayed(); | 			_deviceSmooth->startTimerDelayed(); | ||||||
| 		_lockUpdate = false; | 		_lockUpdate = false; | ||||||
| 	} | 	} | ||||||
| 	// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer | 	// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color | ||||||
| 	update(); | 	update(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -421,6 +430,11 @@ const bool Hyperion::setInputImage(const int priority, const Image<ColorRgb>& im | |||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const bool Hyperion::setInputInactive(const quint8& priority) | ||||||
|  | { | ||||||
|  | 	return _muxer.setInputInactive(priority); | ||||||
|  | } | ||||||
|  |  | ||||||
| void Hyperion::setColor(int priority, const ColorRgb &color, const int timeout_ms, const QString& origin, bool clearEffects) | void Hyperion::setColor(int priority, const ColorRgb &color, const int timeout_ms, const QString& origin, bool clearEffects) | ||||||
| { | { | ||||||
| 	// clear effect if this call does not come from an effect | 	// clear effect if this call does not come from an effect | ||||||
| @@ -602,7 +616,7 @@ void Hyperion::update() | |||||||
| 		// disable the black border detector for effects and ledmapping to 0 | 		// disable the black border detector for effects and ledmapping to 0 | ||||||
| 		if(compChanged) | 		if(compChanged) | ||||||
| 		{ | 		{ | ||||||
| 			_imageProcessor->setBlackbarDetectDisable((_prevCompId == hyperion::COMP_EFFECT || _prevCompId == hyperion::COMP_GRABBER)); | 			_imageProcessor->setBlackbarDetectDisable((_prevCompId == hyperion::COMP_EFFECT)); | ||||||
| 			_imageProcessor->setHardLedMappingType((_prevCompId == hyperion::COMP_EFFECT) ? 0 : -1); | 			_imageProcessor->setHardLedMappingType((_prevCompId == hyperion::COMP_EFFECT) ? 0 : -1); | ||||||
| 		} | 		} | ||||||
| 		_imageProcessor->process(image, _ledBuffer); | 		_imageProcessor->process(image, _ledBuffer); | ||||||
|   | |||||||
| @@ -228,7 +228,7 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, const bool& force) | |||||||
| 		} | 		} | ||||||
| 		_currentConfigId = cfg; | 		_currentConfigId = cfg; | ||||||
| 		//DebugIf( enabled() && !_pause, _log, "set smoothing cfg: %d, interval: %d ms, settlingTime: %d ms, updateDelay: %d frames",  _currentConfigId, _updateInterval, _settlingTime,  _outputDelay ); | 		//DebugIf( enabled() && !_pause, _log, "set smoothing cfg: %d, interval: %d ms, settlingTime: %d ms, updateDelay: %d frames",  _currentConfigId, _updateInterval, _settlingTime,  _outputDelay ); | ||||||
| 		InfoIf( _pause, _log, "set smoothing cfg: %d, pause",  _currentConfigId ); | 		DebugIf( _pause, _log, "set smoothing cfg: %d, pause",  _currentConfigId ); | ||||||
|  |  | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -240,6 +240,12 @@ const bool PriorityMuxer::setInputImage(const int priority, const Image<ColorRgb | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const bool PriorityMuxer::setInputInactive(const quint8& priority) | ||||||
|  | { | ||||||
|  | 	Image<ColorRgb> image; | ||||||
|  | 	return setInputImage(priority, image, -100); | ||||||
|  | } | ||||||
|  |  | ||||||
| const bool PriorityMuxer::clearInput(const uint8_t priority) | const bool PriorityMuxer::clearInput(const uint8_t priority) | ||||||
| { | { | ||||||
| 	if (priority < PriorityMuxer::LOWEST_PRIORITY && _activeInputs.remove(priority)) | 	if (priority < PriorityMuxer::LOWEST_PRIORITY && _activeInputs.remove(priority)) | ||||||
|   | |||||||
| @@ -133,8 +133,6 @@ SettingsManager::~SettingsManager() | |||||||
|  |  | ||||||
| const QJsonDocument SettingsManager::getSetting(const settings::type& type) | const QJsonDocument SettingsManager::getSetting(const settings::type& type) | ||||||
| { | { | ||||||
| 	//return _sTable->getSettingsRecord(settings::typeToString(type)); |  | ||||||
|  |  | ||||||
| 	QString key = settings::typeToString(type); | 	QString key = settings::typeToString(type); | ||||||
| 	if(_qconfig[key].isObject()) | 	if(_qconfig[key].isObject()) | ||||||
| 		return QJsonDocument(_qconfig[key].toObject()); | 		return QJsonDocument(_qconfig[key].toObject()); | ||||||
| @@ -168,6 +166,23 @@ const bool SettingsManager::saveSettings(QJsonObject config, const bool& correct | |||||||
| 			return false; | 			return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// compare old data with new data to emit/save changes accordingly | ||||||
|  | 	for(const auto key : config.keys()) | ||||||
|  | 	{ | ||||||
|  | 		QString newData, oldData; | ||||||
|  |  | ||||||
|  | 		_qconfig[key].isObject() | ||||||
|  | 		? oldData = QString(QJsonDocument(_qconfig[key].toObject()).toJson(QJsonDocument::Compact)) | ||||||
|  | 		: oldData = QString(QJsonDocument(_qconfig[key].toArray()).toJson(QJsonDocument::Compact)); | ||||||
|  |  | ||||||
|  | 		config[key].isObject() | ||||||
|  | 		? newData = QString(QJsonDocument(config[key].toObject()).toJson(QJsonDocument::Compact)) | ||||||
|  | 		: newData = QString(QJsonDocument(config[key].toArray()).toJson(QJsonDocument::Compact)); | ||||||
|  |  | ||||||
|  | 		if(oldData != newData) | ||||||
|  | 			emit settingsChanged(settings::stringToType(key), QJsonDocument::fromJson(newData.toLocal8Bit())); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// store the current state | 	// store the current state | ||||||
| 	_qconfig = config; | 	_qconfig = config; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -55,6 +55,10 @@ | |||||||
| 		{ | 		{ | ||||||
| 			"$ref": "schema-protoServer.json" | 			"$ref": "schema-protoServer.json" | ||||||
| 		}, | 		}, | ||||||
|  | 		"flatbufServer": | ||||||
|  | 		{ | ||||||
|  | 			"$ref": "schema-flatbufServer.json" | ||||||
|  | 		}, | ||||||
| 		"boblightServer" : | 		"boblightServer" : | ||||||
| 		{ | 		{ | ||||||
| 			"$ref": "schema-boblightServer.json" | 			"$ref": "schema-boblightServer.json" | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| 		<file alias="schema-forwarder.json">schema/schema-forwarder.json</file> | 		<file alias="schema-forwarder.json">schema/schema-forwarder.json</file> | ||||||
| 		<file alias="schema-jsonServer.json">schema/schema-jsonServer.json</file> | 		<file alias="schema-jsonServer.json">schema/schema-jsonServer.json</file> | ||||||
| 		<file alias="schema-protoServer.json">schema/schema-protoServer.json</file> | 		<file alias="schema-protoServer.json">schema/schema-protoServer.json</file> | ||||||
|  | 		<file alias="schema-flatbufServer.json">schema/schema-flatbufServer.json</file> | ||||||
| 		<file alias="schema-boblightServer.json">schema/schema-boblightServer.json</file> | 		<file alias="schema-boblightServer.json">schema/schema-boblightServer.json</file> | ||||||
| 		<file alias="schema-udpListener.json">schema/schema-udpListener.json</file> | 		<file alias="schema-udpListener.json">schema/schema-udpListener.json</file> | ||||||
| 		<file alias="schema-webConfig.json">schema/schema-webConfig.json</file> | 		<file alias="schema-webConfig.json">schema/schema-webConfig.json</file> | ||||||
|   | |||||||
| @@ -2,18 +2,21 @@ | |||||||
| 	"type" : "object", | 	"type" : "object", | ||||||
| 	"title" : "edt_dev_general_heading_title", | 	"title" : "edt_dev_general_heading_title", | ||||||
| 	"required" : true, | 	"required" : true, | ||||||
| 	"defaultProperties": ["ledCount","colorOrder","rewriteTime","minimumWriteTime"], | 	"defaultProperties": ["hardwareLedCount","colorOrder","rewriteTime"], | ||||||
| 	"properties" : | 	"properties" : | ||||||
| 	{ | 	{ | ||||||
| 		"type" : | 		"type" : | ||||||
| 		{ | 		{ | ||||||
| 			"type" : "string" | 			"type" : "string", | ||||||
|  | 			"propertyOrder" : 1 | ||||||
| 		}, | 		}, | ||||||
| 		"ledCount" : | 		"hardwareLedCount" : | ||||||
| 		{ | 		{ | ||||||
| 			"type" : "integer", | 			"type" : "integer", | ||||||
| 			"minimum" : 0, | 			"title" : "edt_dev_general_hardwareLedCount_title", | ||||||
| 			"title" : "edt_dev_general_ledCount_title", | 			"minimum" : 1, | ||||||
|  | 			"default" : 1, | ||||||
|  | 			"access" : "expert", | ||||||
| 			"propertyOrder" : 2 | 			"propertyOrder" : 2 | ||||||
| 		}, | 		}, | ||||||
| 		"colorOrder" : | 		"colorOrder" : | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| 	"required" : true, | 	"required" : true, | ||||||
| 	"title" : "edt_conf_v4l2_heading_title", | 	"title" : "edt_conf_v4l2_heading_title", | ||||||
| 	"minItems": 1, | 	"minItems": 1, | ||||||
| 	"maxItems": 2, | 	"maxItems": 1, | ||||||
| 	"items": | 	"items": | ||||||
| 	{ | 	{ | ||||||
| 		"type" : "object", | 		"type" : "object", | ||||||
| @@ -16,17 +16,9 @@ | |||||||
| 				"type" : "string", | 				"type" : "string", | ||||||
| 				"title" : "edt_conf_v4l2_device_title", | 				"title" : "edt_conf_v4l2_device_title", | ||||||
| 				"default" : "auto", | 				"default" : "auto", | ||||||
|  | 				"minLength" : 4, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 2 | 				"propertyOrder" : 1 | ||||||
| 			}, |  | ||||||
| 			"input" : |  | ||||||
| 			{ |  | ||||||
| 				"type" : "integer", |  | ||||||
| 				"title" : "edt_conf_v4l2_input_title", |  | ||||||
| 				"minimum" : 0, |  | ||||||
| 				"default" : 0, |  | ||||||
| 				"required" : true, |  | ||||||
| 				"propertyOrder" : 3 |  | ||||||
| 			}, | 			}, | ||||||
| 			"standard" : | 			"standard" : | ||||||
| 			{ | 			{ | ||||||
| @@ -38,7 +30,7 @@ | |||||||
| 					"enum_titles" : ["edt_conf_enum_PAL", "edt_conf_enum_NTSC", "edt_conf_enum_SECAM", "edt_conf_enum_NO_CHANGE"] | 					"enum_titles" : ["edt_conf_enum_PAL", "edt_conf_enum_NTSC", "edt_conf_enum_SECAM", "edt_conf_enum_NO_CHANGE"] | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 4 | 				"propertyOrder" : 2 | ||||||
| 			}, | 			}, | ||||||
| 			"sizeDecimation" : | 			"sizeDecimation" : | ||||||
| 			{ | 			{ | ||||||
| @@ -48,7 +40,7 @@ | |||||||
| 				"maximum" : 30, | 				"maximum" : 30, | ||||||
| 				"default" : 6, | 				"default" : 6, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 8 | 				"propertyOrder" : 3 | ||||||
| 			}, | 			}, | ||||||
| 			"cropLeft" : | 			"cropLeft" : | ||||||
| 			{ | 			{ | ||||||
| @@ -58,7 +50,7 @@ | |||||||
| 				"default" : 0, | 				"default" : 0, | ||||||
| 				"append" : "edt_append_pixel", | 				"append" : "edt_append_pixel", | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 11 | 				"propertyOrder" : 4 | ||||||
| 			}, | 			}, | ||||||
| 			"cropRight" : | 			"cropRight" : | ||||||
| 			{ | 			{ | ||||||
| @@ -68,7 +60,7 @@ | |||||||
| 				"default" : 0, | 				"default" : 0, | ||||||
| 				"append" : "edt_append_pixel", | 				"append" : "edt_append_pixel", | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 12 | 				"propertyOrder" : 5 | ||||||
| 			}, | 			}, | ||||||
| 			"cropTop" : | 			"cropTop" : | ||||||
| 			{ | 			{ | ||||||
| @@ -78,7 +70,7 @@ | |||||||
| 				"default" : 0, | 				"default" : 0, | ||||||
| 				"append" : "edt_append_pixel", | 				"append" : "edt_append_pixel", | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 13 | 				"propertyOrder" : 6 | ||||||
| 			}, | 			}, | ||||||
| 			"cropBottom" : | 			"cropBottom" : | ||||||
| 			{ | 			{ | ||||||
| @@ -88,7 +80,7 @@ | |||||||
| 				"default" : 0, | 				"default" : 0, | ||||||
| 				"append" : "edt_append_pixel", | 				"append" : "edt_append_pixel", | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 14 | 				"propertyOrder" : 7 | ||||||
| 			}, | 			}, | ||||||
| 			"signalDetection" : | 			"signalDetection" : | ||||||
| 			{ | 			{ | ||||||
| @@ -96,7 +88,7 @@ | |||||||
| 				"title" : "edt_conf_v4l2_signalDetection_title", | 				"title" : "edt_conf_v4l2_signalDetection_title", | ||||||
| 				"default" : false, | 				"default" : false, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 15 | 				"propertyOrder" : 8 | ||||||
| 			}, | 			}, | ||||||
| 			"redSignalThreshold" : | 			"redSignalThreshold" : | ||||||
| 			{ | 			{ | ||||||
| @@ -112,7 +104,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 16 | 				"propertyOrder" : 9 | ||||||
| 			}, | 			}, | ||||||
| 			"greenSignalThreshold" : | 			"greenSignalThreshold" : | ||||||
| 			{ | 			{ | ||||||
| @@ -128,7 +120,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 17 | 				"propertyOrder" : 10 | ||||||
| 			}, | 			}, | ||||||
| 			"blueSignalThreshold" : | 			"blueSignalThreshold" : | ||||||
| 			{ | 			{ | ||||||
| @@ -144,7 +136,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 18 | 				"propertyOrder" : 11 | ||||||
| 			}, | 			}, | ||||||
| 			"sDVOffsetMin" : | 			"sDVOffsetMin" : | ||||||
| 			{ | 			{ | ||||||
| @@ -160,7 +152,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 19 | 				"propertyOrder" : 12 | ||||||
| 			}, | 			}, | ||||||
| 			"sDVOffsetMax" : | 			"sDVOffsetMax" : | ||||||
| 			{ | 			{ | ||||||
| @@ -176,7 +168,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 20 | 				"propertyOrder" : 13 | ||||||
| 			}, | 			}, | ||||||
| 			"sDHOffsetMin" : | 			"sDHOffsetMin" : | ||||||
| 			{ | 			{ | ||||||
| @@ -192,7 +184,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 21 | 				"propertyOrder" : 14 | ||||||
| 			}, | 			}, | ||||||
| 			"sDHOffsetMax" : | 			"sDHOffsetMax" : | ||||||
| 			{ | 			{ | ||||||
| @@ -208,7 +200,7 @@ | |||||||
| 					} | 					} | ||||||
| 				}, | 				}, | ||||||
| 				"required" : true, | 				"required" : true, | ||||||
| 				"propertyOrder" : 22 | 				"propertyOrder" : 15 | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 	"additionalProperties" : false | 	"additionalProperties" : false | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| 		{ | 		{ | ||||||
| 			"type" : "boolean", | 			"type" : "boolean", | ||||||
| 			"required" : true, | 			"required" : true, | ||||||
| 			"title" : "edt_conf_instC_systemEnable", | 			"title" : "edt_conf_instC_systemEnable_title", | ||||||
| 			"default" : true, | 			"default" : true, | ||||||
| 			"propertyOrder" : 1 | 			"propertyOrder" : 1 | ||||||
| 		}, | 		}, | ||||||
| @@ -26,7 +26,7 @@ | |||||||
| 		{ | 		{ | ||||||
| 			"type" : "boolean", | 			"type" : "boolean", | ||||||
| 			"required" : true, | 			"required" : true, | ||||||
| 			"title" : "edt_conf_instC_v4lEnable", | 			"title" : "edt_conf_instC_v4lEnable_title", | ||||||
| 			"default" : false, | 			"default" : false, | ||||||
| 			"propertyOrder" : 3 | 			"propertyOrder" : 3 | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -3,14 +3,6 @@ | |||||||
| 	"title" : "edt_conf_webc_heading_title", | 	"title" : "edt_conf_webc_heading_title", | ||||||
| 	"properties" : | 	"properties" : | ||||||
| 	{ | 	{ | ||||||
| 		"enable" : |  | ||||||
| 		{ |  | ||||||
| 			"type" : "boolean", |  | ||||||
| 			"title" : "edt_conf_general_enable_title", |  | ||||||
| 			"default" : true, |  | ||||||
| 			"access" : "expert", |  | ||||||
| 			"propertyOrder" : 1 |  | ||||||
| 		}, |  | ||||||
| 		"document_root" : | 		"document_root" : | ||||||
| 		{ | 		{ | ||||||
| 			"type" : "string", | 			"type" : "string", | ||||||
|   | |||||||
| @@ -5,11 +5,8 @@ | |||||||
| #include <jsonserver/JsonServer.h> | #include <jsonserver/JsonServer.h> | ||||||
| #include "JsonClientConnection.h" | #include "JsonClientConnection.h" | ||||||
|  |  | ||||||
| // hyperion include | // bonjour include | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <hyperion/MessageForwarder.h> |  | ||||||
| #include <bonjour/bonjourserviceregister.h> | #include <bonjour/bonjourserviceregister.h> | ||||||
| #include <hyperion/ComponentRegister.h> |  | ||||||
|  |  | ||||||
| // qt includes | // qt includes | ||||||
| #include <QTcpServer> | #include <QTcpServer> | ||||||
| @@ -20,27 +17,16 @@ | |||||||
| JsonServer::JsonServer(const QJsonDocument& config) | JsonServer::JsonServer(const QJsonDocument& config) | ||||||
| 	: QObject() | 	: QObject() | ||||||
| 	, _server(new QTcpServer(this)) | 	, _server(new QTcpServer(this)) | ||||||
| 	, _hyperion(Hyperion::getInstance()) |  | ||||||
| 	, _openConnections() | 	, _openConnections() | ||||||
| 	, _log(Logger::getInstance("JSONSERVER")) | 	, _log(Logger::getInstance("JSONSERVER")) | ||||||
| 	, _componentRegister( & _hyperion->getComponentRegister()) |  | ||||||
| { | { | ||||||
| 	Debug(_log, "Created instance"); | 	Debug(_log, "Created instance"); | ||||||
|  |  | ||||||
| 	// Set trigger for incoming connections | 	// Set trigger for incoming connections | ||||||
| 	connect(_server, SIGNAL(newConnection()), this, SLOT(newConnection())); | 	connect(_server, SIGNAL(newConnection()), this, SLOT(newConnection())); | ||||||
|  |  | ||||||
| 	// receive state of forwarder |  | ||||||
| 	connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonServer::componentStateChanged); |  | ||||||
|  |  | ||||||
| 	// listen for component register changes |  | ||||||
| 	connect(_hyperion, &Hyperion::forwardJsonMessage, this, &JsonServer::forwardJsonMessage); |  | ||||||
|  |  | ||||||
| 	// init | 	// init | ||||||
| 	handleSettingsUpdate(settings::JSONSERVER, config); | 	handleSettingsUpdate(settings::JSONSERVER, config); | ||||||
|  |  | ||||||
| 	// set initial state of forwarding |  | ||||||
| 	componentStateChanged(hyperion::COMP_FORWARDER, _componentRegister->isComponentEnabled(hyperion::COMP_FORWARDER)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| JsonServer::~JsonServer() | JsonServer::~JsonServer() | ||||||
| @@ -64,7 +50,13 @@ void JsonServer::start() | |||||||
|  |  | ||||||
| 	if(_serviceRegister == nullptr) | 	if(_serviceRegister == nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		_serviceRegister = new BonjourServiceRegister(); | 		_serviceRegister = new BonjourServiceRegister(this); | ||||||
|  | 		_serviceRegister->registerService("_hyperiond-json._tcp", _port); | ||||||
|  | 	} | ||||||
|  | 	else if( _serviceRegister->getPort() != _port) | ||||||
|  | 	{ | ||||||
|  | 		delete _serviceRegister; | ||||||
|  | 		_serviceRegister = new BonjourServiceRegister(this); | ||||||
| 		_serviceRegister->registerService("_hyperiond-json._tcp", _port); | 		_serviceRegister->registerService("_hyperiond-json._tcp", _port); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -123,38 +115,6 @@ void JsonServer::closedConnection(void) | |||||||
| 	connection->deleteLater(); | 	connection->deleteLater(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void JsonServer::componentStateChanged(const hyperion::Components component, bool enable) |  | ||||||
| { |  | ||||||
| 	if (component == hyperion::COMP_FORWARDER) |  | ||||||
| 	{ |  | ||||||
| 		if(enable) |  | ||||||
| 		{ |  | ||||||
| 			connect(_hyperion, &Hyperion::forwardJsonMessage, this, &JsonServer::forwardJsonMessage); |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			disconnect(_hyperion, &Hyperion::forwardJsonMessage, this, &JsonServer::forwardJsonMessage); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void JsonServer::forwardJsonMessage(const QJsonObject &message) |  | ||||||
| { |  | ||||||
| 	QTcpSocket client; |  | ||||||
| 	QStringList list = _hyperion->getForwarder()->getJsonSlaves(); |  | ||||||
|  |  | ||||||
| 	for (const auto& entry : list) |  | ||||||
| 	{ |  | ||||||
| 		QStringList splitted = entry.split(":"); |  | ||||||
| 		client.connectToHost(splitted[0], splitted[1].toInt()); |  | ||||||
| 		if ( client.waitForConnected(500) ) |  | ||||||
| 		{ |  | ||||||
| 			sendMessage(message,&client); |  | ||||||
| 			client.close(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void JsonServer::sendMessage(const QJsonObject & message, QTcpSocket * socket) | void JsonServer::sendMessage(const QJsonObject & message, QTcpSocket * socket) | ||||||
| { | { | ||||||
| 	// serialize message | 	// serialize message | ||||||
|   | |||||||
| @@ -16,6 +16,9 @@ | |||||||
| // hyperion util includes | // hyperion util includes | ||||||
| #include "utils/ColorRgb.h" | #include "utils/ColorRgb.h" | ||||||
|  |  | ||||||
|  | // Hyperion includes | ||||||
|  | #include <hyperion/Hyperion.h> | ||||||
|  |  | ||||||
| // project includes | // project includes | ||||||
| #include "ProtoClientConnection.h" | #include "ProtoClientConnection.h" | ||||||
|  |  | ||||||
| @@ -198,7 +201,7 @@ void ProtoClientConnection::handleClearCommand(const proto::ClearRequest &messag | |||||||
| 	int priority = message.priority(); | 	int priority = message.priority(); | ||||||
|  |  | ||||||
| 	// clear priority | 	// clear priority | ||||||
| 	_hyperion->clear(priority); | 	//_hyperion->clear(priority); | ||||||
| 	// send reply | 	// send reply | ||||||
| 	sendSuccessReply(); | 	sendSuccessReply(); | ||||||
| } | } | ||||||
| @@ -206,7 +209,7 @@ void ProtoClientConnection::handleClearCommand(const proto::ClearRequest &messag | |||||||
| void ProtoClientConnection::handleClearallCommand() | void ProtoClientConnection::handleClearallCommand() | ||||||
| { | { | ||||||
| 	// clear priority | 	// clear priority | ||||||
| 	_hyperion->clearall(); | 	//_hyperion->clearall(); | ||||||
|  |  | ||||||
| 	// send reply | 	// send reply | ||||||
| 	sendSuccessReply(); | 	sendSuccessReply(); | ||||||
|   | |||||||
| @@ -9,9 +9,6 @@ | |||||||
| #include <QStringList> | #include <QStringList> | ||||||
| #include <QString> | #include <QString> | ||||||
|  |  | ||||||
| // Hyperion includes |  | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
|  |  | ||||||
| //Utils includes | //Utils includes | ||||||
| #include <utils/VideoMode.h> | #include <utils/VideoMode.h> | ||||||
|  |  | ||||||
| @@ -19,6 +16,8 @@ | |||||||
| #include "message.pb.h" | #include "message.pb.h" | ||||||
| #include "protoserver/ProtoConnection.h" | #include "protoserver/ProtoConnection.h" | ||||||
|  |  | ||||||
|  | class Hyperion; | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// The Connection object created by a ProtoServer when a new connection is establshed | /// The Connection object created by a ProtoServer when a new connection is establshed | ||||||
| /// | /// | ||||||
|   | |||||||
| @@ -3,10 +3,9 @@ | |||||||
|  |  | ||||||
| // qt incl | // qt incl | ||||||
| #include <QTcpServer> | #include <QTcpServer> | ||||||
|  | #include <QJsonObject> | ||||||
|  |  | ||||||
| // project includes | // project includes | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <hyperion/MessageForwarder.h> |  | ||||||
| #include <protoserver/ProtoServer.h> | #include <protoserver/ProtoServer.h> | ||||||
| #include "protoserver/ProtoConnection.h" | #include "protoserver/ProtoConnection.h" | ||||||
| #include "ProtoClientConnection.h" | #include "ProtoClientConnection.h" | ||||||
| @@ -15,30 +14,13 @@ | |||||||
|  |  | ||||||
| ProtoServer::ProtoServer(const QJsonDocument& config) | ProtoServer::ProtoServer(const QJsonDocument& config) | ||||||
| 	: QObject() | 	: QObject() | ||||||
| 	, _hyperion(Hyperion::getInstance()) |  | ||||||
| 	, _server(new QTcpServer(this)) | 	, _server(new QTcpServer(this)) | ||||||
| 	, _openConnections() | 	, _openConnections() | ||||||
| 	, _log(Logger::getInstance("PROTOSERVER")) | 	, _log(Logger::getInstance("PROTOSERVER")) | ||||||
| 	, _componentRegister( & _hyperion->getComponentRegister()) |  | ||||||
| { | { | ||||||
| 	Debug(_log,"Instance created"); | 	Debug(_log,"Instance created"); | ||||||
| 	connect( _server, SIGNAL(newConnection()), this, SLOT(newConnection())); | 	connect( _server, SIGNAL(newConnection()), this, SLOT(newConnection())); | ||||||
| 	handleSettingsUpdate(settings::PROTOSERVER, config); | 	handleSettingsUpdate(settings::PROTOSERVER, config); | ||||||
|  |  | ||||||
| 	QStringList slaves = _hyperion->getForwarder()->getProtoSlaves(); |  | ||||||
|  |  | ||||||
| 	for (const auto& entry : slaves) |  | ||||||
| 	{ |  | ||||||
| 		ProtoConnection* p = new ProtoConnection(entry.toLocal8Bit().constData()); |  | ||||||
| 		p->setSkipReply(true); |  | ||||||
| 		_proxy_connections << p; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// listen for component changes |  | ||||||
| 	connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &ProtoServer::componentStateChanged); |  | ||||||
|  |  | ||||||
| 	// get inital forwarder state |  | ||||||
| 	componentStateChanged(hyperion::COMP_FORWARDER, _componentRegister->isComponentEnabled(hyperion::COMP_FORWARDER)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ProtoServer::~ProtoServer() | ProtoServer::~ProtoServer() | ||||||
| @@ -46,9 +28,6 @@ ProtoServer::~ProtoServer() | |||||||
| 	foreach (ProtoClientConnection * connection, _openConnections) { | 	foreach (ProtoClientConnection * connection, _openConnections) { | ||||||
| 		delete connection; | 		delete connection; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	while (!_proxy_connections.isEmpty()) |  | ||||||
| 		delete _proxy_connections.takeFirst(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void ProtoServer::start() | void ProtoServer::start() | ||||||
| @@ -65,7 +44,13 @@ void ProtoServer::start() | |||||||
|  |  | ||||||
| 	if(_serviceRegister == nullptr) | 	if(_serviceRegister == nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		_serviceRegister = new BonjourServiceRegister(); | 		_serviceRegister = new BonjourServiceRegister(this); | ||||||
|  | 		_serviceRegister->registerService("_hyperiond-proto._tcp", _port); | ||||||
|  | 	} | ||||||
|  | 	else if( _serviceRegister->getPort() != _port) | ||||||
|  | 	{ | ||||||
|  | 		delete _serviceRegister; | ||||||
|  | 		_serviceRegister = new BonjourServiceRegister(this); | ||||||
| 		_serviceRegister->registerService("_hyperiond-proto._tcp", _port); | 		_serviceRegister->registerService("_hyperiond-proto._tcp", _port); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -110,37 +95,11 @@ void ProtoServer::newConnection() | |||||||
|  |  | ||||||
| 			// register slot for cleaning up after the connection closed | 			// register slot for cleaning up after the connection closed | ||||||
| 			connect(connection, SIGNAL(connectionClosed(ProtoClientConnection*)), this, SLOT(closedConnection(ProtoClientConnection*))); | 			connect(connection, SIGNAL(connectionClosed(ProtoClientConnection*)), this, SLOT(closedConnection(ProtoClientConnection*))); | ||||||
| 			connect(connection, SIGNAL(newMessage(const proto::HyperionRequest*)), this, SLOT(newMessage(const proto::HyperionRequest*))); | 			//connect(connection, SIGNAL(newMessage(const proto::HyperionRequest*)), this, SLOT(newMessage(const proto::HyperionRequest*))); | ||||||
|  |  | ||||||
| 			// register forward signal for video mode |  | ||||||
| 			connect(this, SIGNAL(videoMode(VideoMode)), connection, SLOT(setVideoMode(VideoMode))); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void ProtoServer::newMessage(const proto::HyperionRequest * message) |  | ||||||
| { |  | ||||||
| 	for (int i = 0; i < _proxy_connections.size(); ++i) |  | ||||||
| 		_proxy_connections.at(i)->sendMessage(*message); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ProtoServer::sendImageToProtoSlaves(int priority, const Image<ColorRgb> & image, int duration_ms) |  | ||||||
| { |  | ||||||
| 	if ( _forwarder_enabled ) |  | ||||||
| 	{ |  | ||||||
| 		for (int i = 0; i < _proxy_connections.size(); ++i) |  | ||||||
| 			_proxy_connections.at(i)->setImage(image, priority, duration_ms); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ProtoServer::componentStateChanged(const hyperion::Components component, bool enable) |  | ||||||
| { |  | ||||||
| 	if (component == hyperion::COMP_FORWARDER) |  | ||||||
| 	{ |  | ||||||
| 		_forwarder_enabled = enable; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ProtoServer::closedConnection(ProtoClientConnection *connection) | void ProtoServer::closedConnection(ProtoClientConnection *connection) | ||||||
| { | { | ||||||
| 	Debug(_log, "Connection closed"); | 	Debug(_log, "Connection closed"); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| find_package(PythonLibs 3.4 REQUIRED) | find_package(PythonLibs 3.5 REQUIRED) | ||||||
|  |  | ||||||
| # Include the python directory. Also include the parent (which is for example /usr/include) | # Include the python directory. Also include the parent (which is for example /usr/include) | ||||||
| # which may be required when it is not includes by the (cross-) compiler by default. | # which may be required when it is not includes by the (cross-) compiler by default. | ||||||
|   | |||||||
| @@ -1,24 +1,21 @@ | |||||||
| // project includes | // project includes | ||||||
| #include <udplistener/UDPListener.h> | #include <udplistener/UDPListener.h> | ||||||
|  |  | ||||||
| // hyperion includes | // bonjour includes | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <bonjour/bonjourserviceregister.h> | #include <bonjour/bonjourserviceregister.h> | ||||||
|  |  | ||||||
| // hyperion util includes | // hyperion includes | ||||||
| #include "utils/ColorRgb.h" |  | ||||||
| #include "HyperionConfig.h" | #include "HyperionConfig.h" | ||||||
|  |  | ||||||
| // qt includes | // qt includes | ||||||
| #include <QUdpSocket> | #include <QUdpSocket> | ||||||
|  | #include <QJsonObject> | ||||||
|  |  | ||||||
| using namespace hyperion; | using namespace hyperion; | ||||||
|  |  | ||||||
| UDPListener::UDPListener(const QJsonDocument& config) : | UDPListener::UDPListener(const QJsonDocument& config) : | ||||||
| 	QObject(), | 	QObject(), | ||||||
| 	_hyperion(Hyperion::getInstance()), |  | ||||||
| 	_server(new QUdpSocket(this)), | 	_server(new QUdpSocket(this)), | ||||||
| 	_openConnections(), |  | ||||||
| 	_priority(0), | 	_priority(0), | ||||||
| 	_timeout(0), | 	_timeout(0), | ||||||
| 	_log(Logger::getInstance("UDPLISTENER")), | 	_log(Logger::getInstance("UDPLISTENER")), | ||||||
| @@ -26,10 +23,6 @@ UDPListener::UDPListener(const QJsonDocument& config) : | |||||||
| 	_listenPort(0) | 	_listenPort(0) | ||||||
| { | { | ||||||
| 	Debug(_log, "Instance created"); | 	Debug(_log, "Instance created"); | ||||||
| 	// listen for comp changes |  | ||||||
| 	connect(_hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool))); |  | ||||||
| 	// Set trigger for incoming connections |  | ||||||
| 	connect(_server, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); |  | ||||||
|  |  | ||||||
| 	// init | 	// init | ||||||
| 	handleSettingsUpdate(settings::UDPLISTENER, config); | 	handleSettingsUpdate(settings::UDPLISTENER, config); | ||||||
| @@ -40,7 +33,6 @@ UDPListener::~UDPListener() | |||||||
| 	// clear the current channel | 	// clear the current channel | ||||||
| 	stop(); | 	stop(); | ||||||
| 	delete _server; | 	delete _server; | ||||||
| 	_hyperion->clear(_priority); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -67,12 +59,17 @@ void UDPListener::start() | |||||||
| 			WarningIf( ! joinGroupOK, _log, "Multicast failed"); | 			WarningIf( ! joinGroupOK, _log, "Multicast failed"); | ||||||
| 		} | 		} | ||||||
| 		_isActive = true; | 		_isActive = true; | ||||||
| 		_hyperion->getComponentRegister().componentStateChanged(COMP_UDPLISTENER, _isActive); |  | ||||||
|  |  | ||||||
| 		if(_bonjourService == nullptr) | 		if(_serviceRegister == nullptr) | ||||||
| 		{ | 		{ | ||||||
| 			_bonjourService = new BonjourServiceRegister(); | 			_serviceRegister = new BonjourServiceRegister(this); | ||||||
| 			_bonjourService->registerService("_hyperiond-udp._udp", _listenPort); | 			_serviceRegister->registerService("_hyperiond-udp._udp", _listenPort); | ||||||
|  | 		} | ||||||
|  | 		else if( _serviceRegister->getPort() != _listenPort) | ||||||
|  | 		{ | ||||||
|  | 			delete _serviceRegister; | ||||||
|  | 			_serviceRegister = new BonjourServiceRegister(this); | ||||||
|  | 			_serviceRegister->registerService("_hyperiond-udp._udp", _listenPort); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -85,8 +82,7 @@ void UDPListener::stop() | |||||||
| 	_server->close(); | 	_server->close(); | ||||||
| 	_isActive = false; | 	_isActive = false; | ||||||
| 	Info(_log, "Stopped"); | 	Info(_log, "Stopped"); | ||||||
| 	_hyperion->clear(_priority); | 	emit clearGlobalPriority(_priority, hyperion::COMP_UDPLISTENER); | ||||||
| 	_hyperion->getComponentRegister().componentStateChanged(COMP_UDPLISTENER, _isActive); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void UDPListener::componentStateChanged(const hyperion::Components component, bool enable) | void UDPListener::componentStateChanged(const hyperion::Components component, bool enable) | ||||||
| @@ -124,20 +120,19 @@ void UDPListener::readPendingDatagrams() | |||||||
| void UDPListener::processTheDatagram(const QByteArray * datagram, const QHostAddress * sender) | void UDPListener::processTheDatagram(const QByteArray * datagram, const QHostAddress * sender) | ||||||
| { | { | ||||||
| 	int packetLedCount = datagram->size()/3; | 	int packetLedCount = datagram->size()/3; | ||||||
| 	int hyperionLedCount = Hyperion::getInstance()->getLedCount(); | 	//DebugIf( (packetLedCount != hyperionLedCount), _log, "packetLedCount (%d) != hyperionLedCount (%d)", packetLedCount, hyperionLedCount); | ||||||
| 	DebugIf( (packetLedCount != hyperionLedCount), _log, "packetLedCount (%d) != hyperionLedCount (%d)", packetLedCount, hyperionLedCount); |  | ||||||
|  |  | ||||||
| 	std::vector<ColorRgb> _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb::BLACK); | 	std::vector<ColorRgb> _ledColors(packetLedCount, ColorRgb::BLACK); | ||||||
|  |  | ||||||
| 	for (int ledIndex=0; ledIndex < qMin(packetLedCount, hyperionLedCount); ledIndex++) { | 	for (int ledIndex=0; ledIndex < packetLedCount; ledIndex++) { | ||||||
| 		ColorRgb & rgb =  _ledColors[ledIndex]; | 		ColorRgb & rgb =  _ledColors[ledIndex]; | ||||||
| 		rgb.red   = datagram->at(ledIndex*3+0); | 		rgb.red   = datagram->at(ledIndex*3+0); | ||||||
| 		rgb.green = datagram->at(ledIndex*3+1); | 		rgb.green = datagram->at(ledIndex*3+1); | ||||||
| 		rgb.blue  = datagram->at(ledIndex*3+2); | 		rgb.blue  = datagram->at(ledIndex*3+2); | ||||||
| 	} | 	} | ||||||
| 	// TODO provide a setInput with origin arg to overwrite senders smarter | 	// TODO provide a setInput with origin arg to overwrite senders smarter | ||||||
| 	_hyperion->registerInput(_priority, hyperion::COMP_UDPLISTENER, QString("UDPListener@%1").arg(sender->toString())); | 	emit registerGlobalInput(_priority, hyperion::COMP_UDPLISTENER, QString("UDPListener@%1").arg(sender->toString())); | ||||||
| 	_hyperion->setInput(_priority, _ledColors, _timeout); | 	emit setGlobalInput(_priority, _ledColors, _timeout); | ||||||
| } | } | ||||||
|  |  | ||||||
| void UDPListener::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | void UDPListener::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | ||||||
|   | |||||||
| @@ -13,11 +13,15 @@ | |||||||
| #include <QDir> | #include <QDir> | ||||||
| #include <QDateTime> | #include <QDateTime> | ||||||
|  |  | ||||||
| Stats::Stats() | Stats* Stats::instance = nullptr; | ||||||
|  |  | ||||||
|  | Stats::Stats(const QJsonObject& config) | ||||||
| 	: QObject() | 	: QObject() | ||||||
| 	, _log(Logger::getInstance("STATS")) | 	, _log(Logger::getInstance("STATS")) | ||||||
| 	, _hyperion(Hyperion::getInstance()) | 	, _hyperion(Hyperion::getInstance()) | ||||||
| { | { | ||||||
|  | 	Stats::instance = this; | ||||||
|  |  | ||||||
| 	// generate hash | 	// generate hash | ||||||
| 	foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) | 	foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) | ||||||
| 	{ | 	{ | ||||||
| @@ -38,8 +42,31 @@ Stats::Stats() | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// prep data | ||||||
|  | 	handleDataUpdate(config); | ||||||
|  |  | ||||||
|  | 	// QNetworkRequest Header | ||||||
|  | 	_req.setRawHeader("Content-Type", "application/json"); | ||||||
|  |    	_req.setRawHeader("Authorization", "Basic SHlwZXJpb25YbDQ5MlZrcXA6ZDQxZDhjZDk4ZjAwYjIw"); | ||||||
|  |  | ||||||
|  | 	connect(&_mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(resolveReply(QNetworkReply*))); | ||||||
|  |  | ||||||
|  | 	// 7 days interval | ||||||
|  | 	QTimer *timer = new QTimer(this); | ||||||
|  | 	connect(timer, SIGNAL(timeout()), this, SLOT(sendHTTP())); | ||||||
|  | 	timer->start(604800000); | ||||||
|  |  | ||||||
|  | 	// delay initial check | ||||||
|  | 	QTimer::singleShot(60000, this, SLOT(initialExec())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Stats::~Stats() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Stats::handleDataUpdate(const QJsonObject& config) | ||||||
|  | { | ||||||
| 	// prepare content | 	// prepare content | ||||||
| 	QJsonObject config = _hyperion->getQJsonConfig(); |  | ||||||
| 	SysInfo::HyperionSysInfo data = SysInfo::get(); | 	SysInfo::HyperionSysInfo data = SysInfo::get(); | ||||||
|  |  | ||||||
| 	QJsonObject system; | 	QJsonObject system; | ||||||
| @@ -63,25 +90,6 @@ Stats::Stats() | |||||||
|  |  | ||||||
| 	QJsonDocument doc(system); | 	QJsonDocument doc(system); | ||||||
| 	_ba = doc.toJson(); | 	_ba = doc.toJson(); | ||||||
|  |  | ||||||
| 	// QNetworkRequest Header |  | ||||||
| 	_req.setRawHeader("Content-Type", "application/json"); |  | ||||||
|    	_req.setRawHeader("Authorization", "Basic SHlwZXJpb25YbDQ5MlZrcXA6ZDQxZDhjZDk4ZjAwYjIw"); |  | ||||||
|  |  | ||||||
| 	connect(&_mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(resolveReply(QNetworkReply*))); |  | ||||||
|  |  | ||||||
| 	// 7 days interval |  | ||||||
| 	QTimer *timer = new QTimer(this); |  | ||||||
| 	connect(timer, SIGNAL(timeout()), this, SLOT(sendHTTP())); |  | ||||||
| 	timer->start(604800000); |  | ||||||
|  |  | ||||||
| 	//delay initial check |  | ||||||
| 	QTimer::singleShot(60000, this, SLOT(initialExec())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| Stats::~Stats() |  | ||||||
| { |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Stats::initialExec() | void Stats::initialExec() | ||||||
|   | |||||||
| @@ -13,11 +13,9 @@ | |||||||
| #include <utils/Process.h> | #include <utils/Process.h> | ||||||
| #include <utils/jsonschema/QJsonFactory.h> | #include <utils/jsonschema/QJsonFactory.h> | ||||||
|  |  | ||||||
| CgiHandler::CgiHandler (Hyperion * hyperion, QObject * parent) | CgiHandler::CgiHandler (QObject * parent) | ||||||
| 	: QObject(parent) | 	: QObject(parent) | ||||||
| 	, _hyperion(hyperion) |  | ||||||
| 	, _args(QStringList()) | 	, _args(QStringList()) | ||||||
| 	, _hyperionConfig(_hyperion->getQJsonConfig()) |  | ||||||
| 	, _baseUrl() | 	, _baseUrl() | ||||||
| 	, _log(Logger::getInstance("WEBSERVER")) | 	, _log(Logger::getInstance("WEBSERVER")) | ||||||
| { | { | ||||||
| @@ -57,11 +55,6 @@ void CgiHandler::cmd_cfg_jsonserver() | |||||||
| 	if ( _args.at(0) == "cfg_jsonserver" ) | 	if ( _args.at(0) == "cfg_jsonserver" ) | ||||||
| 	{ | 	{ | ||||||
| 		quint16 jsonPort = 19444; | 		quint16 jsonPort = 19444; | ||||||
| 		if (_hyperionConfig.contains("jsonServer")) |  | ||||||
| 		{ |  | ||||||
| 			const QJsonObject jsonConfig = _hyperionConfig["jsonServer"].toObject(); |  | ||||||
| 			jsonPort = jsonConfig["port"].toInt(jsonPort); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// send result as reply | 		// send result as reply | ||||||
| 		_reply->addHeader ("Content-Type", "text/plain" ); | 		_reply->addHeader ("Content-Type", "text/plain" ); | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| #include <QString> | #include <QString> | ||||||
| #include <QStringList> | #include <QStringList> | ||||||
|  |  | ||||||
| #include <hyperion/Hyperion.h> |  | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
|  |  | ||||||
| #include "QtHttpReply.h" | #include "QtHttpReply.h" | ||||||
| @@ -15,7 +14,7 @@ class CgiHandler : public QObject { | |||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	CgiHandler (Hyperion * hyperion, QObject * parent = NULL); | 	CgiHandler (QObject * parent = NULL); | ||||||
| 	virtual ~CgiHandler (void); | 	virtual ~CgiHandler (void); | ||||||
|  |  | ||||||
| 	void setBaseUrl(const QString& url); | 	void setBaseUrl(const QString& url); | ||||||
| @@ -26,11 +25,9 @@ public: | |||||||
| 	void cmd_runscript (); | 	void cmd_runscript (); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	Hyperion*           _hyperion; |  | ||||||
| 	QtHttpReply *       _reply; | 	QtHttpReply *       _reply; | ||||||
| 	QtHttpRequest *     _request; | 	QtHttpRequest *     _request; | ||||||
| 	QStringList         _args; | 	QStringList         _args; | ||||||
| 	const QJsonObject & _hyperionConfig; |  | ||||||
| 	QString             _baseUrl; | 	QString             _baseUrl; | ||||||
| 	Logger *            _log; | 	Logger *            _log; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -49,6 +49,8 @@ public: | |||||||
| 	quint16 getServerPort    (void) const; | 	quint16 getServerPort    (void) const; | ||||||
| 	QString getErrorString   (void) const; | 	QString getErrorString   (void) const; | ||||||
|  |  | ||||||
|  | //	const bool isListening(void) { return m_sockServer->isListening(); }; | ||||||
|  |  | ||||||
| public slots: | public slots: | ||||||
| 	void start           (quint16 port = 0); | 	void start           (quint16 port = 0); | ||||||
| 	void stop            (void); | 	void stop            (void); | ||||||
|   | |||||||
| @@ -10,11 +10,10 @@ | |||||||
| #include <QResource> | #include <QResource> | ||||||
| #include <exception> | #include <exception> | ||||||
|  |  | ||||||
| StaticFileServing::StaticFileServing (Hyperion *hyperion, QObject * parent) | StaticFileServing::StaticFileServing (QObject * parent) | ||||||
| 	:  QObject   (parent) | 	:  QObject   (parent) | ||||||
| 	, _hyperion(hyperion) |  | ||||||
| 	, _baseUrl () | 	, _baseUrl () | ||||||
| 	, _cgi(hyperion, this) | 	, _cgi(this) | ||||||
| 	, _log(Logger::getInstance("WEBSERVER")) | 	, _log(Logger::getInstance("WEBSERVER")) | ||||||
| { | { | ||||||
| 	Q_INIT_RESOURCE(WebConfig); | 	Q_INIT_RESOURCE(WebConfig); | ||||||
|   | |||||||
| @@ -1,22 +1,23 @@ | |||||||
| #ifndef STATICFILESERVING_H | #ifndef STATICFILESERVING_H | ||||||
| #define STATICFILESERVING_H | #define STATICFILESERVING_H | ||||||
|  |  | ||||||
| #include <QMimeDatabase> | // locales includes | ||||||
|  | #include "CgiHandler.h" | ||||||
|  |  | ||||||
| //#include "QtHttpServer.h" | // qt includes | ||||||
|  | #include <QMimeDatabase> | ||||||
| #include "QtHttpRequest.h" | #include "QtHttpRequest.h" | ||||||
| #include "QtHttpReply.h" | #include "QtHttpReply.h" | ||||||
| #include "QtHttpHeader.h" | #include "QtHttpHeader.h" | ||||||
| #include "CgiHandler.h" |  | ||||||
|  |  | ||||||
| #include <hyperion/Hyperion.h> | //utils includes | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
|  |  | ||||||
| class StaticFileServing : public QObject { | class StaticFileServing : public QObject { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     explicit StaticFileServing (Hyperion *hyperion, QObject * parent = nullptr); |     explicit StaticFileServing (QObject * parent = nullptr); | ||||||
|     virtual ~StaticFileServing (void); |     virtual ~StaticFileServing (void); | ||||||
|  |  | ||||||
| 	void setBaseUrl(const QString& url); | 	void setBaseUrl(const QString& url); | ||||||
| @@ -25,7 +26,6 @@ public slots: | |||||||
|     void onRequestNeedsReply  (QtHttpRequest * request, QtHttpReply * reply); |     void onRequestNeedsReply  (QtHttpRequest * request, QtHttpReply * reply); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	Hyperion      * _hyperion; |  | ||||||
| 	QString         _baseUrl; | 	QString         _baseUrl; | ||||||
| 	QMimeDatabase * _mimeDb; | 	QMimeDatabase * _mimeDb; | ||||||
| 	CgiHandler      _cgi; | 	CgiHandler      _cgi; | ||||||
|   | |||||||
| @@ -1,7 +1,11 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | // utils includes | ||||||
| #include <utils/Logger.h> | #include <utils/Logger.h> | ||||||
|  |  | ||||||
|  | // qt includes | ||||||
|  | #include <QJsonObject> | ||||||
|  |  | ||||||
| class QtHttpServer; | class QtHttpServer; | ||||||
| class QtHttpRequest; | class QtHttpRequest; | ||||||
| class QtHttpClientWrapper; | class QtHttpClientWrapper; | ||||||
|   | |||||||
| @@ -1,17 +1,21 @@ | |||||||
| #include "webserver/WebServer.h" | #include "webserver/WebServer.h" | ||||||
| #include "StaticFileServing.h" | #include "StaticFileServing.h" | ||||||
| #include "QtHttpServer.h" |  | ||||||
|  |  | ||||||
| // bonjour | // qt includes | ||||||
|  | #include "QtHttpServer.h" | ||||||
|  | #include <QFileInfo> | ||||||
|  | #include <QJsonObject> | ||||||
|  |  | ||||||
|  | // bonjour includes | ||||||
| #include <bonjour/bonjourserviceregister.h> | #include <bonjour/bonjourserviceregister.h> | ||||||
| #include <bonjour/bonjourrecord.h> | #include <bonjour/bonjourrecord.h> | ||||||
|  |  | ||||||
| #include <QFileInfo> | // utils includes | ||||||
|  | #include <utils/NetUtils.h> | ||||||
|  |  | ||||||
| WebServer::WebServer(const QJsonDocument& config, QObject * parent) | WebServer::WebServer(const QJsonDocument& config, QObject * parent) | ||||||
| 	:  QObject(parent) | 	:  QObject(parent) | ||||||
| 	, _log(Logger::getInstance("WEBSERVER")) | 	, _log(Logger::getInstance("WEBSERVER")) | ||||||
| 	, _hyperion(Hyperion::getInstance()) |  | ||||||
| 	, _server(new QtHttpServer (this)) | 	, _server(new QtHttpServer (this)) | ||||||
| { | { | ||||||
| 	_server->setServerName (QStringLiteral ("Hyperion Webserver")); | 	_server->setServerName (QStringLiteral ("Hyperion Webserver")); | ||||||
| @@ -21,7 +25,7 @@ WebServer::WebServer(const QJsonDocument& config, QObject * parent) | |||||||
| 	connect (_server, &QtHttpServer::error,   this, &WebServer::onServerError); | 	connect (_server, &QtHttpServer::error,   this, &WebServer::onServerError); | ||||||
|  |  | ||||||
| 	// create StaticFileServing | 	// create StaticFileServing | ||||||
| 	_staticFileServing = new StaticFileServing (_hyperion, this); | 	_staticFileServing = new StaticFileServing (this); | ||||||
| 	connect(_server, &QtHttpServer::requestNeedsReply, _staticFileServing, &StaticFileServing::onRequestNeedsReply); | 	connect(_server, &QtHttpServer::requestNeedsReply, _staticFileServing, &StaticFileServing::onRequestNeedsReply); | ||||||
|  |  | ||||||
| 	Debug(_log, "Instance created"); | 	Debug(_log, "Instance created"); | ||||||
| @@ -38,8 +42,17 @@ void WebServer::onServerStarted (quint16 port) | |||||||
| { | { | ||||||
| 	Info(_log, "Started on port %d name '%s'", port ,_server->getServerName().toStdString().c_str()); | 	Info(_log, "Started on port %d name '%s'", port ,_server->getServerName().toStdString().c_str()); | ||||||
|  |  | ||||||
| 	BonjourServiceRegister *bonjourRegister_http = new BonjourServiceRegister(); | 	if(_serviceRegister == nullptr) | ||||||
| 	bonjourRegister_http->registerService("_hyperiond-http._tcp", port); | 	{ | ||||||
|  | 		_serviceRegister = new BonjourServiceRegister(this); | ||||||
|  | 		_serviceRegister->registerService("_hyperiond-http._tcp", port); | ||||||
|  | 	} | ||||||
|  | 	else if( _serviceRegister->getPort() != port) | ||||||
|  | 	{ | ||||||
|  | 		delete _serviceRegister; | ||||||
|  | 		_serviceRegister = new BonjourServiceRegister(this); | ||||||
|  | 		_serviceRegister->registerService("_hyperiond-http._tcp", port); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebServer::onServerStopped () { | void WebServer::onServerStopped () { | ||||||
| @@ -57,10 +70,8 @@ void WebServer::handleSettingsUpdate(const settings::type& type, const QJsonDocu | |||||||
| 	{ | 	{ | ||||||
| 		const QJsonObject& obj = config.object(); | 		const QJsonObject& obj = config.object(); | ||||||
|  |  | ||||||
| 		bool webconfigEnable = obj["enable"].toBool(true); |  | ||||||
| 		_baseUrl = obj["document_root"].toString(WEBSERVER_DEFAULT_PATH); | 		_baseUrl = obj["document_root"].toString(WEBSERVER_DEFAULT_PATH); | ||||||
|  |  | ||||||
|  |  | ||||||
| 		if ( (_baseUrl != ":/webconfig") && !_baseUrl.trimmed().isEmpty()) | 		if ( (_baseUrl != ":/webconfig") && !_baseUrl.trimmed().isEmpty()) | ||||||
| 		{ | 		{ | ||||||
| 			QFileInfo info(_baseUrl); | 			QFileInfo info(_baseUrl); | ||||||
| @@ -81,11 +92,11 @@ void WebServer::handleSettingsUpdate(const settings::type& type, const QJsonDocu | |||||||
| 			_port = obj["port"].toInt(WEBSERVER_DEFAULT_PORT); | 			_port = obj["port"].toInt(WEBSERVER_DEFAULT_PORT); | ||||||
| 			stop(); | 			stop(); | ||||||
| 		} | 		} | ||||||
| 		if ( webconfigEnable ) |  | ||||||
| 		{ | 		// eval if the port is available, will be incremented if not | ||||||
|  | 		NetUtils::portAvailable(_port, _log); | ||||||
| 		start(); | 		start(); | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebServer::start() | void WebServer::start() | ||||||
|   | |||||||
| @@ -1,13 +1,18 @@ | |||||||
| #include "WebSocketClient.h" | #include "WebSocketClient.h" | ||||||
| #include "QtHttpRequest.h" |  | ||||||
| #include "QtHttpHeader.h" |  | ||||||
|  |  | ||||||
|  | // hyperion includes | ||||||
| #include <hyperion/Hyperion.h> | #include <hyperion/Hyperion.h> | ||||||
|  |  | ||||||
|  | // JsonAPI includes | ||||||
| #include <api/JsonAPI.h> | #include <api/JsonAPI.h> | ||||||
|  |  | ||||||
|  | // qt includes | ||||||
|  | #include "QtHttpRequest.h" | ||||||
|  | #include "QtHttpHeader.h" | ||||||
| #include <QTcpSocket> | #include <QTcpSocket> | ||||||
| #include <QtEndian> | #include <QtEndian> | ||||||
| #include <QCryptographicHash> | #include <QCryptographicHash> | ||||||
|  | #include <QJsonObject> | ||||||
|  |  | ||||||
| WebSocketClient::WebSocketClient(QtHttpRequest* request, QTcpSocket* sock, QObject* parent) | WebSocketClient::WebSocketClient(QtHttpRequest* request, QTcpSocket* sock, QObject* parent) | ||||||
| 	: QObject(parent) | 	: QObject(parent) | ||||||
|   | |||||||
| @@ -56,10 +56,9 @@ int main(int argc, char** argv) | |||||||
| 		// create the option parser and initialize all parameters | 		// create the option parser and initialize all parameters | ||||||
| 		Parser parser("V4L capture application for Hyperion"); | 		Parser parser("V4L capture application for Hyperion"); | ||||||
|  |  | ||||||
| 		Option             & argDevice              = parser.add<Option>       ('d', "device", "The device to use [default: %1]", "auto"); | 		Option             & argDevice              = parser.add<Option>       ('d', "device", "The device to use, can be /dev/video0 [default: %1 (auto detected)]", "auto"); | ||||||
| 		SwitchOption<VideoStandard> & argVideoStandard= parser.add<SwitchOption<VideoStandard>>('v', "video-standard", "The used video standard. Valid values are PAL, NTSC, SECAM or no-change. [default: %1]", "no-change"); | 		SwitchOption<VideoStandard> & argVideoStandard= parser.add<SwitchOption<VideoStandard>>('v', "video-standard", "The used video standard. Valid values are PAL, NTSC, SECAM or no-change. [default: %1]", "no-change"); | ||||||
| 		SwitchOption<PixelFormat> & argPixelFormat    = parser.add<SwitchOption<PixelFormat>>  (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, RGB32 or no-change. [default: %1]", "no-change"); | 		SwitchOption<PixelFormat> & argPixelFormat    = parser.add<SwitchOption<PixelFormat>>  (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, RGB32 or no-change. [default: %1]", "no-change"); | ||||||
| 		IntOption          & argInput               = parser.add<IntOption>    (0x0, "input", "Input channel (optional)", "-1"); |  | ||||||
| 		IntOption          & argCropWidth           = parser.add<IntOption>    (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: %1]", "0"); | 		IntOption          & argCropWidth           = parser.add<IntOption>    (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: %1]", "0"); | ||||||
| 		IntOption          & argCropHeight          = parser.add<IntOption>    (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: %1]", "0"); | 		IntOption          & argCropHeight          = parser.add<IntOption>    (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: %1]", "0"); | ||||||
| 		IntOption          & argCropLeft            = parser.add<IntOption>    (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)"); | 		IntOption          & argCropLeft            = parser.add<IntOption>    (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)"); | ||||||
| @@ -109,7 +108,6 @@ int main(int argc, char** argv) | |||||||
| 		// initialize the grabber | 		// initialize the grabber | ||||||
| 		V4L2Grabber grabber( | 		V4L2Grabber grabber( | ||||||
| 					argDevice.value(parser), | 					argDevice.value(parser), | ||||||
| 					argInput.getInt(parser), |  | ||||||
| 					argVideoStandard.switchValue(parser), | 					argVideoStandard.switchValue(parser), | ||||||
| 					argPixelFormat.switchValue(parser), | 					argPixelFormat.switchValue(parser), | ||||||
| 					std::max(1, argSizeDecimation.getInt(parser))); | 					std::max(1, argSizeDecimation.getInt(parser))); | ||||||
|   | |||||||
| @@ -36,8 +36,9 @@ bool X11Wrapper::displayInit() | |||||||
|  |  | ||||||
| void X11Wrapper::capture() | void X11Wrapper::capture() | ||||||
| { | { | ||||||
| 	_grabber.grabFrame(_screenshot, true); | 	_grabber.grabFrame(_screenshot, !_inited); | ||||||
| 	emit sig_screenshot(_screenshot); | 	emit sig_screenshot(_screenshot); | ||||||
|  | 	_inited = true; | ||||||
| } | } | ||||||
|  |  | ||||||
| void X11Wrapper::setVideoMode(const VideoMode mode) | void X11Wrapper::setVideoMode(const VideoMode mode) | ||||||
|   | |||||||
| @@ -50,4 +50,7 @@ private: | |||||||
| 	X11Grabber _grabber; | 	X11Grabber _grabber; | ||||||
|  |  | ||||||
| 	Image<ColorRgb>  _screenshot; | 	Image<ColorRgb>  _screenshot; | ||||||
|  |  | ||||||
|  | 	// prevent cont dimension updates | ||||||
|  | 	bool _inited = false; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
|  |  | ||||||
| find_package(PythonLibs 3.4 REQUIRED) | find_package(PythonLibs 3.5 REQUIRED) | ||||||
| include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..) | ||||||
|  |  | ||||||
| add_executable(hyperiond | add_executable(hyperiond | ||||||
| @@ -15,9 +15,9 @@ target_link_libraries(hyperiond | |||||||
| 		hyperion | 		hyperion | ||||||
| 		effectengine | 		effectengine | ||||||
| 		jsonserver | 		jsonserver | ||||||
| 		boblightserver |  | ||||||
| 		udplistener | 		udplistener | ||||||
| 		protoserver | 		protoserver | ||||||
|  | 		flatbufserver | ||||||
| 		webserver | 		webserver | ||||||
| 		bonjour | 		bonjour | ||||||
| 		python | 		python | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
| #include <QPair> | #include <QPair> | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <limits> | #include <limits> | ||||||
|  | #include <QThread> | ||||||
|  |  | ||||||
| #include <utils/Components.h> | #include <utils/Components.h> | ||||||
| #include <utils/JsonUtils.h> | #include <utils/JsonUtils.h> | ||||||
| @@ -21,13 +22,15 @@ | |||||||
| #include <hyperion/Hyperion.h> | #include <hyperion/Hyperion.h> | ||||||
| #include <jsonserver/JsonServer.h> | #include <jsonserver/JsonServer.h> | ||||||
| #include <protoserver/ProtoServer.h> | #include <protoserver/ProtoServer.h> | ||||||
| #include <boblightserver/BoblightServer.h> |  | ||||||
| #include <udplistener/UDPListener.h> | #include <udplistener/UDPListener.h> | ||||||
| #include <webserver/WebServer.h> | #include <webserver/WebServer.h> | ||||||
| #include <utils/Stats.h> | #include <utils/Stats.h> | ||||||
| #include <HyperionConfig.h> // Required to determine the cmake options | #include <HyperionConfig.h> // Required to determine the cmake options | ||||||
| #include "hyperiond.h" | #include "hyperiond.h" | ||||||
|  |  | ||||||
|  | // FlatBufferServer | ||||||
|  | #include <flatbufserver/FlatBufferServer.h> | ||||||
|  |  | ||||||
| // bonjour browser | // bonjour browser | ||||||
| #include <bonjour/bonjourbrowserwrapper.h> | #include <bonjour/bonjourbrowserwrapper.h> | ||||||
|  |  | ||||||
| @@ -39,7 +42,7 @@ | |||||||
|  |  | ||||||
| HyperionDaemon* HyperionDaemon::daemon = nullptr; | HyperionDaemon* HyperionDaemon::daemon = nullptr; | ||||||
|  |  | ||||||
| HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObject *parent) | HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObject *parent, const bool& logLvlOverwrite) | ||||||
| 	: QObject(parent) | 	: QObject(parent) | ||||||
| 	, _log(Logger::getInstance("DAEMON")) | 	, _log(Logger::getInstance("DAEMON")) | ||||||
| 	, _bonjourBrowserWrapper(new BonjourBrowserWrapper()) | 	, _bonjourBrowserWrapper(new BonjourBrowserWrapper()) | ||||||
| @@ -47,7 +50,6 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje | |||||||
| 	, _webserver(nullptr) | 	, _webserver(nullptr) | ||||||
| 	, _jsonServer(nullptr) | 	, _jsonServer(nullptr) | ||||||
| 	, _protoServer(nullptr) | 	, _protoServer(nullptr) | ||||||
| 	, _boblightServer(nullptr) |  | ||||||
| 	, _udpListener(nullptr) | 	, _udpListener(nullptr) | ||||||
| 	, _v4l2Grabbers() | 	, _v4l2Grabbers() | ||||||
| 	, _dispmanx(nullptr) | 	, _dispmanx(nullptr) | ||||||
| @@ -61,23 +63,19 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje | |||||||
| { | { | ||||||
| 	HyperionDaemon::daemon = this; | 	HyperionDaemon::daemon = this; | ||||||
|  |  | ||||||
|  | 	// Register metas for thread queued connection | ||||||
|  | 	qRegisterMetaType<Image<ColorRgb>>("Image<ColorRgb>"); | ||||||
|  | 	qRegisterMetaType<hyperion::Components>("hyperion::Components"); | ||||||
|  | 	qRegisterMetaType<settings::type>("settings::type"); | ||||||
|  |  | ||||||
| 	// init settings | 	// init settings | ||||||
| 	_settingsManager = new SettingsManager(0,configFile); | 	_settingsManager = new SettingsManager(0,configFile); | ||||||
|  |  | ||||||
| 	const QJsonObject& logConfig = _settingsManager->getSetting(settings::LOGGER).object(); | 	// set inital log lvl if the loglvl wasn't overwritten by arg | ||||||
| 	if (Logger::getLogLevel() == Logger::WARNING) | 	if(!logLvlOverwrite) | ||||||
| 	{ | 		handleSettingsUpdate(settings::LOGGER, _settingsManager->getSetting(settings::LOGGER)); | ||||||
| 		std::string level = logConfig["level"].toString("warn").toStdString(); // silent warn verbose debug |  | ||||||
| 		if (level == "silent")       Logger::setLogLevel(Logger::OFF); |  | ||||||
| 		else if (level == "warn")    Logger::setLogLevel(Logger::WARNING); |  | ||||||
| 		else if (level == "verbose") Logger::setLogLevel(Logger::INFO); |  | ||||||
| 		else if (level == "debug")   Logger::setLogLevel(Logger::DEBUG); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		Warning(Logger::getInstance("LOGGER"), "Logger settings overridden by command line argument"); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|  | 	// spawn all Hyperion instances before network services | ||||||
| 	_hyperion = Hyperion::initInstance(this, 0, configFile, rootPath); | 	_hyperion = Hyperion::initInstance(this, 0, configFile, rootPath); | ||||||
|  |  | ||||||
| 	Info(_log, "Hyperion initialized"); | 	Info(_log, "Hyperion initialized"); | ||||||
| @@ -141,7 +139,8 @@ void HyperionDaemon::freeObjects() | |||||||
| 	delete _webserver; | 	delete _webserver; | ||||||
| 	delete _jsonServer; | 	delete _jsonServer; | ||||||
| 	delete _protoServer; | 	delete _protoServer; | ||||||
| 	delete _boblightServer; | 	_flatBufferServer->thread()->quit(); | ||||||
|  | 	_flatBufferServer->thread()->wait(1000); | ||||||
| 	delete _udpListener; | 	delete _udpListener; | ||||||
|  |  | ||||||
| 	delete _bonjourBrowserWrapper; | 	delete _bonjourBrowserWrapper; | ||||||
| @@ -164,15 +163,14 @@ void HyperionDaemon::freeObjects() | |||||||
| 	_webserver      = nullptr; | 	_webserver      = nullptr; | ||||||
| 	_jsonServer     = nullptr; | 	_jsonServer     = nullptr; | ||||||
| 	_protoServer    = nullptr; | 	_protoServer    = nullptr; | ||||||
| 	_boblightServer = nullptr; |  | ||||||
| 	_udpListener    = nullptr; | 	_udpListener    = nullptr; | ||||||
| 	_stats          = nullptr; | 	_stats          = nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| void HyperionDaemon::startNetworkServices() | void HyperionDaemon::startNetworkServices() | ||||||
| { | { | ||||||
| 	// Create Stats before network services | 	// Create Stats | ||||||
| 	_stats = new Stats(); | 	_stats = new Stats(_settingsManager->getSettings()); | ||||||
|  |  | ||||||
| 	// Create Json server | 	// Create Json server | ||||||
| 	_jsonServer = new JsonServer(getSetting(settings::JSONSERVER)); | 	_jsonServer = new JsonServer(getSetting(settings::JSONSERVER)); | ||||||
| @@ -181,11 +179,17 @@ void HyperionDaemon::startNetworkServices() | |||||||
| 	// Create Proto server | 	// Create Proto server | ||||||
| 	_protoServer = new ProtoServer(getSetting(settings::PROTOSERVER)); | 	_protoServer = new ProtoServer(getSetting(settings::PROTOSERVER)); | ||||||
| 	connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate); | 	connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate); | ||||||
| 	//QObject::connect(_hyperion, SIGNAL(videoMode(VideoMode)), _protoServer, SLOT(setVideoMode(VideoMode))); |  | ||||||
|  |  | ||||||
| 	// boblight server | 	// Create FlatBuffer server & move to Thread | ||||||
| 	_boblightServer = new BoblightServer(getSetting(settings::BOBLSERVER)); | 	_flatBufferServer = new FlatBufferServer(getSetting(settings::FLATBUFSERVER)); | ||||||
| 	connect(this, &HyperionDaemon::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate); | 	connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate); | ||||||
|  | 	QThread* fbThread = new QThread(this); | ||||||
|  |  | ||||||
|  | 	_flatBufferServer->moveToThread(fbThread); | ||||||
|  | 	connect( fbThread, &QThread::started, _flatBufferServer, &FlatBufferServer::initServer ); | ||||||
|  | 	connect( fbThread, &QThread::finished, _flatBufferServer, &QObject::deleteLater ); | ||||||
|  | 	connect( fbThread, &QThread::finished, fbThread, &QObject::deleteLater ); | ||||||
|  | 	fbThread->start(); | ||||||
|  |  | ||||||
| 	// Create UDP listener | 	// Create UDP listener | ||||||
| 	_udpListener = new UDPListener(getSetting(settings::UDPLISTENER)); | 	_udpListener = new UDPListener(getSetting(settings::UDPLISTENER)); | ||||||
| @@ -198,6 +202,17 @@ void HyperionDaemon::startNetworkServices() | |||||||
|  |  | ||||||
| void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) | ||||||
| { | { | ||||||
|  | 	if(type == settings::LOGGER) | ||||||
|  | 	{ | ||||||
|  | 		const QJsonObject & logConfig = config.object(); | ||||||
|  |  | ||||||
|  | 		std::string level = logConfig["level"].toString("warn").toStdString(); // silent warn verbose debug | ||||||
|  | 		if (level == "silent")       Logger::setLogLevel(Logger::OFF); | ||||||
|  | 		else if (level == "warn")    Logger::setLogLevel(Logger::WARNING); | ||||||
|  | 		else if (level == "verbose") Logger::setLogLevel(Logger::INFO); | ||||||
|  | 		else if (level == "debug")   Logger::setLogLevel(Logger::DEBUG); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if(type == settings::SYSTEMCAPTURE) | 	if(type == settings::SYSTEMCAPTURE) | ||||||
| 	{ | 	{ | ||||||
| 		const QJsonObject & grabberConfig = config.object(); | 		const QJsonObject & grabberConfig = config.object(); | ||||||
| @@ -249,7 +264,6 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso | |||||||
| 		else if (type == "amlogic" && _amlGrabber == nullptr)      createGrabberAmlogic(); | 		else if (type == "amlogic" && _amlGrabber == nullptr)      createGrabberAmlogic(); | ||||||
| 		else if (type == "osx" && _osxGrabber == nullptr)          createGrabberOsx(grabberConfig); | 		else if (type == "osx" && _osxGrabber == nullptr)          createGrabberOsx(grabberConfig); | ||||||
| 		else if (type == "x11" && _x11Grabber == nullptr)          createGrabberX11(grabberConfig); | 		else if (type == "x11" && _x11Grabber == nullptr)          createGrabberX11(grabberConfig); | ||||||
| 		else { Warning( _log, "unknown framegrabber type '%s'", QSTRING_CSTR(type)); } |  | ||||||
| 	} | 	} | ||||||
| 	else if(type == settings::V4L2) | 	else if(type == settings::V4L2) | ||||||
| 	{ | 	{ | ||||||
| @@ -268,7 +282,6 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso | |||||||
| 			#ifdef ENABLE_V4L2 | 			#ifdef ENABLE_V4L2 | ||||||
| 			V4L2Wrapper* grabber = new V4L2Wrapper( | 			V4L2Wrapper* grabber = new V4L2Wrapper( | ||||||
| 				grabberConfig["device"].toString("auto"), | 				grabberConfig["device"].toString("auto"), | ||||||
| 				grabberConfig["input"].toInt(0), |  | ||||||
| 				parseVideoStandard(grabberConfig["standard"].toString("no-change")), | 				parseVideoStandard(grabberConfig["standard"].toString("no-change")), | ||||||
| 				parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")), | 				parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")), | ||||||
| 				grabberConfig["sizeDecimation"].toInt(8) ); | 				grabberConfig["sizeDecimation"].toInt(8) ); | ||||||
| @@ -294,10 +307,6 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso | |||||||
| 			connect(this, &HyperionDaemon::videoMode, grabber, &V4L2Wrapper::setVideoMode); | 			connect(this, &HyperionDaemon::videoMode, grabber, &V4L2Wrapper::setVideoMode); | ||||||
| 			connect(this, &HyperionDaemon::settingsChanged, grabber, &V4L2Wrapper::handleSettingsUpdate); | 			connect(this, &HyperionDaemon::settingsChanged, grabber, &V4L2Wrapper::handleSettingsUpdate); | ||||||
|  |  | ||||||
| 			if (grabber->start()) |  | ||||||
| 			{ |  | ||||||
| 				Info(_log, "V4L2 grabber started"); |  | ||||||
| 			} |  | ||||||
| 			_v4l2Grabbers.push_back(grabber); | 			_v4l2Grabbers.push_back(grabber); | ||||||
| 			#endif | 			#endif | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -50,13 +50,13 @@ class Hyperion; | |||||||
| class SysTray; | class SysTray; | ||||||
| class JsonServer; | class JsonServer; | ||||||
| class ProtoServer; | class ProtoServer; | ||||||
| class BoblightServer; |  | ||||||
| class UDPListener; | class UDPListener; | ||||||
| class Stats; | class Stats; | ||||||
| class BonjourBrowserWrapper; | class BonjourBrowserWrapper; | ||||||
| class WebServer; | class WebServer; | ||||||
| class SettingsManager; | class SettingsManager; | ||||||
| class PythonInit; | class PythonInit; | ||||||
|  | class FlatBufferServer; | ||||||
|  |  | ||||||
| class HyperionDaemon : public QObject | class HyperionDaemon : public QObject | ||||||
| { | { | ||||||
| @@ -65,7 +65,7 @@ class HyperionDaemon : public QObject | |||||||
| 	friend SysTray; | 	friend SysTray; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	HyperionDaemon(QString configFile, QString rootPath, QObject *parent=nullptr); | 	HyperionDaemon(QString configFile, QString rootPath, QObject *parent, const bool& logLvlOverwrite ); | ||||||
| 	~HyperionDaemon(); | 	~HyperionDaemon(); | ||||||
|  |  | ||||||
| 	quint16 getWebServerPort(); | 	quint16 getWebServerPort(); | ||||||
| @@ -135,7 +135,6 @@ private: | |||||||
| 	WebServer*             _webserver; | 	WebServer*             _webserver; | ||||||
| 	JsonServer*            _jsonServer; | 	JsonServer*            _jsonServer; | ||||||
| 	ProtoServer*           _protoServer; | 	ProtoServer*           _protoServer; | ||||||
| 	BoblightServer*        _boblightServer; |  | ||||||
| 	UDPListener*           _udpListener; | 	UDPListener*           _udpListener; | ||||||
| 	std::vector<V4L2Wrapper*>  _v4l2Grabbers; | 	std::vector<V4L2Wrapper*>  _v4l2Grabbers; | ||||||
| 	DispmanxWrapper*       _dispmanx; | 	DispmanxWrapper*       _dispmanx; | ||||||
| @@ -145,6 +144,7 @@ private: | |||||||
| 	OsxWrapper*            _osxGrabber; | 	OsxWrapper*            _osxGrabber; | ||||||
| 	Hyperion*              _hyperion; | 	Hyperion*              _hyperion; | ||||||
| 	Stats*                 _stats; | 	Stats*                 _stats; | ||||||
|  | 	FlatBufferServer* _flatBufferServer; | ||||||
|  |  | ||||||
| 	unsigned            _grabber_width; | 	unsigned            _grabber_width; | ||||||
| 	unsigned            _grabber_height; | 	unsigned            _grabber_height; | ||||||
|   | |||||||
| @@ -317,7 +317,7 @@ int main(int argc, char** argv) | |||||||
| 	HyperionDaemon* hyperiond = nullptr; | 	HyperionDaemon* hyperiond = nullptr; | ||||||
| 	try | 	try | ||||||
| 	{ | 	{ | ||||||
| 		hyperiond = new HyperionDaemon(configFiles[0], rootPath, qApp); | 		hyperiond = new HyperionDaemon(configFiles[0], rootPath, qApp, bool(logLevelCheck)); | ||||||
| 	} | 	} | ||||||
| 	catch (std::exception& e) | 	catch (std::exception& e) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user