Added ProtoServer to the Hyperion server;

Updated the configuration file and schema to be more flexible;


Former-commit-id: 0f670ae6f9512abedf279fe0b014802e31f2f16f
This commit is contained in:
johan 2013-10-13 14:48:59 +02:00
parent 2a55e1b23c
commit 6db1db3129
6 changed files with 227 additions and 120 deletions

View File

@ -1,41 +1,73 @@
// Hyperion configuration // 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" : "device" :
{ {
"name" : "MyPi", "name" : "MyPi",
"type" : "ws2801", "type" : "ws2801",
"output" : "/dev/spidev0.0", "output" : "/dev/spidev0.0",
"interval" : 20000, "rate" : 1000000
"rate" : 48000
}, },
/// 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" : "color" :
{ {
"hsv" : { "hsv" : {
"saturationGain" : 1.0, "saturationGain" : 1.5,
"valueGain" : 1.0 "valueGain" : 1.5
}, },
"red" : "red" :
{ {
"threshold" : 0.0, "threshold" : 0.1,
"gamma" : 1.0, "gamma" : 2.0,
"blacklevel" : 0.0, "blacklevel" : 0.0,
"whitelevel" : 1.0 "whitelevel" : 1.0
}, },
"green" : "green" :
{ {
"threshold" : 0.0, "threshold" : 0.1,
"gamma" : 1.0, "gamma" : 2.0,
"blacklevel" : 0.0, "blacklevel" : 0.0,
"whitelevel" : 1.0 "whitelevel" : 1.0
}, },
"blue" : "blue" :
{ {
"threshold" : 0.0, "threshold" : 0.1,
"gamma" : 1.0, "gamma" : 2.0,
"blacklevel" : 0.0, "blacklevel" : 0.0,
"whitelevel" : 1.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" : "leds" :
[ [
{ {
@ -78,7 +110,6 @@
"hscan" : { "minimum" : 5.88235, "maximum" : 11.7647 }, "hscan" : { "minimum" : 5.88235, "maximum" : 11.7647 },
"vscan" : { "minimum" : 0, "maximum" : 10 } "vscan" : { "minimum" : 0, "maximum" : 10 }
}, },
// TOP-LEFT Corner
{ {
"index" : 8, "index" : 8,
"hscan" : { "minimum" : 0, "maximum" : 5.88235 }, "hscan" : { "minimum" : 0, "maximum" : 5.88235 },
@ -124,7 +155,6 @@
"hscan" : { "minimum" : 0, "maximum" : 10 }, "hscan" : { "minimum" : 0, "maximum" : 10 },
"vscan" : { "minimum" : 80, "maximum" : 90 } "vscan" : { "minimum" : 80, "maximum" : 90 }
}, },
// BOTTOM-LEFT Corner
{ {
"index" : 17, "index" : 17,
"hscan" : { "minimum" : 0, "maximum" : 5.88235 }, "hscan" : { "minimum" : 0, "maximum" : 5.88235 },
@ -205,7 +235,6 @@
"hscan" : { "minimum" : 88.2353, "maximum" : 94.1176 }, "hscan" : { "minimum" : 88.2353, "maximum" : 94.1176 },
"vscan" : { "minimum" : 90, "maximum" : 100 } "vscan" : { "minimum" : 90, "maximum" : 100 }
}, },
// BOTTOM-RIGHT Corner
{ {
"index" : 33, "index" : 33,
"hscan" : { "minimum" : 94.1176, "maximum" : 100 }, "hscan" : { "minimum" : 94.1176, "maximum" : 100 },
@ -251,7 +280,6 @@
"hscan" : { "minimum" : 90, "maximum" : 100 }, "hscan" : { "minimum" : 90, "maximum" : 100 },
"vscan" : { "minimum" : 10, "maximum" : 20 } "vscan" : { "minimum" : 10, "maximum" : 20 }
}, },
// TOP-RIGHT Corner
{ {
"index" : 42, "index" : 42,
"hscan" : { "minimum" : 94.1176, "maximum" : 100 }, "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 /// The boot-sequence configuration, contains the following items:
"xbmcVideoChecker" : { /// * type : The type of the boot-sequence ('rainbow', 'knight_rider', 'none')
// Enable the use of the XBMC checker /// * duration_ms : The length of the boot-sequence [ms]
"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
},
"bootsequence" : "bootsequence" :
{ {
"type" : "rainbow", "type" : "rainbow",
"duration_ms" : 3000 "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" : "framegrabber" :
{ {
"width" : 64, "width" : 64,
"height" : 64, "height" : 64,
"frequency_Hz" : 10 "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
} }
} }

View File

@ -27,7 +27,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
/// ///
ProtoServer(Hyperion * hyperion, uint16_t port = 19444); ProtoServer(Hyperion * hyperion, uint16_t port = 19445);
~ProtoServer(); ~ProtoServer();
/// ///

View File

@ -1,50 +1,47 @@
{ {
"type":"object", "type" : "object",
"required":true, "required" : true,
"properties":{ "properties" : {
"device": { "device" : {
"type":"object", "type" : "object",
"required":true, "required" : true,
"properties":{ "properties" : {
"name": { "name" : {
"type":"string", "type" : "string",
"required":true "required" : true
}, },
"type": { "type" : {
"type":"string", "type" : "string",
"required":true "required" : true
}, },
"output": { "output" : {
"type":"string", "type" : "string",
"required":true "required" : true
}, },
"interval": { "rate" : {
"type":"integer", "type" : "integer",
"required":true "required" : true,
}, "minimum" : 0
"rate": {
"type":"integer",
"required":true
} }
}, },
"additionalProperties": false "additionalProperties" : false
}, },
"color": { "color": {
"type":"object", "type":"object",
"required":true, "required":false,
"properties": { "properties": {
"hsv" : { "hsv" : {
"type" : "object", "type" : "object",
"required" : true, "required" : false,
"properties" : { "properties" : {
"saturationGain" : { "saturationGain" : {
"type" : "number", "type" : "number",
"required" : true, "required" : false,
"minimum" : 0.0 "minimum" : 0.0
}, },
"valueGain" : { "valueGain" : {
"type" : "number", "type" : "number",
"required" : true, "required" : false,
"minimum" : 0.0 "minimum" : 0.0
} }
}, },
@ -52,77 +49,81 @@
}, },
"red": { "red": {
"type":"object", "type":"object",
"required":true, "required":false,
"properties":{ "properties":{
"gamma": { "gamma": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"blacklevel": { "blacklevel": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"whitelevel": { "whitelevel": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"threshold": { "threshold": {
"type":"number", "type":"number",
"required":true, "required":false,
"minimum" : 0.0, "minimum" : 0.0,
"maximum" : 1.0 "maximum" : 1.0
} }
} },
"additionalProperties" : false
}, },
"green": { "green": {
"type":"object", "type":"object",
"required":true, "required":false,
"properties":{ "properties":{
"gamma": { "gamma": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"blacklevel": { "blacklevel": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"whitelevel": { "whitelevel": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"threshold": { "threshold": {
"type":"number", "type":"number",
"required":true, "required":false,
"minimum" : 0.0, "minimum" : 0.0,
"maximum" : 1.0 "maximum" : 1.0
} }
} },
"additionalProperties" : false
}, },
"blue": { "blue": {
"type":"object", "type":"object",
"required":true, "required":false,
"properties":{ "properties":{
"gamma": { "gamma": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"whitelevel": { "whitelevel": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"blacklevel": { "blacklevel": {
"type":"number", "type":"number",
"required":true "required":false
}, },
"threshold": { "threshold": {
"type":"number", "type":"number",
"required":true, "required":false,
"minimum" : 0.0, "minimum" : 0.0,
"maximum" : 1.0 "maximum" : 1.0
} }
} },
"additionalProperties" : false
} }
} },
"additionalProperties" : false
}, },
"leds": { "leds": {
"type":"array", "type":"array",
@ -146,7 +147,8 @@
"type":"number", "type":"number",
"required":true "required":true
} }
} },
"additionalProperties" : false
}, },
"vscan": { "vscan": {
"type":"object", "type":"object",
@ -160,20 +162,18 @@
"type":"number", "type":"number",
"required":true "required":true
} }
} },
"additionalProperties" : false
} }
} },
"additionalProperties" : false
} }
}, },
"xbmcVideoChecker" : "xbmcVideoChecker" :
{ {
"type" : "object", "type" : "object",
"required" : true, "required" : false,
"properties" : { "properties" : {
"enable" : {
"type" : "boolean",
"required" : true
},
"xbmcAddress" : { "xbmcAddress" : {
"type" : "string", "type" : "string",
"required" : true "required" : true
@ -204,7 +204,7 @@
"bootsequence" : "bootsequence" :
{ {
"type" : "object", "type" : "object",
"required" : true, "required" : false,
"properties" : { "properties" : {
"type" : { "type" : {
"type" : "string", "type" : "string",
@ -220,7 +220,7 @@
"framegrabber" : "framegrabber" :
{ {
"type" : "object", "type" : "object",
"required" : true, "required" : false,
"properties" : { "properties" : {
"width" : { "width" : {
"type" : "integer", "type" : "integer",
@ -236,6 +236,34 @@
} }
}, },
"additionalProperties" : false "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 "additionalProperties" : false

View File

@ -45,8 +45,6 @@ void HsvTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) con
uint8_t saturation, value; uint8_t saturation, value;
rgb2hsv(red, green, blue, hue, saturation, value); rgb2hsv(red, green, blue, hue, saturation, value);
std::cout << int(hue) << " " << int(saturation) << " " << int(value) << std::endl;
int s = saturation * _saturationGain; int s = saturation * _saturationGain;
if (s > 255) if (s > 255)
saturation = 255; saturation = 255;

View File

@ -7,4 +7,5 @@ target_link_libraries(hyperiond
hyperion hyperion
dispmanx-grabber dispmanx-grabber
xbmcvideochecker xbmcvideochecker
jsonserver) jsonserver
protoserver)

View File

@ -23,6 +23,9 @@
// JsonServer includes // JsonServer includes
#include <jsonserver/JsonServer.h> #include <jsonserver/JsonServer.h>
// ProtoServer includes
#include <protoserver/ProtoServer.h>
void signal_handler(const int signum) void signal_handler(const int signum)
{ {
QCoreApplication::quit(); QCoreApplication::quit();
@ -75,14 +78,20 @@ int main(int argc, char** argv)
Hyperion hyperion(config); Hyperion hyperion(config);
std::cout << "Hyperion created and initialised" << std::endl; std::cout << "Hyperion created and initialised" << std::endl;
BootSequence * bootSequence = BootSequenceFactory::createBootSequence(&hyperion, config["bootsequence"]); // create boot sequence if the configuration is present
if (bootSequence) BootSequence * bootSequence = nullptr;
if (config.isMember("bootsequence"))
{ {
bootSequence = BootSequenceFactory::createBootSequence(&hyperion, config["bootsequence"]);
bootSequence->start(); bootSequence->start();
} }
const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"]; // create XBMC video checker if the configuration is present
XBMCVideoChecker xbmcVideoChecker( XBMCVideoChecker * xbmcVideoChecker = nullptr;
if (config.isMember("xbmcVideoChecker"))
{
const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"];
xbmcVideoChecker = new XBMCVideoChecker(
videoCheckerConfig["xbmcAddress"].asString(), videoCheckerConfig["xbmcAddress"].asString(),
videoCheckerConfig["xbmcTcpPort"].asUInt(), videoCheckerConfig["xbmcTcpPort"].asUInt(),
1000, 1000,
@ -90,38 +99,67 @@ int main(int argc, char** argv)
videoCheckerConfig["grabPictures"].asBool(), videoCheckerConfig["grabPictures"].asBool(),
videoCheckerConfig["grabAudio"].asBool(), videoCheckerConfig["grabAudio"].asBool(),
videoCheckerConfig["grabMenu"].asBool()); videoCheckerConfig["grabMenu"].asBool());
if (videoCheckerConfig["enable"].asBool())
{ xbmcVideoChecker->start();
xbmcVideoChecker.start();
std::cout << "XBMC video checker created and started" << std::endl; std::cout << "XBMC video checker created and started" << std::endl;
} }
// Construct and start the frame-grabber // Construct and start the frame-grabber if the configuration is present
const Json::Value & frameGrabberConfig = config["framegrabber"]; DispmanxWrapper * dispmanx = nullptr;
DispmanxWrapper dispmanx( if (config.isMember("framegrabber"))
{
const Json::Value & frameGrabberConfig = config["framegrabber"];
dispmanx = new DispmanxWrapper(
frameGrabberConfig["width"].asUInt(), frameGrabberConfig["width"].asUInt(),
frameGrabberConfig["height"].asUInt(), frameGrabberConfig["height"].asUInt(),
frameGrabberConfig["frequency_Hz"].asUInt(), frameGrabberConfig["frequency_Hz"].asUInt(),
&hyperion); &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); if (xbmcVideoChecker != nullptr)
std::cout << "Json server created and started on port " << jsonServer.getPort() << std::endl; {
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 // run the application
int rc = app.exec(); int rc = app.exec();
std::cout << "Application closed" << std::endl; 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) // Clear all colors (switchting off all leds)
hyperion.clearall(); hyperion.clearall();
// Delete all component
delete bootSequence;
delete dispmanx;
delete xbmcVideoChecker;
delete jsonServer;
delete protoServer;
// leave application
return rc; return rc;
} }