2013-08-13 20:10:19 +02:00
// stl includes
2014-01-28 00:39:04 +01:00
# include <clocale>
2013-08-11 21:49:11 +02:00
# include <initializer_list>
2016-08-06 08:28:42 +02:00
# include <limits>
2016-10-11 19:51:20 +02:00
# include <iostream>
2017-03-21 17:55:46 +01:00
# include <stdlib.h>
2013-08-11 21:49:11 +02:00
2013-08-13 20:10:19 +02:00
// Qt includes
2013-08-11 11:54:16 +02:00
# include <QCoreApplication>
2014-01-28 22:27:02 +01:00
# include <QLocale>
2013-08-11 11:54:16 +02:00
2013-08-13 20:10:19 +02:00
// hyperion-remote include
2013-08-17 11:54:16 +02:00
# include "JsonConnection.h"
2013-08-11 21:49:11 +02:00
2016-03-10 12:01:10 +01:00
# include "HyperionConfig.h"
2016-08-28 15:10:43 +02:00
# include <commandline/Parser.h>
2016-03-10 12:01:10 +01:00
2016-08-28 15:10:43 +02:00
using namespace commandline ;
2013-08-11 11:54:16 +02:00
2013-08-13 20:10:19 +02:00
/// Count the number of true values in a list of booleans
2013-08-11 21:49:11 +02:00
int count ( std : : initializer_list < bool > values )
{
2013-08-13 20:10:19 +02:00
int count = 0 ;
for ( bool value : values ) {
if ( value )
count + + ;
}
return count ;
2013-08-11 21:49:11 +02:00
}
2016-08-28 15:10:43 +02:00
void showHelp ( Option & option ) {
QString shortOption ;
2016-10-17 21:38:19 +02:00
QString longOption = QString ( " --%1 " ) . arg ( option . names ( ) . last ( ) ) ;
2016-08-28 15:10:43 +02:00
if ( option . names ( ) . size ( ) = = 2 ) {
shortOption = QString ( " -%1 " ) . arg ( option . names ( ) . first ( ) ) ;
}
qWarning ( ) < < qPrintable ( QString ( " \t %1 \t %2 \t %3 " ) . arg ( shortOption , longOption , option . description ( ) ) ) ;
}
2013-08-13 19:31:56 +02:00
int main ( int argc , char * argv [ ] )
2013-08-11 11:54:16 +02:00
{
2017-03-21 17:55:46 +01:00
setenv ( " AVAHI_COMPAT_NOWARN " , " 1 " , 1 ) ;
2016-03-10 12:01:10 +01:00
std : : cout
< < " hyperion-remote: " < < std : : endl
2016-06-24 23:22:31 +02:00
< < " \t Version : " < < HYPERION_VERSION < < " ( " < < HYPERION_BUILD_ID < < " ) " < < std : : endl
2016-03-10 12:01:10 +01:00
< < " \t build time: " < < __DATE__ < < " " < < __TIME__ < < std : : endl ;
2013-08-13 20:10:19 +02:00
QCoreApplication app ( argc , argv ) ;
2014-01-28 22:27:02 +01:00
// force the locale
setlocale ( LC_ALL , " C " ) ;
QLocale : : setDefault ( QLocale : : c ( ) ) ;
2013-08-13 20:10:19 +02:00
try
{
// create the option parser and initialize all parameters
2017-01-06 14:25:55 +01:00
Parser parser ( " Application to send a command to hyperion using the Json interface " ) ;
2013-08-13 20:10:19 +02:00
2016-10-24 23:52:53 +02:00
Option & argAddress = parser . add < Option > ( ' a ' , " address " , " Set the address of the hyperion server [default: %1] " , " localhost:19444 " ) ;
2017-01-17 21:53:35 +01:00
IntOption & argPriority = parser . add < IntOption > ( ' p ' , " priority " , " Use to the provided priority channel (suggested 2-99) [default: %1] " , " 50 " ) ;
2016-09-17 00:40:29 +02:00
IntOption & argDuration = parser . add < IntOption > ( ' d ' , " duration " , " Specify how long the leds should be switched on in milliseconds [default: infinity] " ) ;
ColorsOption & argColor = parser . add < ColorsOption > ( ' c ' , " color " , " Set all leds to a constant color (either RRGGBB hex getColors or a color name. The color may be repeated multiple time like: RRGGBBRRGGBB) " ) ;
ImageOption & argImage = parser . add < ImageOption > ( ' i ' , " image " , " Set the leds to the colors according to the given image file " ) ;
Option & argEffect = parser . add < Option > ( ' e ' , " effect " , " Enable the effect with the given name " ) ;
2016-10-24 23:52:53 +02:00
Option & argEffectFile = parser . add < Option > ( 0x0 , " effectFile " , " Arguments to use in combination with --createEffect " ) ;
2016-09-17 00:40:29 +02:00
Option & argEffectArgs = parser . add < Option > ( 0x0 , " effectArgs " , " Arguments to use in combination with the specified effect. Should be a Json object string. " , " " ) ;
2016-10-24 23:52:53 +02:00
Option & argCreateEffect = parser . add < Option > ( 0x0 , " createEffect " , " Write a new Json Effect configuration file. \n First parameter = Effect name. \n Second parameter = Effect file (--effectFile). \n Last parameter = Effect arguments (--effectArgs.) " , " " ) ;
2016-11-18 18:39:21 +01:00
Option & argDeleteEffect = parser . add < Option > ( 0x0 , " deleteEffect " , " Delete a custom created Json Effect configuration file. " ) ;
2016-09-17 00:40:29 +02:00
BooleanOption & argServerInfo = parser . add < BooleanOption > ( ' l ' , " list " , " List server info and active effects with priority and duration " ) ;
2017-03-04 22:17:42 +01:00
BooleanOption & argSysInfo = parser . add < BooleanOption > ( ' s ' , " sysinfo " , " show system info " ) ;
2016-09-17 00:40:29 +02:00
BooleanOption & argClear = parser . add < BooleanOption > ( ' x ' , " clear " , " Clear data for the priority channel provided by the -p option " ) ;
BooleanOption & argClearAll = parser . add < BooleanOption > ( 0x0 , " clearall " , " Clear data for all active priority channels " ) ;
2017-11-22 00:52:55 +01:00
Option & argEnableComponent = parser . add < Option > ( ' E ' , " enable " , " Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER, V4L, LEDDEVICE] " ) ;
Option & argDisableComponent = parser . add < Option > ( ' D ' , " disable " , " Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER, V4L, LEDDEVICE] " ) ;
2017-04-03 05:19:05 +02:00
Option & argId = parser . add < Option > ( ' q ' , " qualifier " , " Identifier(qualifier) of the adjustment to set " ) ;
IntOption & argBrightness = parser . add < IntOption > ( ' L ' , " brightness " , " Set the brightness gain of the leds " ) ;
IntOption & argBrightnessC = parser . add < IntOption > ( 0x0 , " brightnessCompensation " , " Set the brightness compensation " ) ;
IntOption & argBacklightThreshold = parser . add < IntOption > ( ' n ' , " backlightThreshold " , " threshold for activating backlight (minimum brightness) " ) ;
2017-02-11 22:52:47 +01:00
IntOption & argBacklightColored = parser . add < IntOption > ( 0x0 , " backlightColored " , " 0 = white backlight; 1 = colored backlight " ) ;
2017-01-06 14:25:55 +01:00
DoubleOption & argGamma = parser . add < DoubleOption > ( ' g ' , " gamma " , " Set the overall gamma of the leds " ) ;
2016-08-28 15:10:43 +02:00
BooleanOption & argPrint = parser . add < BooleanOption > ( 0x0 , " print " , " Print the json input and output messages on stdout " ) ;
BooleanOption & argHelp = parser . add < BooleanOption > ( ' h ' , " help " , " Show this help message and exit " ) ;
2016-09-17 00:40:29 +02:00
ColorOption & argRAdjust = parser . add < ColorOption > ( ' R ' , " redAdjustment " , " Set the adjustment of the red color (requires colors in hex format as RRGGBB) " ) ;
ColorOption & argGAdjust = parser . add < ColorOption > ( ' G ' , " greenAdjustment " , " Set the adjustment of the green color (requires colors in hex format as RRGGBB) " ) ;
ColorOption & argBAdjust = parser . add < ColorOption > ( ' B ' , " blueAdjustment " , " Set the adjustment of the blue color (requires colors in hex format as RRGGBB) " ) ;
2017-01-06 14:25:55 +01:00
ColorOption & argCAdjust = parser . add < ColorOption > ( ' C ' , " cyanAdjustment " , " Set the adjustment of the cyan color (requires colors in hex format as RRGGBB) " ) ;
ColorOption & argMAdjust = parser . add < ColorOption > ( ' M ' , " magentaAdjustment " , " Set the adjustment of the magenta color (requires colors in hex format as RRGGBB) " ) ;
ColorOption & argYAdjust = parser . add < ColorOption > ( ' Y ' , " yellowAdjustment " , " Set the adjustment of the yellow color (requires colors in hex format as RRGGBB) " ) ;
ColorOption & argWAdjust = parser . add < ColorOption > ( ' W ' , " whiteAdjustment " , " Set the adjustment of the white color (requires colors in hex format as RRGGBB) " ) ;
ColorOption & argbAdjust = parser . add < ColorOption > ( ' b ' , " blackAdjustment " , " Set the adjustment of the black color (requires colors in hex format as RRGGBB) " ) ;
2017-02-08 14:36:28 +01:00
Option & argMapping = parser . add < Option > ( ' m ' , " ledMapping " , " Set the methode for image to led mapping valid values: multicolor_mean, unicolor_mean " ) ;
2017-09-03 13:48:16 +02:00
Option & argVideoMode = parser . add < Option > ( ' V ' , " videoMode " , " Set the video mode valid values: 2D, 3DSBS, 3DTAB " ) ;
2016-09-17 00:40:29 +02:00
IntOption & argSource = parser . add < IntOption > ( 0x0 , " sourceSelect " , " Set current active priority channel and deactivate auto source switching " ) ;
BooleanOption & argSourceAuto = parser . add < BooleanOption > ( 0x0 , " sourceAutoSelect " , " Enables auto source, if disabled prio by manual selecting input source " ) ;
2017-03-23 17:11:07 +01:00
BooleanOption & argOff = parser . add < BooleanOption > ( 0x0 , " off " , " deactivates hyperion " ) ;
BooleanOption & argOn = parser . add < BooleanOption > ( 0x0 , " on " , " activates hyperion " ) ;
2016-09-17 00:40:29 +02:00
BooleanOption & argConfigGet = parser . add < BooleanOption > ( 0x0 , " configGet " , " Print the current loaded Hyperion configuration file " ) ;
2016-10-09 22:22:17 +02:00
BooleanOption & argSchemaGet = parser . add < BooleanOption > ( 0x0 , " schemaGet " , " Print the json schema for Hyperion configuration " ) ;
2017-01-06 14:25:55 +01:00
Option & argConfigSet = parser . add < Option > ( 0x0 , " configSet " , " Write to the actual loaded configuration file. Should be a Json object string. " ) ;
2013-08-13 20:10:19 +02:00
2016-08-28 15:10:43 +02:00
// parse all _options
2016-10-24 23:52:53 +02:00
parser . process ( app ) ;
2013-08-13 20:10:19 +02:00
// check if we need to display the usage. exit if we do.
2016-08-28 15:10:43 +02:00
if ( parser . isSet ( argHelp ) )
2013-08-13 20:10:19 +02:00
{
2016-10-24 23:52:53 +02:00
parser . showHelp ( 0 ) ;
2013-08-13 20:10:19 +02:00
}
// check if at least one of the available color transforms is set
2017-01-06 14:25:55 +01:00
bool colorAdjust = parser . isSet ( argRAdjust ) | | parser . isSet ( argGAdjust ) | | parser . isSet ( argBAdjust ) | | parser . isSet ( argCAdjust ) | | parser . isSet ( argMAdjust )
2017-04-03 05:19:05 +02:00
| | parser . isSet ( argYAdjust ) | | parser . isSet ( argWAdjust ) | | parser . isSet ( argbAdjust ) | | parser . isSet ( argGamma ) | | parser . isSet ( argBrightness ) | | parser . isSet ( argBrightnessC )
2017-02-11 22:52:47 +01:00
| | parser . isSet ( argBacklightThreshold ) | | parser . isSet ( argBacklightColored ) ;
2017-11-22 00:52:55 +01:00
2013-08-13 20:10:19 +02:00
// check that exactly one command was given
2017-11-22 00:52:55 +01:00
int commandCount = count ( { parser . isSet ( argColor ) , parser . isSet ( argImage ) , parser . isSet ( argEffect ) , parser . isSet ( argCreateEffect ) , parser . isSet ( argDeleteEffect ) ,
2017-03-04 22:17:42 +01:00
parser . isSet ( argServerInfo ) , parser . isSet ( argSysInfo ) , parser . isSet ( argClear ) , parser . isSet ( argClearAll ) , parser . isSet ( argEnableComponent ) , parser . isSet ( argDisableComponent ) , colorAdjust ,
2017-03-23 17:11:07 +01:00
parser . isSet ( argSource ) , parser . isSet ( argSourceAuto ) , parser . isSet ( argOff ) , parser . isSet ( argOn ) , parser . isSet ( argConfigGet ) , parser . isSet ( argSchemaGet ) , parser . isSet ( argConfigSet ) ,
2017-08-04 23:08:15 +02:00
parser . isSet ( argMapping ) , parser . isSet ( argVideoMode ) } ) ;
2013-08-13 20:10:19 +02:00
if ( commandCount ! = 1 )
{
2016-08-28 15:10:43 +02:00
qWarning ( ) < < ( commandCount = = 0 ? " No command found. " : " Multiple commands found. " ) < < " Provide exactly one of the following options: " ;
showHelp ( argColor ) ;
showHelp ( argImage ) ;
2016-10-24 23:52:53 +02:00
showHelp ( argEffect ) ;
showHelp ( argCreateEffect ) ;
2016-11-18 18:39:21 +01:00
showHelp ( argDeleteEffect ) ;
2016-08-28 15:10:43 +02:00
showHelp ( argServerInfo ) ;
2017-03-04 22:17:42 +01:00
showHelp ( argSysInfo ) ;
2016-08-28 15:10:43 +02:00
showHelp ( argClear ) ;
showHelp ( argClearAll ) ;
showHelp ( argEnableComponent ) ;
showHelp ( argDisableComponent ) ;
showHelp ( argSource ) ;
showHelp ( argSourceAuto ) ;
showHelp ( argConfigGet ) ;
2017-09-03 13:48:16 +02:00
showHelp ( argVideoMode ) ;
2016-08-28 15:10:43 +02:00
qWarning ( ) < < " or one or more of the available color modding operations: " ;
showHelp ( argId ) ;
2017-01-06 14:25:55 +01:00
showHelp ( argBrightness ) ;
2017-04-03 05:19:05 +02:00
showHelp ( argBrightnessC ) ;
2017-02-11 22:52:47 +01:00
showHelp ( argBacklightThreshold ) ;
showHelp ( argBacklightColored ) ;
2016-08-28 15:10:43 +02:00
showHelp ( argGamma ) ;
showHelp ( argRAdjust ) ;
showHelp ( argGAdjust ) ;
showHelp ( argBAdjust ) ;
2017-01-06 14:25:55 +01:00
showHelp ( argCAdjust ) ;
showHelp ( argMAdjust ) ;
showHelp ( argYAdjust ) ;
2013-08-13 20:10:19 +02:00
return 1 ;
}
// create the connection to the hyperion server
2016-08-28 15:10:43 +02:00
JsonConnection connection ( argAddress . value ( parser ) , parser . isSet ( argPrint ) ) ;
2013-08-13 20:10:19 +02:00
// now execute the given command
2016-08-28 15:10:43 +02:00
if ( parser . isSet ( argColor ) )
{
2017-01-06 14:25:55 +01:00
// TODO: make sure setColor accepts a QList<QColor>
2016-08-28 15:10:43 +02:00
connection . setColor ( argColor . getColors ( parser ) . toVector ( ) . toStdVector ( ) , argPriority . getInt ( parser ) , argDuration . getInt ( parser ) ) ;
}
else if ( parser . isSet ( argImage ) )
2013-08-13 20:10:19 +02:00
{
2016-08-28 15:10:43 +02:00
connection . setImage ( argImage . getImage ( parser ) , argPriority . getInt ( parser ) , argDuration . getInt ( parser ) ) ;
2013-08-13 20:10:19 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argEffect ) )
2013-08-13 20:10:19 +02:00
{
2016-08-28 15:10:43 +02:00
connection . setEffect ( argEffect . value ( parser ) , argEffectArgs . value ( parser ) , argPriority . getInt ( parser ) , argDuration . getInt ( parser ) ) ;
2013-08-13 20:10:19 +02:00
}
2016-10-24 23:52:53 +02:00
else if ( parser . isSet ( argCreateEffect ) )
{
connection . createEffect ( argCreateEffect . value ( parser ) , argEffectFile . value ( parser ) , argEffectArgs . value ( parser ) ) ;
}
2016-11-18 18:39:21 +01:00
else if ( parser . isSet ( argDeleteEffect ) )
{
connection . deleteEffect ( argDeleteEffect . value ( parser ) ) ;
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argServerInfo ) )
2013-08-13 20:10:19 +02:00
{
2017-03-04 22:17:42 +01:00
std : : cout < < " Server info: \n " < < connection . getServerInfo ( ) . toStdString ( ) < < std : : endl ;
}
else if ( parser . isSet ( argSysInfo ) )
{
std : : cout < < " System info: \n " < < connection . getSysInfo ( ) . toStdString ( ) < < std : : endl ;
2013-08-13 20:10:19 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argClear ) )
2013-08-13 20:10:19 +02:00
{
2016-08-28 15:10:43 +02:00
connection . clear ( argPriority . getInt ( parser ) ) ;
2013-08-13 20:10:19 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argClearAll ) )
2013-08-13 20:10:19 +02:00
{
connection . clearAll ( ) ;
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argEnableComponent ) )
2016-08-04 13:10:53 +02:00
{
2016-08-28 15:10:43 +02:00
connection . setComponentState ( argEnableComponent . value ( parser ) , true ) ;
2016-08-04 13:10:53 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argDisableComponent ) )
2016-08-04 13:10:53 +02:00
{
2016-08-28 15:10:43 +02:00
connection . setComponentState ( argDisableComponent . value ( parser ) , false ) ;
2016-08-04 13:10:53 +02:00
}
2017-03-23 17:11:07 +01:00
else if ( parser . isSet ( argOn ) )
2016-08-06 08:28:42 +02:00
{
2017-03-23 17:11:07 +01:00
connection . setComponentState ( " ALL " , true ) ;
}
else if ( parser . isSet ( argOff ) )
{
connection . setComponentState ( " ALL " , false ) ;
2016-08-06 08:28:42 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argSource ) )
2016-07-31 22:21:35 +02:00
{
2016-08-28 15:10:43 +02:00
connection . setSource ( argSource . getInt ( parser ) ) ;
2016-07-31 22:21:35 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argSourceAuto ) )
2016-07-31 22:21:35 +02:00
{
connection . setSourceAutoSelect ( ) ;
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argConfigGet ) )
2016-08-03 22:03:19 +02:00
{
2016-08-15 22:32:01 +02:00
QString info = connection . getConfig ( " config " ) ;
std : : cout < < " Configuration: \n " < < info . toStdString ( ) < < std : : endl ;
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argSchemaGet ) )
2016-08-15 22:32:01 +02:00
{
QString info = connection . getConfig ( " schema " ) ;
std : : cout < < " Configuration Schema \n " < < info . toStdString ( ) < < std : : endl ;
2016-08-03 22:03:19 +02:00
}
2016-08-28 15:10:43 +02:00
else if ( parser . isSet ( argConfigSet ) )
2016-08-14 20:17:12 +02:00
{
2016-10-09 22:22:17 +02:00
connection . setConfig ( argConfigSet . value ( parser ) ) ;
2016-08-14 20:17:12 +02:00
}
2016-12-19 23:59:50 +01:00
else if ( parser . isSet ( argMapping ) )
{
connection . setLedMapping ( argMapping . value ( parser ) ) ;
}
2017-08-04 23:08:15 +02:00
else if ( parser . isSet ( argVideoMode ) )
{
connection . setVideoMode ( argVideoMode . value ( parser ) ) ;
}
2017-01-06 14:25:55 +01:00
else if ( colorAdjust )
{
connection . setAdjustment (
argId . value ( parser ) ,
argRAdjust . getColor ( parser ) ,
argGAdjust . getColor ( parser ) ,
argBAdjust . getColor ( parser ) ,
argCAdjust . getColor ( parser ) ,
argMAdjust . getColor ( parser ) ,
argYAdjust . getColor ( parser ) ,
argWAdjust . getColor ( parser ) ,
argbAdjust . getColor ( parser ) ,
argGamma . getDoublePtr ( parser ) ,
argGamma . getDoublePtr ( parser ) ,
argGamma . getDoublePtr ( parser ) ,
2017-04-03 05:19:05 +02:00
argBacklightThreshold . getIntPtr ( parser ) ,
2017-02-11 22:52:47 +01:00
argBacklightColored . getIntPtr ( parser ) ,
2017-04-03 05:19:05 +02:00
argBrightness . getIntPtr ( parser ) ,
argBrightnessC . getIntPtr ( parser )
2017-01-06 14:25:55 +01:00
) ;
2016-03-11 12:20:59 +01:00
}
2013-08-13 20:10:19 +02:00
}
catch ( const std : : runtime_error & e )
{
// An error occured. Display error and quit
std : : cerr < < e . what ( ) < < std : : endl ;
return 1 ;
}
return 0 ;
2013-08-11 11:54:16 +02:00
}