diff --git a/config/hyperion.config.json b/config/hyperion.config.json index 2f22a63d..e83f7e98 100644 --- a/config/hyperion.config.json +++ b/config/hyperion.config.json @@ -1,41 +1,73 @@ // Hyperion configuration { + /// Device configuration contains the following fields: + /// * 'name' : The user friendly name of the device (only used for display purposes) + /// * 'type' : The type of the device or leds (known types for now are 'ws2801', 'test' and + /// 'none') + /// * 'output' : The output specification depends on selected device + /// - 'ws2801' this is the device (eg '/dev/spidev0.0') + /// - 'test' this is the file used to write test output (eg + /// '/home/pi/hyperion.out') + /// * 'rate' : The baudrate of the output to the device (only applicable for 'ws2801') "device" : { "name" : "MyPi", "type" : "ws2801", "output" : "/dev/spidev0.0", - "interval" : 20000, - "rate" : 48000 + "rate" : 1000000 }, + + /// Color manipulation configuration used to tune the output colors to specific surroundings. + /// Contains the following fields: + /// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following + /// tuning parameters: + /// - 'saturationGain' The gain adjustement of the saturation + /// - 'valueGain' The gain adjustement of the value + /// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the + /// following tuning parameters for each channel: + /// - 'threshold' The minimum required input value for the channel to be on (else + /// zero) + /// - 'gamma' The gamma-curve correction factor + /// - 'blacklevel' The lowest possible value (when the channel is black) + /// - 'whitelevel' The highest possible value (when the channel is white) "color" : { "hsv" : { - "saturationGain" : 1.0, - "valueGain" : 1.0 + "saturationGain" : 1.5, + "valueGain" : 1.5 }, "red" : { - "threshold" : 0.0, - "gamma" : 1.0, + "threshold" : 0.1, + "gamma" : 2.0, "blacklevel" : 0.0, "whitelevel" : 1.0 }, "green" : { - "threshold" : 0.0, - "gamma" : 1.0, + "threshold" : 0.1, + "gamma" : 2.0, "blacklevel" : 0.0, "whitelevel" : 1.0 }, "blue" : { - "threshold" : 0.0, - "gamma" : 1.0, + "threshold" : 0.1, + "gamma" : 2.0, "blacklevel" : 0.0, "whitelevel" : 1.0 } }, + + /// The configuration for each individual led. This contains the specification of the area + /// averaged of an input image for each led to determine its color. Each item in the list + /// contains the following fields: + /// * index: The index of the led. This determines its location in the string of leds; zero + /// being the first led. + /// * hscan: The fractional part of the image along the horizontal used for the averaging + /// (minimum and maximum inclusive) + /// * vscan: The fractional part of the image along the vertical used for the averaging + /// (minimum and maximum inclusive) "leds" : [ { @@ -78,7 +110,6 @@ "hscan" : { "minimum" : 5.88235, "maximum" : 11.7647 }, "vscan" : { "minimum" : 0, "maximum" : 10 } }, - // TOP-LEFT Corner { "index" : 8, "hscan" : { "minimum" : 0, "maximum" : 5.88235 }, @@ -124,7 +155,6 @@ "hscan" : { "minimum" : 0, "maximum" : 10 }, "vscan" : { "minimum" : 80, "maximum" : 90 } }, - // BOTTOM-LEFT Corner { "index" : 17, "hscan" : { "minimum" : 0, "maximum" : 5.88235 }, @@ -205,7 +235,6 @@ "hscan" : { "minimum" : 88.2353, "maximum" : 94.1176 }, "vscan" : { "minimum" : 90, "maximum" : 100 } }, - // BOTTOM-RIGHT Corner { "index" : 33, "hscan" : { "minimum" : 94.1176, "maximum" : 100 }, @@ -251,7 +280,6 @@ "hscan" : { "minimum" : 90, "maximum" : 100 }, "vscan" : { "minimum" : 10, "maximum" : 20 } }, - // TOP-RIGHT Corner { "index" : 42, "hscan" : { "minimum" : 94.1176, "maximum" : 100 }, @@ -294,40 +322,54 @@ } ], - // The XBMC video checker will connect to XBMC to check its player state and adjust the grabbing on it - "xbmcVideoChecker" : { - // Enable the use of the XBMC checker - "enable" : true, - - // Address of the hoxt running XBMC - "xbmcAddress" : "127.0.0.1", - - // Port used by XBMC for the TCP json service (Default disabled by XBMC for non-local clients) - "xbmcTcpPort" : 9090, - - // Grab screen when XBMC is playing video - "grabVideo" : true, - - // Grab screen when XBMC is playing pictures - "grabPictures" : true, - - // Grab screen when XBMC is playing audio - "grabAudio" : true, - - // Grab screen when XBMC is not playing anything (in menu) - "grabMenu" : true - }, - + /// The boot-sequence configuration, contains the following items: + /// * type : The type of the boot-sequence ('rainbow', 'knight_rider', 'none') + /// * duration_ms : The length of the boot-sequence [ms] "bootsequence" : { "type" : "rainbow", "duration_ms" : 3000 }, + /// The configuration for the frame-grabber, contains the following items: + /// * width : The width of the grabbed frames [pixels] + /// * height : The height of the grabbed frames [pixels] + /// * frequency_Hz : The frequency of the frame grab [Hz] "framegrabber" : { "width" : 64, "height" : 64, "frequency_Hz" : 10 + }, + + /// The configuration of the XBMC connection used to enable and disable the frame-grabber. + /// Contains the following fields: + /// * xbmcAddress : The IP address of the XBMC-host + /// * xbmcTcpPort : The TCP-port of the XBMC-server + /// * grabVideo : Flag indicating that the frame-grabber is on(true) during video playback + /// * grabPictures : Flag indicating that the frame-grabber is on(true) during picture show + /// * grabAudio : Flag indicating that the frame-grabber is on(true) during audio playback + /// * grabMenu : Flag indicating that the frame-grabber is on(true) in the XBMC menu + "xbmcVideoChecker" : { + "xbmcAddress" : "127.0.0.1", + "xbmcTcpPort" : 9090, + "grabVideo" : true, + "grabPictures" : true, + "grabAudio" : true, + "grabMenu" : false + }, + + /// The configuration of the Json server which enables the json remote interface + /// * port : Port at which the json server is started + "jsonServer" : + { + "port" : 19444 + }, + + /// The configuration of the Proto server which enables the protobuffer remote interface + /// * port : Port at which the protobuffer server is started + "protoServer" : + { + "port" : 19445 } } diff --git a/include/protoserver/ProtoServer.h b/include/protoserver/ProtoServer.h index 441a12cf..dae57481 100644 --- a/include/protoserver/ProtoServer.h +++ b/include/protoserver/ProtoServer.h @@ -27,7 +27,7 @@ public: /// @param hyperion Hyperion instance /// @param port port number on which to start listening for connections /// - ProtoServer(Hyperion * hyperion, uint16_t port = 19444); + ProtoServer(Hyperion * hyperion, uint16_t port = 19445); ~ProtoServer(); /// diff --git a/libsrc/hyperion/hyperion.schema.json b/libsrc/hyperion/hyperion.schema.json index f3923a90..7924961e 100644 --- a/libsrc/hyperion/hyperion.schema.json +++ b/libsrc/hyperion/hyperion.schema.json @@ -1,50 +1,47 @@ { - "type":"object", - "required":true, - "properties":{ - "device": { - "type":"object", - "required":true, - "properties":{ - "name": { - "type":"string", - "required":true + "type" : "object", + "required" : true, + "properties" : { + "device" : { + "type" : "object", + "required" : true, + "properties" : { + "name" : { + "type" : "string", + "required" : true }, - "type": { - "type":"string", - "required":true + "type" : { + "type" : "string", + "required" : true }, - "output": { - "type":"string", - "required":true + "output" : { + "type" : "string", + "required" : true }, - "interval": { - "type":"integer", - "required":true - }, - "rate": { - "type":"integer", - "required":true + "rate" : { + "type" : "integer", + "required" : true, + "minimum" : 0 } }, - "additionalProperties": false + "additionalProperties" : false }, "color": { "type":"object", - "required":true, + "required":false, "properties": { "hsv" : { "type" : "object", - "required" : true, + "required" : false, "properties" : { "saturationGain" : { "type" : "number", - "required" : true, + "required" : false, "minimum" : 0.0 }, "valueGain" : { "type" : "number", - "required" : true, + "required" : false, "minimum" : 0.0 } }, @@ -52,77 +49,81 @@ }, "red": { "type":"object", - "required":true, + "required":false, "properties":{ "gamma": { "type":"number", - "required":true + "required":false }, "blacklevel": { "type":"number", - "required":true + "required":false }, "whitelevel": { "type":"number", - "required":true + "required":false }, "threshold": { "type":"number", - "required":true, + "required":false, "minimum" : 0.0, "maximum" : 1.0 } - } + }, + "additionalProperties" : false }, "green": { "type":"object", - "required":true, + "required":false, "properties":{ "gamma": { "type":"number", - "required":true + "required":false }, "blacklevel": { "type":"number", - "required":true + "required":false }, "whitelevel": { "type":"number", - "required":true + "required":false }, "threshold": { "type":"number", - "required":true, + "required":false, "minimum" : 0.0, "maximum" : 1.0 } - } + }, + "additionalProperties" : false }, "blue": { "type":"object", - "required":true, + "required":false, "properties":{ "gamma": { "type":"number", - "required":true + "required":false }, "whitelevel": { "type":"number", - "required":true + "required":false }, "blacklevel": { "type":"number", - "required":true + "required":false }, "threshold": { "type":"number", - "required":true, + "required":false, "minimum" : 0.0, "maximum" : 1.0 } - } + }, + "additionalProperties" : false } - } + }, + "additionalProperties" : false }, "leds": { "type":"array", @@ -146,7 +147,8 @@ "type":"number", "required":true } - } + }, + "additionalProperties" : false }, "vscan": { "type":"object", @@ -160,20 +162,18 @@ "type":"number", "required":true } - } + }, + "additionalProperties" : false } - } + }, + "additionalProperties" : false } }, "xbmcVideoChecker" : { "type" : "object", - "required" : true, + "required" : false, "properties" : { - "enable" : { - "type" : "boolean", - "required" : true - }, "xbmcAddress" : { "type" : "string", "required" : true @@ -204,7 +204,7 @@ "bootsequence" : { "type" : "object", - "required" : true, + "required" : false, "properties" : { "type" : { "type" : "string", @@ -220,7 +220,7 @@ "framegrabber" : { "type" : "object", - "required" : true, + "required" : false, "properties" : { "width" : { "type" : "integer", @@ -236,6 +236,34 @@ } }, "additionalProperties" : false + }, + "jsonServer" : + { + "type" : "object", + "required" : false, + "properties" : { + "port" : { + "type" : "integer", + "required" : true, + "minimum" : 0, + "maximum" : 65535 + } + }, + "additionalProperties" : false + }, + "protoServer" : + { + "type" : "object", + "required" : false, + "properties" : { + "port" : { + "type" : "integer", + "required" : true, + "minimum" : 0, + "maximum" : 65535 + } + }, + "additionalProperties" : false } }, "additionalProperties" : false diff --git a/libsrc/utils/HsvTransform.cpp b/libsrc/utils/HsvTransform.cpp index 3b147662..14554fa9 100644 --- a/libsrc/utils/HsvTransform.cpp +++ b/libsrc/utils/HsvTransform.cpp @@ -45,8 +45,6 @@ void HsvTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) con uint8_t saturation, value; rgb2hsv(red, green, blue, hue, saturation, value); - std::cout << int(hue) << " " << int(saturation) << " " << int(value) << std::endl; - int s = saturation * _saturationGain; if (s > 255) saturation = 255; diff --git a/src/hyperiond/CMakeLists.txt b/src/hyperiond/CMakeLists.txt index 92f7d83b..01e3488a 100644 --- a/src/hyperiond/CMakeLists.txt +++ b/src/hyperiond/CMakeLists.txt @@ -7,4 +7,5 @@ target_link_libraries(hyperiond hyperion dispmanx-grabber xbmcvideochecker - jsonserver) + jsonserver + protoserver) diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index e21752bd..b2fcc185 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -23,6 +23,9 @@ // JsonServer includes #include +// ProtoServer includes +#include + void signal_handler(const int signum) { QCoreApplication::quit(); @@ -75,14 +78,20 @@ int main(int argc, char** argv) Hyperion hyperion(config); std::cout << "Hyperion created and initialised" << std::endl; - BootSequence * bootSequence = BootSequenceFactory::createBootSequence(&hyperion, config["bootsequence"]); - if (bootSequence) + // create boot sequence if the configuration is present + BootSequence * bootSequence = nullptr; + if (config.isMember("bootsequence")) { + bootSequence = BootSequenceFactory::createBootSequence(&hyperion, config["bootsequence"]); bootSequence->start(); } - const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"]; - XBMCVideoChecker xbmcVideoChecker( + // create XBMC video checker if the configuration is present + XBMCVideoChecker * xbmcVideoChecker = nullptr; + if (config.isMember("xbmcVideoChecker")) + { + const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"]; + xbmcVideoChecker = new XBMCVideoChecker( videoCheckerConfig["xbmcAddress"].asString(), videoCheckerConfig["xbmcTcpPort"].asUInt(), 1000, @@ -90,38 +99,67 @@ int main(int argc, char** argv) videoCheckerConfig["grabPictures"].asBool(), videoCheckerConfig["grabAudio"].asBool(), videoCheckerConfig["grabMenu"].asBool()); - if (videoCheckerConfig["enable"].asBool()) - { - xbmcVideoChecker.start(); + + xbmcVideoChecker->start(); std::cout << "XBMC video checker created and started" << std::endl; } - // Construct and start the frame-grabber - const Json::Value & frameGrabberConfig = config["framegrabber"]; - DispmanxWrapper dispmanx( + // Construct and start the frame-grabber if the configuration is present + DispmanxWrapper * dispmanx = nullptr; + if (config.isMember("framegrabber")) + { + const Json::Value & frameGrabberConfig = config["framegrabber"]; + dispmanx = new DispmanxWrapper( frameGrabberConfig["width"].asUInt(), frameGrabberConfig["height"].asUInt(), frameGrabberConfig["frequency_Hz"].asUInt(), &hyperion); - QObject::connect(&xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), &dispmanx, SLOT(setGrabbingMode(GrabbingMode))); - dispmanx.start(); - std::cout << "Frame grabber created and started" << std::endl; - JsonServer jsonServer(&hyperion); - std::cout << "Json server created and started on port " << jsonServer.getPort() << std::endl; + if (xbmcVideoChecker != nullptr) + { + QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode))); + } + else + { + dispmanx->setGrabbingMode(GRABBINGMODE_VIDEO); + } + + dispmanx->start(); + std::cout << "Frame grabber created and started" << std::endl; + } + + // Create Json server if configuration is present + JsonServer * jsonServer = nullptr; + if (config.isMember("jsonServer")) + { + const Json::Value & jsonServerConfig = config["jsonServer"]; + jsonServer = new JsonServer(&hyperion, jsonServerConfig["port"].asUInt()); + std::cout << "Json server created and started on port " << jsonServer->getPort() << std::endl; + } + + // Create Proto server if configuration is present + ProtoServer * protoServer = nullptr; + if (config.isMember("protoServer")) + { + const Json::Value & protoServerConfig = config["protoServer"]; + protoServer = new ProtoServer(&hyperion, protoServerConfig["port"].asUInt()); + std::cout << "Proto server created and started on port " << protoServer->getPort() << std::endl; + } // run the application int rc = app.exec(); std::cout << "Application closed" << std::endl; - // Stop the frame grabber - dispmanx.stop(); - - // Delete the boot sequence - delete bootSequence; - // Clear all colors (switchting off all leds) hyperion.clearall(); + // Delete all component + delete bootSequence; + delete dispmanx; + delete xbmcVideoChecker; + delete jsonServer; + delete protoServer; + + // leave application return rc; }