98_Hyperion.pm 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716
  1. #####################################################################################
  2. # $Id: 98_Hyperion.pm 13366 2017-02-08 21:20:47Z DeeSPe $
  3. #
  4. # Usage
  5. #
  6. # define <name> Hyperion <IP or HOSTNAME> <PORT> <INTERVAL>
  7. #
  8. #####################################################################################
  9. package main;
  10. use strict;
  11. use warnings;
  12. use Color;
  13. use DevIo;
  14. use JSON;
  15. use SetExtensions;
  16. my %Hyperion_sets =
  17. (
  18. "addEffect" => "textField",
  19. "dim" => "slider,0,1,100",
  20. "dimDown" => "textField",
  21. "dimUp" => "textField",
  22. "clear" => "textField",
  23. "clearall" => "noArg",
  24. "mode" => "clearall,effect,off,rgb",
  25. "off" => "noArg",
  26. "on" => "noArg",
  27. "rgb" => "colorpicker,RGB",
  28. "toggle" => "noArg",
  29. "toggleMode" => "noArg",
  30. "valueGainDown" => "textField",
  31. "valueGainUp" => "textField"
  32. );
  33. my $Hyperion_requiredVersion = "1.03.2";
  34. my $Hyperion_serverinfo = {"command" => "serverinfo"};
  35. my $Hyperion_webCmd = "rgb:effect:mode:dimDown:dimUp:on:off";
  36. my $Hyperion_webCmd_config = "rgb:effect:configFile:mode:dimDown:dimUp:on:off";
  37. my $Hyperion_homebridgeMapping = "On=state,subtype=TV.Licht,valueOn=/rgb.*/,cmdOff=off,cmdOn=mode+rgb ".
  38. "On=state,subtype=Umgebungslicht,valueOn=clearall,cmdOff=off,cmdOn=clearall ".
  39. "On=state,subtype=Effekt,valueOn=/effect.*/,cmdOff=off,cmdOn=mode+effect ";
  40. # "On=state,subtype=Knight.Rider,valueOn=/.*Knight_rider/,cmdOff=off,cmdOn=effect+Knight_rider " .
  41. # "On=configFile,subtype=Eingang.HDMI,valueOn=hyperion-hdmi,cmdOff=configFile+hyperion,cmdOn=configFile+hyperion-hdmi ";
  42. sub Hyperion_Initialize($)
  43. {
  44. my ($hash) = @_;
  45. $hash->{AttrFn} = "Hyperion_Attr";
  46. $hash->{DefFn} = "Hyperion_Define";
  47. $hash->{GetFn} = "Hyperion_Get";
  48. $hash->{NotifyFn} = "Hyperion_Notify";
  49. $hash->{ReadFn} = "Hyperion_Read";
  50. $hash->{SetFn} = "Hyperion_Set";
  51. $hash->{UndefFn} = "Hyperion_Undef";
  52. $hash->{AttrList} = "disable:1,0 ".
  53. "hyperionBin ".
  54. "hyperionConfigDir ".
  55. "hyperionCustomEffects:textField-long ".
  56. "hyperionDefaultDuration ".
  57. "hyperionDefaultPriority ".
  58. "hyperionDimStep ".
  59. "hyperionGainStep ".
  60. "hyperionNoSudo:1 ".
  61. "hyperionSshUser ".
  62. "hyperionToggleModes ".
  63. "hyperionVersionCheck:0 ".
  64. "queryAfterSet:0 ".
  65. $readingFnAttributes;
  66. FHEM_colorpickerInit();
  67. }
  68. sub Hyperion_Define($$)
  69. {
  70. my ($hash,$def) = @_;
  71. my @args = split("[ \t]+",$def);
  72. return "Usage: define <name> Hyperion <IP> <PORT> [<INTERVAL>]"
  73. if (@args < 4);
  74. my ($name,$type,$host,$port,$interval) = @args;
  75. if ($interval)
  76. {
  77. $hash->{INTERVAL} = $interval;
  78. }
  79. else
  80. {
  81. delete $hash->{INTERVAL};
  82. }
  83. $hash->{IP} = $host;
  84. $hash->{PORT} = $port;
  85. $hash->{DeviceName} = "$host:$port";
  86. $interval = undef unless defined $interval;
  87. $interval = 5 if ($interval && $interval < 5);
  88. RemoveInternalTimer($hash);
  89. Hyperion_OpenDev($hash);
  90. if ($init_done && !defined $hash->{OLDDEF})
  91. {
  92. $attr{$name}{alias} = "Ambilight";
  93. $attr{$name}{cmdIcon} = "on:general_an off:general_aus dimDown:dimdown dimUp:dimup";
  94. $attr{$name}{"event-on-change-reading"} = ".*";
  95. $attr{$name}{"event-on-update-reading"} = "serverResponse";
  96. $attr{$name}{devStateIcon} = '{(Hyperion_devStateIcon($name),"toggle")}';
  97. $attr{$name}{group} = "colordimmer";
  98. $attr{$name}{homebridgeMapping} = $Hyperion_homebridgeMapping;
  99. $attr{$name}{icon} = "light_led_stripe_rgb";
  100. $attr{$name}{lightSceneParamsToSave} = "state";
  101. $attr{$name}{room} = "Hyperion";
  102. $attr{$name}{webCmd} = $Hyperion_webCmd;
  103. $attr{$name}{widgetOverride} = "dimUp:noArg dimDown:noArg";
  104. addToDevAttrList($name,"lightSceneParamsToSave") if (index($attr{"global"}{userattr},"lightSceneParamsToSave") == -1);
  105. addToDevAttrList($name,"homebridgeMapping") if (index($attr{"global"}{userattr},"homebridgeMapping") == -1);
  106. }
  107. if ($init_done)
  108. {
  109. Hyperion_GetUpdate($hash);
  110. }
  111. else
  112. {
  113. InternalTimer(gettimeofday() + $interval,"Hyperion_GetUpdate",$hash);
  114. }
  115. return undef;
  116. }
  117. sub Hyperion_DoInit($)
  118. {
  119. my ($hash) = @_;
  120. DevIo_SimpleWrite($hash,encode_json($Hyperion_serverinfo)."\n",2);
  121. return undef;
  122. }
  123. sub Hyperion_Notify($$)
  124. {
  125. my ($hash,$dev) = @_;
  126. my $name = $hash->{NAME};
  127. return if ($dev->{NAME} ne "global");
  128. return if (!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}}));
  129. return undef if (IsDisabled($name));
  130. Hyperion_Read($hash);
  131. return undef;
  132. }
  133. sub Hyperion_OpenDev($)
  134. {
  135. my ($hash) = @_;
  136. $hash->{STATE} = DevIo_OpenDev($hash,0,"Hyperion_DoInit",sub($$$)
  137. {
  138. my ($h,$err) = @_;
  139. if ($err)
  140. {
  141. readingsBeginUpdate($hash);
  142. readingsBulkUpdate($hash,"lastError",$err);
  143. readingsBulkUpdate($hash,"serverResponse","ERROR");
  144. readingsBulkUpdate($hash,"state","ERROR");
  145. readingsEndUpdate($hash,1);
  146. }
  147. return $err ? "Error: $err" : $hash->{DeviceName}." connected";
  148. });
  149. return undef;
  150. }
  151. sub Hyperion_Undef($$)
  152. {
  153. my ($hash,$name) = @_;
  154. RemoveInternalTimer($hash);
  155. DevIo_CloseDev($hash);
  156. return undef;
  157. }
  158. sub Hyperion_list2array($$)
  159. {
  160. my ($list,$round) = @_;
  161. my @arr;
  162. foreach my $part (split(",",$list))
  163. {
  164. $part = sprintf($round,$part) * 1;
  165. push @arr,$part;
  166. }
  167. return \@arr;
  168. }
  169. sub Hyperion_isLocal($)
  170. {
  171. my ($hash) = @_;
  172. return ($hash->{IP} =~ /^(localhost|127\.0{1,3}\.0{1,3}\.(0{1,2})?1)$/)?1:undef;
  173. }
  174. sub Hyperion_Get($@)
  175. {
  176. my ($hash,$name,$cmd) = @_;
  177. my $params = "devStateIcon:noArg ".
  178. "statusRequest:noArg ".
  179. "configFiles:noArg ";
  180. return "get $name needs one parameter: $params"
  181. if (!$cmd);
  182. if ($cmd eq "configFiles")
  183. {
  184. Hyperion_GetConfigs($hash);
  185. }
  186. elsif ($cmd eq "devStateIcon")
  187. {
  188. return Hyperion_devStateIcon($hash);
  189. }
  190. elsif ($cmd eq "statusRequest")
  191. {
  192. Hyperion_GetUpdate($hash);
  193. }
  194. else
  195. {
  196. return "Unknown argument $cmd for $name, choose one of $params";
  197. }
  198. }
  199. sub Hyperion_Read($)
  200. {
  201. my ($hash) = @_;
  202. my $name = $hash->{NAME};
  203. my $buf = DevIo_SimpleRead($hash);
  204. return undef if (!$buf);
  205. my $result = $hash->{PARTIAL}?$hash->{PARTIAL}.$buf:$buf;
  206. $hash->{PARTIAL} = $result;
  207. return undef if ($buf !~ /(^.+"success":(true|false)\}$)/);
  208. Log3 $name,5,"$name: url ".$hash->{DeviceName}." returned result: $result";
  209. delete $hash->{PARTIAL};
  210. $result =~ /(\s+)?\/{2,}.*|(?:[\t ]*(?:\r?\n|\r))+/gm;
  211. if ($result =~ /^\{"success":true\}$/)
  212. {
  213. fhem "sleep 1; get $name statusRequest"
  214. if (AttrVal($name,"queryAfterSet",1) == 1 || !$hash->{INTERVAL});
  215. return undef;
  216. }
  217. elsif ($result =~ /^\{"info":\{.+\},"success":true\}$/)
  218. {
  219. my $obj = eval {decode_json($result)};
  220. my $data = $obj->{info};
  221. if (AttrVal($name,"hyperionVersionCheck",1) == 1)
  222. {
  223. my $error;
  224. $error = "Can't detect your version of hyperion!"
  225. if (!$data->{hyperion_build}->[0]->{version});
  226. if (!$error)
  227. {
  228. my $ver = (split("V",(split(" ",$data->{hyperion_build}->[0]->{version}))[0]))[1];
  229. $ver =~ s/\.//g;
  230. my $rver = $Hyperion_requiredVersion;
  231. $rver =~ s/\.//g;
  232. $error = "Your version of hyperion (detected version: ".$data->{hyperion_build}->[0]->{version}.") is not (longer) supported by this module!" if ($ver<$rver);
  233. }
  234. if ($error)
  235. {
  236. $error = "ATTENTION!!! $error Please update your hyperion to V$Hyperion_requiredVersion at least using HyperCon...";
  237. Log3 $name, 1, $error;
  238. readingsBeginUpdate($hash);
  239. readingsBulkUpdate($hash,"serverResponse","ERROR");
  240. readingsBulkUpdate($hash,"lastError",$error);
  241. readingsBulkUpdate($hash,"state","ERROR");
  242. readingsEndUpdate($hash,1);
  243. return undef;
  244. }
  245. }
  246. my $vers = $data->{hyperion_build}->[0]->{version} ? $data->{hyperion_build}->[0]->{version} : "";
  247. my $prio = (defined $data->{priorities}->[0]->{priority}) ? $data->{priorities}->[0]->{priority} : "";
  248. my $duration = (defined $data->{priorities}->[0]->{duration_ms} && $data->{priorities}->[0]->{duration_ms} > 999) ? int($data->{priorities}->[0]->{duration_ms} / 1000) : 0;
  249. $duration = ($duration) >= 1 ? $duration : "infinite";
  250. my $adj = $data->{adjustment}->[0] ? $data->{adjustment}->[0] : undef;
  251. my $col = $data->{activeLedColor}->[0]->{"HEX Value"}->[0] ? $data->{activeLedColor}->[0]->{"HEX Value"}->[0] : "";
  252. my $configs = ReadingsVal($name,".configs",undef);
  253. my $corr = $data->{correction}->[0] ? $data->{correction}->[0] : undef;
  254. my $effects = $data->{effects} ? $data->{effects} : undef;
  255. if ($hash->{helper}{customeffects})
  256. {
  257. foreach my $eff (@{$hash->{helper}{customeffects}})
  258. {
  259. push @{$effects},$eff;
  260. }
  261. }
  262. my $effectList = $effects ? join(",",map {"$_->{name}"} @{$effects}) : "";
  263. $effectList =~ s/ /_/g;
  264. my $effargs = $data->{activeEffects}->[0]->{args} ? JSON->new->convert_blessed->canonical->encode($data->{activeEffects}->[0]->{args}) : undef;
  265. my $script = $data->{activeEffects}->[0]->{script} ? $data->{activeEffects}->[0]->{script} : undef;
  266. my $temp = $data->{temperature}->[0] ? $data->{temperature}->[0] : undef;
  267. my $trans = $data->{transform}->[0] ? $data->{transform}->[0] : undef;
  268. my $id = $trans->{id} ? $trans->{id} : undef;
  269. my $adjR = $adj ? join(",",@{$adj->{redAdjust}}) : undef;
  270. my $adjG = $adj ? join(",",@{$adj->{greenAdjust}}) : undef;
  271. my $adjB = $adj ? join(",",@{$adj->{blueAdjust}}) : undef;
  272. my $corS = $corr ? join(",",@{$corr->{correctionValues}}) : undef;
  273. my $temP = $temp ? join(",",@{$temp->{correctionValues}}) : undef;
  274. my $blkL = $trans->{blacklevel} ? sprintf("%.2f",$trans->{blacklevel}->[0]).",".sprintf("%.2f",$trans->{blacklevel}->[1]).",".sprintf("%.2f",$trans->{blacklevel}->[2]) : undef;
  275. my $gamM = $trans->{gamma} ? sprintf("%.2f",$trans->{gamma}->[0]).",".sprintf("%.2f",$trans->{gamma}->[1]).",".sprintf("%.2f",$trans->{gamma}->[2]) : undef;
  276. my $thrE = $trans->{threshold} ? sprintf("%.2f",$trans->{threshold}->[0]).",".sprintf("%.2f",$trans->{threshold}->[1]).",".sprintf("%.2f",$trans->{threshold}->[2]) : undef;
  277. my $whiL = $trans->{whitelevel} ? sprintf("%.2f",$trans->{whitelevel}->[0]).",".sprintf("%.2f",$trans->{whitelevel}->[1]).",".sprintf("%.2f",$trans->{whitelevel}->[2]) : undef;
  278. my $lumG = defined $trans->{luminanceGain} ? sprintf("%.2f",$trans->{luminanceGain}) : undef;
  279. my $lumM = defined $trans->{luminanceMinimum} ? sprintf("%.2f",$trans->{luminanceMinimum}) : undef;
  280. my $satG = defined $trans->{saturationGain} ? sprintf("%.2f",$trans->{saturationGain}) : undef;
  281. my $satL = defined $trans->{saturationLGain} ? sprintf("%.2f",$trans->{saturationLGain}) : undef;
  282. my $valG = defined $trans->{valueGain} ? sprintf("%.2f",$trans->{valueGain}) : undef;
  283. $hash->{hostname} = $data->{hostname} if (($data->{hostname} && !$hash->{hostname}) || ($data->{hostname} && $hash->{hostname} ne $data->{hostname}));
  284. $hash->{build_version} = $vers if (($vers && !$hash->{build_version}) || ($vers && $hash->{build_version} ne $vers));
  285. $hash->{build_time} = $data->{hyperion_build}->[0]->{time} if (($data->{hyperion_build}->[0]->{time} && !$hash->{build_time}) || ($data->{hyperion_build}->[0]->{time} && $hash->{build_time} ne $data->{hyperion_build}->[0]->{time}));
  286. readingsBeginUpdate($hash);
  287. readingsBulkUpdate($hash,"adjustRed",$adjR);
  288. readingsBulkUpdate($hash,"adjustGreen",$adjG);
  289. readingsBulkUpdate($hash,"adjustBlue",$adjB);
  290. readingsBulkUpdate($hash,"blacklevel",$blkL);
  291. readingsBulkUpdate($hash,"colorTemperature",$temP);
  292. readingsBulkUpdate($hash,"correction",$corS);
  293. readingsBulkUpdate($hash,"effect",(split(",",$effectList))[0]) if (!defined ReadingsVal($name,"effect",undef));
  294. readingsBulkUpdate($hash,".effects",$effectList);
  295. readingsBulkUpdate($hash,"effectArgs",$effargs);
  296. readingsBulkUpdate($hash,"duration",$duration);
  297. readingsBulkUpdate($hash,"gamma",$gamM);
  298. readingsBulkUpdate($hash,"id",$id);
  299. readingsBulkUpdate($hash,"luminanceGain",$lumG);
  300. readingsBulkUpdate($hash,"luminanceMinimum",$lumM);
  301. readingsBulkUpdate($hash,"priority",$prio);
  302. readingsBulkUpdate($hash,"rgb","ff0d0d") if (!defined ReadingsVal($name,"rgb",undef));
  303. readingsBulkUpdate($hash,"saturationGain",$satG);
  304. readingsBulkUpdate($hash,"saturationLGain",$satL);
  305. readingsBulkUpdate($hash,"threshold",$thrE);
  306. readingsBulkUpdate($hash,"valueGain",$valG);
  307. readingsBulkUpdate($hash,"whitelevel",$whiL);
  308. if ($script)
  309. {
  310. my $effname;
  311. my $tempname;
  312. foreach my $e (@$effects)
  313. {
  314. if ($e->{script} && $e->{script} eq $script)
  315. {
  316. $tempname = $e->{name};
  317. $effname = $e->{name} if (JSON->new->convert_blessed->canonical->encode($e->{args}) eq $effargs);
  318. }
  319. }
  320. if (!$effname)
  321. {
  322. foreach my $e (@{$hash->{helper}{customeffects}})
  323. {
  324. $effname = $e->{name} if (JSON->new->convert_blessed->canonical->encode($e->{args}) eq $effargs);
  325. }
  326. }
  327. $effname = $effname?$effname:$tempname;
  328. $effname =~ s/ /_/g;
  329. readingsBulkUpdate($hash,"effect",$effname);
  330. readingsBulkUpdate($hash,"mode","effect");
  331. readingsBulkUpdate($hash,"state","effect $effname");
  332. readingsBulkUpdate($hash,"mode_before_off","effect");
  333. Log3 $name,4,"$name: effect $effname";
  334. }
  335. elsif ($col)
  336. {
  337. my $rgb = lc((split("x",$col))[1]);
  338. my ($r,$g,$b) = Color::hex2rgb($rgb);
  339. my ($h,$s,$v) = Color::rgb2hsv($r / 255,$g / 255,$b / 255);
  340. my $dim = int($v * 100);
  341. readingsBulkUpdate($hash,"rgb",$rgb);
  342. readingsBulkUpdate($hash,"dim",$dim);
  343. readingsBulkUpdate($hash,"mode","rgb");
  344. readingsBulkUpdate($hash,"mode_before_off","rgb");
  345. readingsBulkUpdate($hash,"state","rgb $rgb");
  346. Log3 $name,4,"$name: rgb $rgb";
  347. }
  348. else
  349. {
  350. if ($prio && defined $data->{priorities}->[0]->{duration_ms} && !defined $data->{priorities}->[1]->{priority})
  351. {
  352. readingsBulkUpdate($hash,"mode","clearall");
  353. readingsBulkUpdate($hash,"mode_before_off","clearall");
  354. readingsBulkUpdate($hash,"state","clearall");
  355. Log3 $name,4,"$name: clearall";
  356. }
  357. else
  358. {
  359. readingsBulkUpdate($hash,"mode","off");
  360. readingsBulkUpdate($hash,"state","off");
  361. Log3 $name,4,"$name: off";
  362. }
  363. }
  364. readingsBulkUpdate($hash,"serverResponse","success");
  365. readingsEndUpdate($hash,1);
  366. }
  367. else
  368. {
  369. Log3 $name,4,"$name: error while requesting ".$hash->{DeviceName}." - $result";
  370. readingsBeginUpdate($hash);
  371. readingsBulkUpdate($hash,"lastError","error while requesting ".$hash->{DeviceName});
  372. readingsBulkUpdate($hash,"serverResponse","ERROR");
  373. readingsBulkUpdate($hash,"state","ERROR");
  374. readingsEndUpdate($hash,1);
  375. }
  376. return undef;
  377. }
  378. sub Hyperion_GetConfigs($)
  379. {
  380. my ($hash) = @_;
  381. return "Not connected" if (!$hash->{FD});
  382. my $name = $hash->{NAME};
  383. my $ip = $hash->{IP};
  384. my $dir = AttrVal($name,"hyperionConfigDir","/etc/hyperion/");
  385. my $com = "ls $dir 2>/dev/null";
  386. my @files;
  387. if (Hyperion_isLocal($hash))
  388. {
  389. @files = Hyperion_listFilesInDir($hash,$com);
  390. }
  391. else
  392. {
  393. my $user = AttrVal($name,"hyperionSshUser","pi");
  394. my $cmd = qx(which ssh);
  395. chomp $cmd;
  396. $cmd .= " $user\@$ip $com";
  397. @files = Hyperion_listFilesInDir($hash,$cmd);
  398. }
  399. return "No files found on server $ip in directory $dir. Maybe the wrong directory? If SSH is used, has the user ".AttrVal($name,"hyperionSshUser","pi")." been configured to log in without entering a password (http://www.linuxproblem.org/art_9.html)?"
  400. if (@files == 0);
  401. if (@files > 1)
  402. {
  403. my $configs = join(",",@files);
  404. readingsSingleUpdate($hash,".configs",$configs,1) if (ReadingsVal($name,".configs","") ne $configs);
  405. $attr{$name}{webCmd} = $Hyperion_webCmd_config if (AttrVal($name,"webCmd","") eq $Hyperion_webCmd);
  406. }
  407. else
  408. {
  409. fhem "deletereading $name .configs" if (defined ReadingsVal($name,".configs",undef));
  410. $attr{$name}{webCmd} = $Hyperion_webCmd if (AttrVal($name,"webCmd","") eq $Hyperion_webCmd_config);
  411. return "Found just one config file. Please add at least one more config file to properly use this function."
  412. if (@files == 1);
  413. return "No config files found!";
  414. }
  415. Hyperion_GetUpdate($hash);
  416. return "Found ".@files." config files. Please refresh this page to see the result.";
  417. }
  418. sub Hyperion_listFilesInDir($$)
  419. {
  420. my ($hash,$cmd) = @_;
  421. my $name = $hash->{NAME};
  422. my $fh;
  423. my @filelist;
  424. if (open($fh,"$cmd|"))
  425. {
  426. my @files = <$fh>;
  427. for (my $i = 0; $i < @files; $i++)
  428. {
  429. my $file = $files[$i];
  430. $file =~ s/\s+//gm;
  431. next if ($file !~ /\w+\.config\.json$/);
  432. $file =~ s/.config.json$//gm;
  433. push @filelist,$file;
  434. Log3 $name,4,"$name: Hyperion_listFilesInDir matching file: \"$file\"";
  435. }
  436. close $fh;
  437. }
  438. return @filelist;
  439. }
  440. sub Hyperion_GetUpdate(@)
  441. {
  442. my ($hash) = @_;
  443. my $name = $hash->{NAME};
  444. RemoveInternalTimer($hash);
  445. if ($hash->{INTERVAL})
  446. {
  447. InternalTimer(gettimeofday() + $hash->{INTERVAL},"Hyperion_GetUpdate",$hash);
  448. }
  449. return undef if (IsDisabled($hash));
  450. Hyperion_Call($hash);
  451. return undef;
  452. }
  453. sub Hyperion_Set($@)
  454. {
  455. my ($hash,$name,@aa) = @_;
  456. my ($cmd,@args) = @aa;
  457. my $value = (defined($args[0])) ? $args[0] : undef;
  458. return "\"set $name\" needs at least one argument and maximum five arguments" if (@aa < 1 || @aa > 5);
  459. my $duration = (defined $args[1]) ? int $args[1] : int AttrVal($name,"hyperionDefaultDuration",0);
  460. my $priority = (defined $args[2]) ? int $args[2] : int AttrVal($name,"hyperionDefaultPriority",0);
  461. my %Hyperion_sets_local = %Hyperion_sets;
  462. if (ReadingsVal($name,".configs",""))
  463. {
  464. $Hyperion_sets_local{configFile} = ReadingsVal($name,".configs","");
  465. $attr{$name}{webCmd} = $Hyperion_webCmd_config if (AttrVal($name,"webCmd","") eq $Hyperion_webCmd);
  466. }
  467. $Hyperion_sets_local{adjustRed} = "textField" if (ReadingsVal($name,"adjustRed",""));
  468. $Hyperion_sets_local{adjustGreen} = "textField" if (ReadingsVal($name,"adjustGreen",""));
  469. $Hyperion_sets_local{adjustBlue} = "textField" if (ReadingsVal($name,"adjustBlue",""));
  470. $Hyperion_sets_local{correction} = "textField" if (ReadingsVal($name,"correction",""));
  471. $Hyperion_sets_local{effect} = ReadingsVal($name,".effects","") if (ReadingsVal($name,".effects",""));
  472. $Hyperion_sets_local{colorTemperature} = "textField" if (ReadingsVal($name,"colorTemperature",""));
  473. $Hyperion_sets_local{blacklevel} = "textField" if (ReadingsVal($name,"blacklevel",""));
  474. $Hyperion_sets_local{gamma} = "textField" if (ReadingsVal($name,"gamma",""));
  475. $Hyperion_sets_local{threshold} = "textField" if (ReadingsVal($name,"threshold",""));
  476. $Hyperion_sets_local{whitelevel} = "textField" if (ReadingsVal($name,"whitelevel",""));
  477. $Hyperion_sets_local{luminanceGain} = "slider,0,0.01,5,1" if (ReadingsVal($name,"luminanceGain",""));
  478. $Hyperion_sets_local{luminanceMinimum} = "slider,0,0.01,5,1" if (ReadingsVal($name,"luminanceMinimum",""));
  479. $Hyperion_sets_local{saturationGain} = "slider,0,0.01,5,1" if (ReadingsVal($name,"saturationGain",""));
  480. $Hyperion_sets_local{saturationLGain} = "slider,0,0.01,5,1" if (ReadingsVal($name,"saturationLGain",""));
  481. $Hyperion_sets_local{valueGain} = "slider,0,0.01,5,1" if (ReadingsVal($name,"valueGain",""));
  482. my $params = join(" ",map {"$_:$Hyperion_sets_local{$_}"} keys %Hyperion_sets_local);
  483. my %obj;
  484. Log3 $name,4,"$name: Hyperion_Set cmd: $cmd";
  485. Log3 $name,4,"$name: Hyperion_Set value: $value" if ($value);
  486. Log3 $name,4,"$name: Hyperion_Set duration: $duration, priority: $priority" if ($cmd =~ /^rgb|dim|dimUp|dimDown|effect$/);
  487. if ($cmd eq "configFile")
  488. {
  489. $value = $value.".config.json";
  490. my $confdir = AttrVal($name,"hyperionConfigDir","/etc/hyperion/");
  491. my $binpath = AttrVal($name,"hyperionBin","/usr/bin/hyperiond");
  492. my $bin = (split("/",$binpath))[scalar(split("/",$binpath)) - 1];
  493. $bin =~ s/\.sh$// if ($bin =~ /\.sh$/);
  494. my $user = AttrVal($name,"hyperionSshUser","pi");
  495. my $ip = $hash->{IP};
  496. my $sudo = ($user eq "root" || int AttrVal($name,"hyperionNoSudo",0) == 1) ? "" : "sudo ";
  497. my $command = $sudo."killall $bin; sleep 1; ".$sudo."$binpath $confdir$value > /dev/null 2>&1 &";
  498. my $status;
  499. my $fh;
  500. if (Hyperion_isLocal($hash))
  501. {
  502. if (open($fh,"$command|"))
  503. {
  504. $status = <$fh>;
  505. close $fh;
  506. }
  507. }
  508. else
  509. {
  510. my $com = qx(which ssh);
  511. chomp $com;
  512. $com .= " $user\@$ip '$command'";
  513. if (open($fh,"$com|"))
  514. {
  515. $status = <$fh>;
  516. close $fh;
  517. }
  518. }
  519. if (!$status)
  520. {
  521. Log3 $name,4,"$name: restarted Hyperion with $binpath $confdir$value";
  522. $value =~ s/.config.json$//;
  523. readingsSingleUpdate($hash,"configFile",$value,1);
  524. return undef;
  525. }
  526. else
  527. {
  528. Log3 $name,4,"$name: NOT restarted Hyperion with $binpath $confdir$value, status: $status";
  529. readingsBeginUpdate($hash);
  530. readingsBulkUpdate($hash,"lastError",$status);
  531. readingsBulkUpdate($hash,"serverResponse","ERROR");
  532. readingsBulkUpdate($hash,"state","ERROR");
  533. readingsEndUpdate($hash,1);
  534. return "$name NOT restarted Hyperion with $binpath $confdir$value, status: $status";
  535. }
  536. }
  537. elsif ($cmd eq "rgb")
  538. {
  539. return "Value of $cmd has to be in RGB hex format like ffffff or 3F7D90"
  540. if ($value !~ /^[\dA-Fa-f]{6}$/);
  541. $value = lc($value);
  542. my ($r,$g,$b) = Color::hex2rgb($value);
  543. $obj{color} = [$r,$g,$b];
  544. $obj{command} = "color";
  545. $obj{priority} = $priority * 1;
  546. $obj{duration} = $duration * 1000 if ($duration > 0);
  547. }
  548. elsif ($cmd eq "dim")
  549. {
  550. return "Value of $cmd has to be between 1 and 100"
  551. if ($value !~ /^(\d+)$/ || $1 > 100 || $1 < 1);
  552. my $rgb = ReadingsVal($name,"rgb","ffffff");
  553. $value = $value + 1
  554. if ($cmd eq "dim" && $value < 100);
  555. $value = $value / 100;
  556. my ($r,$g,$b) = Color::hex2rgb($rgb);
  557. my ($h,$s,$v) = Color::rgb2hsv($r / 255,$g / 255,$b / 255);
  558. my ($rn,$gn,$bn);
  559. ($rn,$gn,$bn) = Color::hsv2rgb($h,$s,$value)
  560. if ($cmd eq "dim");
  561. $rn = int($rn * 255);
  562. $gn = int($gn * 255);
  563. $bn = int($bn * 255);
  564. $obj{color} = [$rn,$gn,$bn];
  565. $obj{command} = "color";
  566. $obj{priority} = $priority * 1;
  567. $obj{duration} = $duration * 1000
  568. if ($duration > 0);
  569. }
  570. elsif ($cmd =~ /^(dimUp|dimDown)$/)
  571. {
  572. return "Value of $cmd has to be between 1 and 99"
  573. if (defined $value && ($value !~ /^(\d+)$/ || $1 > 99 || $1 < 1));
  574. my $dim = ReadingsVal($name,"dim",100);
  575. my $dimStep = $value ? $value : AttrVal($name,"hyperionDimStep",10);
  576. my $dimUp = ($dim + $dimStep < 100) ? $dim + $dimStep : 100;
  577. my $dimDown = ($dim - $dimStep > 0) ? $dim - $dimStep : 1;
  578. $cmd eq "dimUp" ? fhem "set $name dim $dimUp" : fhem "set $name dim $dimDown";
  579. return undef;
  580. }
  581. elsif ($cmd eq "effect")
  582. {
  583. return "Effect $value is not available in the effect list of $name!"
  584. if ($value !~ /^([\w-]+)$/ || index(ReadingsVal($name,".effects",""),$value) == -1);
  585. my $arg = $args[3] ? eval{decode_json $args[3]} : "";
  586. my $ce = $hash->{helper}{customeffects};
  587. if (!$arg && $ce)
  588. {
  589. foreach my $eff (@{$ce})
  590. {
  591. if ($eff->{name} eq $value)
  592. {
  593. $value = $eff->{oname};
  594. $arg = $eff->{args};
  595. }
  596. }
  597. }
  598. $value =~ s/_/ /g;
  599. my %ef = ("name" => $value);
  600. $ef{args} = $arg if ($arg);
  601. $obj{effect} = \%ef;
  602. $obj{command} = "effect";
  603. $obj{priority} = $priority * 1;
  604. $obj{duration} = $duration * 1000 if ($duration > 0);
  605. }
  606. elsif ($cmd eq "clearall")
  607. {
  608. return "$cmd need no additional value of $value" if (defined $value);
  609. $obj{command} = $cmd;
  610. }
  611. elsif ($cmd eq "clear")
  612. {
  613. return "Value of $cmd has to be between 0 and 65536 in steps of 1"
  614. if (defined $value && $value !~ /^(\d+)$/ || $1 > 65536);
  615. $obj{command} = $cmd;
  616. $value = defined $1?$1:AttrVal($name,"hyperionDefaultPriority",0);
  617. $obj{priority} = $value*1;
  618. }
  619. elsif ($cmd eq "off")
  620. {
  621. return "$cmd need no additional value of $value" if (defined $value);
  622. $obj{command} = "color";
  623. $obj{color} = [0,0,0];
  624. $obj{priority} = AttrVal($name,"hyperionDefaultPriority",0)*1;
  625. }
  626. elsif ($cmd eq "on")
  627. {
  628. return "$cmd need no additional value of $value" if (defined $value);
  629. my $rmode = ReadingsVal($name,"mode_before_off","rgb");
  630. my $rrgb = ReadingsVal($name,"rgb","");
  631. my $reffect = ReadingsVal($name,"effect","");
  632. my ($r,$g,$b) = Color::hex2rgb($rrgb);
  633. if ($rmode eq "rgb")
  634. {
  635. fhem "set ".$name." $rmode $rrgb";
  636. }
  637. elsif ($rmode eq "effect")
  638. {
  639. fhem "set ".$name." $rmode $reffect";
  640. }
  641. elsif ($rmode eq "clearall")
  642. {
  643. fhem "set ".$name." clearall";
  644. }
  645. return undef;
  646. }
  647. elsif ($cmd eq "toggle")
  648. {
  649. return "$cmd need no additional value of $value" if (defined $value);
  650. my $state = Value($name);
  651. my $nstate = $state ne "off" ? "off" : "on";
  652. fhem "set $name $nstate";
  653. return undef;
  654. }
  655. elsif ($cmd eq "toggleMode")
  656. {
  657. return "$cmd need no additional value of $value" if (defined $value);
  658. my $mode = ReadingsVal($name,"mode","off");
  659. my $nmode;
  660. my @modeorder = split(",",AttrVal($name,"hyperionToggleModes","clearall,rgb,effect,off"));
  661. for (my $i = 0; $i < @modeorder; $i++)
  662. {
  663. $nmode = $i < @modeorder - 1 ? $modeorder[$i+1] : $modeorder[0] if ($modeorder[$i] eq $mode);
  664. }
  665. $nmode = $nmode?$nmode:$modeorder[0];
  666. fhem "set $name mode $nmode";
  667. return undef;
  668. }
  669. elsif ($cmd eq "mode")
  670. {
  671. return "The value of mode has to be rgb,effect,clearall,off" if ($value !~ /^(off|clearall|rgb|effect)$/);
  672. Log3 $name,4,"$name: cmd: $cmd, value: $value";
  673. my $rmode = $value;
  674. my $rrgb = ReadingsVal($name,"rgb","");
  675. my $reffect = ReadingsVal($name,"effect","");
  676. my ($r,$g,$b) = Color::hex2rgb($rrgb);
  677. if ($rmode eq "rgb")
  678. {
  679. fhem "set $name $rmode $rrgb";
  680. }
  681. elsif ($rmode eq "effect")
  682. {
  683. fhem "set $name $rmode $reffect";
  684. }
  685. elsif ($rmode eq "clearall")
  686. {
  687. fhem "set $name clearall";
  688. }
  689. elsif ($rmode eq "off")
  690. {
  691. fhem "set $name $rmode";
  692. }
  693. return undef;
  694. }
  695. elsif ($cmd =~ /^(luminanceGain|luminanceMinimum|saturationGain|saturationLGain|valueGain)$/)
  696. {
  697. return "The value of $cmd has to be from 0.00 to 5.00 in steps of 0.01."
  698. if ($value !~ /^((\d)\.(\d){1,2})?$/ || $1 > 5);
  699. $value = sprintf("%.4f",$value) * 1;
  700. my %tr = ($cmd => $value);
  701. $obj{command} = "transform";
  702. $obj{transform} = \%tr;
  703. }
  704. elsif ($cmd =~ /^(blacklevel|gamma|threshold|whitelevel)$/)
  705. {
  706. return "Each of the three comma separated values of $cmd must be from 0.00 to 1.00 in steps of 0.01"
  707. if ($cmd =~ /^blacklevel|threshold|whitelevel$/ && ($value !~ /^((\d)\.(\d){1,2}),((\d)\.(\d){1,2}),((\d)\.(\d){1,2})$/ || $1 > 1 || $4 > 1 || $7 > 1));
  708. return "Each of the three comma separated values of $cmd must be from 0.00 to 5.00 in steps of 0.01"
  709. if ($cmd eq "gamma" && ($value !~ /^((\d)\.(\d){1,2}),((\d)\.(\d){1,2}),((\d)\.(\d){1,2})$/ || $1 > 5 || $4 > 5 || $7 > 5));
  710. my $arr = Hyperion_list2array($value,"%.4f");
  711. my %ar = ($cmd => $arr);
  712. $obj{command} = "transform";
  713. $obj{transform} = \%ar;
  714. }
  715. elsif ($cmd =~ /^(correction|colorTemperature)$/)
  716. {
  717. $cmd = "temperature" if ($cmd eq "colorTemperature");
  718. return "Each of the three comma separated values of $cmd must be from 0 to 255 in steps of 1"
  719. if ($value !~ /^(\d{1,3})?,(\d{1,3})?,(\d{1,3})?$/ || $1 > 255 || $2 > 255 || $3 > 255);
  720. my $arr = Hyperion_list2array($value,"%d");
  721. my %ar = ("correctionValues" => $arr);
  722. $obj{command} = $cmd;
  723. $obj{$cmd} = \%ar;
  724. }
  725. elsif ($cmd =~ /^(adjustRed|adjustGreen|adjustBlue)$/)
  726. {
  727. return "Each of the three comma separated values of $cmd must be from 0 an 255 in steps of 1"
  728. if ($value !~ /^(\d{1,3})?,(\d{1,3})?,(\d{1,3})?$/ || $1 > 255 || $2 > 255 || $3 > 255);
  729. $cmd = "redAdjust" if ($cmd eq "adjustRed");
  730. $cmd = "greenAdjust" if ($cmd eq "adjustGreen");
  731. $cmd = "blueAdjust" if ($cmd eq "adjustBlue");
  732. my $arr = Hyperion_list2array($value,"%d");
  733. my %ar = ($cmd => $arr);
  734. $obj{command} = "adjustment";
  735. $obj{adjustment} = \%ar;
  736. }
  737. elsif ($cmd =~ /^(valueGainUp|valueGainDown)$/)
  738. {
  739. return "Value of $cmd has to be between 0.1 and 1.0 in steps of 0.1"
  740. if (defined $value && ($value !~ /^(\d\.\d)$/ || $1 > 1 || $1 < 0.1));
  741. my $gain = ReadingsNum($name,"valueGain",1);
  742. my $gainStep = $value ? $value : AttrVal($name,"hyperionGainStep",0.1);
  743. my $gainUp = ($gain + $gainStep < 5) ? $gain + $gainStep : 5;
  744. my $gainDown = ($gain - $gainStep > 0) ? $gain - $gainStep : 0.1;
  745. $cmd eq "valueGainUp" ? fhem "set $name valueGain $gainUp" : fhem "set $name valueGain $gainDown";
  746. return undef;
  747. }
  748. elsif ($cmd eq "addEffect")
  749. {
  750. return "$name must be in effect mode!" if (ReadingsVal($name,"mode","off") ne "effect");
  751. return "Value of $cmd has to be a name like My_custom_EffeKt1 or my-effect!" if (!defined $value || $value !~ /^[a-zA-Z0-9_-]+$/);
  752. return "Effect with name $value already defined! Please choose a different name!" if (grep(/^$value$/,split(",",ReadingsVal($name,".effects",""))));
  753. my $eff = ReadingsVal($name,"effect","");
  754. foreach my $e (@{$hash->{helper}{customeffects}})
  755. {
  756. return "The base effect can't be a custom effect! Please set a non-custom effect first!" if ($e->{name} eq $eff);
  757. }
  758. my $effs = AttrVal($name,"hyperionCustomEffects","");
  759. $effs .= "\r\n" if ($effs);
  760. $effs .= '{"name":"'.$value.'","oname":"'.$eff.'","args":'.ReadingsVal($name,"effectArgs","").'}';
  761. $attr{$name}{hyperionCustomEffects} = $effs;
  762. return undef;
  763. }
  764. if (scalar keys %obj)
  765. {
  766. Log3 $name,5,"$name: $cmd obj json: ".encode_json(\%obj);
  767. SetExtensionsCancel($hash);
  768. Hyperion_Call($hash,\%obj);
  769. return undef;
  770. }
  771. return SetExtensions($hash,$params,$name,@aa);
  772. }
  773. sub Hyperion_Attr(@)
  774. {
  775. my ($cmd,$name,$attr_name,$attr_value) = @_;
  776. my $hash = $defs{$name};
  777. my $err = undef;
  778. my $local = Hyperion_isLocal($hash);
  779. if ($cmd eq "set")
  780. {
  781. if ($attr_name eq "hyperionBin")
  782. {
  783. if ($attr_value !~ /^(\/.+){2,}$/)
  784. {
  785. $err = "Invalid value $attr_value for attribute $attr_name. Must be a path like /usr/bin/hyperiond.";
  786. }
  787. elsif ($local && !-e $attr_value)
  788. {
  789. $err = "The given file $attr_value is not available.";
  790. }
  791. }
  792. elsif ($attr_name eq "hyperionCustomEffects")
  793. {
  794. if ($attr_value !~ /^\{"name":"[a-zA-Z0-9_-]+","oname":"[a-zA-Z0-9_-]+","args":\{[a-zA-Z0-9:_\[\]\.",-]+\}\}([\s(\r\n)]\{"name":"[a-zA-Z0-9_-]+","oname":"[a-zA-Z0-9_-]+","args":\{[a-zA-Z0-9:_\[\]\.",-]+\}\}){0,}$/)
  795. {
  796. $err = "Invalid value $attr_value for attribute $attr_name. Must be a space separated list of JSON strings.";
  797. }
  798. else
  799. {
  800. $attr_value =~ s/\r\n/ /;
  801. $attr_value =~ s/\s{2,}/ /;
  802. my @custeffs = split(" ",$attr_value);
  803. my @effs;
  804. if (@custeffs > 1)
  805. {
  806. foreach my $eff (@custeffs)
  807. {
  808. push @effs,eval{decode_json $eff};
  809. }
  810. }
  811. else
  812. {
  813. push @effs,eval{decode_json $attr_value};
  814. }
  815. $hash->{helper}{customeffects} = \@effs;
  816. Hyperion_Call($hash);
  817. }
  818. }
  819. elsif ($attr_name eq "hyperionConfigDir")
  820. {
  821. if ($attr_value !~ /^\/(.+\/){2,}/)
  822. {
  823. $err = "Invalid value $attr_value for attribute $attr_name. Must be a path with trailing slash like /etc/hyperion/.";
  824. }
  825. elsif ($local && !-d $attr_value)
  826. {
  827. $err = "The given directory $attr_value is not available.";
  828. }
  829. else
  830. {
  831. Hyperion_GetConfigs($hash);
  832. Hyperion_Call($hash);
  833. }
  834. }
  835. elsif ($attr_name =~ /^hyperionDefault(Priority|Duration)$/)
  836. {
  837. $err = "Invalid value $attr_value for attribute $attr_name. Must be a number between 0 and 65536." if ($attr_value !~ /^(\d+)$/ || $1 < 0 || $1 > 65536);
  838. }
  839. elsif ($attr_name eq "hyperionDimStep")
  840. {
  841. $err = "Invalid value $attr_value for attribute $attr_name. Must be between 1 and 50 in steps of 1, default is 5." if ($attr_value !~ /^(\d+)$/ || $1 < 1 || $1 > 50);
  842. }
  843. elsif ($attr_name eq "hyperionNoSudo")
  844. {
  845. $err = "Invalid value $attr_value for attribute $attr_name. Can only be value 1." if ($attr_value !~ /^1$/);
  846. }
  847. elsif ($attr_name eq "hyperionSshUser")
  848. {
  849. if ($attr_value !~ /^\w+$/)
  850. {
  851. $err = "Invalid value $attr_value for attribute $attr_name. Must be a name like pi or fhem.";
  852. }
  853. else
  854. {
  855. Hyperion_GetConfigs($hash);
  856. Hyperion_Call($hash);
  857. }
  858. }
  859. elsif ($attr_name eq "hyperionToggleModes")
  860. {
  861. $err = "Invalid value $attr_value for attribute $attr_name. Must be a comma separated list of available modes of clearall,rgb,effect,off. Each mode only once in the list." if ($attr_value !~ /^(clearall|rgb|effect|off),(clearall|rgb|effect|off)(,(clearall|rgb|effect|off)){0,2}$/);
  862. }
  863. elsif ($attr_name eq "hyperionVersionCheck")
  864. {
  865. $err = "Invalid value $attr_value for attribute $attr_name. Can only be value 0." if ($attr_value !~ /^0$/);
  866. }
  867. elsif ($attr_name eq "queryAfterSet")
  868. {
  869. $err = "Invalid value $attr_value for attribute $attr_name. Must be 0 if set, default is 1." if ($attr_value !~ /^0$/);
  870. }
  871. elsif ($attr_name eq "disable")
  872. {
  873. $err = "Invalid value $attr_value for attribute $attr_name. Must be 1 if set, default is 0." if ($attr_value !~ /^0|1$/);
  874. return $err if (defined $err);
  875. if ($attr_value eq "1")
  876. {
  877. RemoveInternalTimer($hash);
  878. DevIo_Disconnected($hash);
  879. DevIo_CloseDev($hash);
  880. }
  881. else
  882. {
  883. Hyperion_GetUpdate($hash);
  884. }
  885. }
  886. }
  887. else
  888. {
  889. delete $hash->{helper}{customeffects} if ($attr_name eq "hyperionCustomEffects");
  890. Hyperion_GetUpdate($hash) if (!IsDisabled($hash));
  891. }
  892. return $err if (defined $err);
  893. return undef;
  894. }
  895. sub Hyperion_Call($;$)
  896. {
  897. my ($hash,$obj) = @_;
  898. $obj = ($obj) ? $obj : $Hyperion_serverinfo;
  899. my $name = $hash->{NAME};
  900. my $json = encode_json($obj);
  901. return undef if (IsDisabled($name));
  902. if (!$hash->{FD})
  903. {
  904. DevIo_CloseDev($hash);
  905. DevIo_Disconnected($hash);
  906. Hyperion_OpenDev($hash);
  907. return undef;
  908. }
  909. Log3 $name,5,"$name: Hyperion_Call: json object: $json";
  910. DevIo_SimpleWrite($hash,$json."\n",2);
  911. }
  912. sub Hyperion_devStateIcon($;$)
  913. {
  914. my ($hash,$state) = @_;
  915. $hash = $defs{$hash} if (ref $hash ne "HASH");
  916. return undef if (!$hash);
  917. my $name = $hash->{NAME};
  918. my $rgb = ReadingsVal($name,"rgb","");
  919. my $dim = ReadingsVal($name,"dim",10);
  920. my $ico = (int($dim / 10) * 10 < 10)?10:int($dim / 10) * 10;
  921. return ".*:off:toggle"
  922. if (Value($name) eq "off");
  923. return ".*:light_exclamation"
  924. if (Value($name) =~ /^(ERROR|disconnected)$/);
  925. return ".*:light_light_dim_$ico@#".$rgb.":toggle"
  926. if (Value($name) ne "off" && ReadingsVal($name,"mode","") eq "rgb");
  927. return ".*:light_led_stripe_rgb@#FFFF00:toggle"
  928. if (Value($name) ne "off" && ReadingsVal($name,"mode","") eq "effect");
  929. return ".*:it_television@#0000FF:toggle"
  930. if (Value($name) ne "off" && ReadingsVal($name,"mode","") eq "clearall");
  931. return ".*:light_question";
  932. }
  933. 1;
  934. =pod
  935. =item device
  936. =item summary provides access to the Hyperion JSON server
  937. =item summary_DE stellt Zugang zum Hyperion JSON Server zur Verf&uuml;gung
  938. =begin html
  939. <a name="Hyperion"></a>
  940. <h3>Hyperion</h3>
  941. <ul>
  942. With <i>Hyperion</i> it is possible to change the color or start an effect on a hyperion server.<br>
  943. It's also possible to control the complete color calibration (changes are temorary and will not be written to the config file).<br>
  944. The Hyperion server must have enabled the JSON server.<br>
  945. You can also restart Hyperion with different configuration files (p.e. switch input/grabber)<br>
  946. <br>
  947. <a name="Hyperion_define"></a>
  948. <p><b>Define</b></p>
  949. <ul>
  950. <code>define &lt;name&gt; Hyperion &lt;IP or HOSTNAME&gt; &lt;PORT&gt; [&lt;INTERVAL&gt;]</code><br>
  951. </ul>
  952. <br>
  953. &lt;INTERVAL&gt; is optional for periodically polling.<br>
  954. <br>
  955. <i>After defining "get &lt;name&gt; statusRequest" will be called once automatically to get the list of available effects and the current state of the Hyperion server.</i><br>
  956. <br>
  957. Example for running Hyperion on local system:
  958. <br><br>
  959. <ul>
  960. <code>define Ambilight Hyperion localhost 19444 10</code><br>
  961. </ul>
  962. <br>
  963. Example for running Hyperion on remote system:
  964. <br><br>
  965. <ul>
  966. <code>define Ambilight Hyperion 192.168.1.4 19444 10</code><br>
  967. </ul>
  968. <br>
  969. <a name="Hyperion_set"></a>
  970. <p><b>set &lt;required&gt; [optional]</b></p>
  971. <ul>
  972. <li>
  973. <i>addEffect &lt;custom_name&gt;</i><br>
  974. add the current effect with the given name to the custom effects<br>
  975. can be altered after adding in attribute hyperionCustomEffects<br>
  976. device has to be in effect mode with a non-custom effect and given name must be a unique effect name
  977. </li>
  978. <li>
  979. <i>adjustBlue &lt;0,0,255&gt;</i><br>
  980. adjust each color of blue separately (comma separated) (R,G,B)<br>
  981. values from 0 to 255 in steps of 1
  982. </li>
  983. <li>
  984. <i>adjustGreen &lt;0,255,0&gt;</i><br>
  985. adjust each color of green separately (comma separated) (R,G,B)<br>
  986. values from 0 to 255 in steps of 1
  987. </li>
  988. <li>
  989. <i>adjustRed &lt;255,0,0&gt;</i><br>
  990. adjust each color of red separately (comma separated) (R,G,B)<br>
  991. values from 0 to 255 in steps of 1
  992. </li>
  993. <li>
  994. <i>blacklevel &lt;0.00,0.00,0.00&gt;</i><br>
  995. adjust blacklevel of each color separately (comma separated) (R,G,B)<br>
  996. values from 0.00 to 1.00 in steps of 0.01
  997. </li>
  998. <li>
  999. <i>clear &lt;1000&gt;</i><br>
  1000. clear a specific priority channel
  1001. </li>
  1002. <li>
  1003. <i>clearall</i><br>
  1004. clear all priority channels / switch to Ambilight mode
  1005. </li>
  1006. <li>
  1007. <i>colorTemperature &lt;255,255,255&gt;</i><br>
  1008. adjust temperature of each color separately (comma separated) (R,G,B)<br>
  1009. values from 0 to 255 in steps of 1
  1010. </li>
  1011. <li>
  1012. <i>configFile &lt;filename&gt;</i><br>
  1013. restart the Hyperion server with the given configuration file (files will be listed automatically from the given directory in attribute hyperionConfigDir)<br>
  1014. please omit the double extension of the file name (.config.json)<br>
  1015. only available after successful "get &lt;name&gt; configFiles"
  1016. </li>
  1017. <li>
  1018. <i>correction &lt;255,255,255&gt;</i><br>
  1019. adjust correction of each color separately (comma separated) (R,G,B)<br>
  1020. values from 0 to 255 in steps of 1
  1021. </li>
  1022. <li>
  1023. <i>dim &lt;percent&gt; [duration] [priority]</i><br>
  1024. dim the rgb light to given percentage with optional duration in seconds and optional priority
  1025. </li>
  1026. <li>
  1027. <i>dimDown [delta]</i><br>
  1028. dim down rgb light by steps defined in attribute hyperionDimStep or by given value (default: 10)
  1029. </li>
  1030. <li>
  1031. <i>dimUp [delta]</i><br>
  1032. dim up rgb light by steps defined in attribute hyperionDimStep or by given value (default: 10)
  1033. </li>
  1034. <li>
  1035. <i>effect &lt;effect&gt; [duration] [priority] [effectargs]</i><br>
  1036. set effect (replace blanks with underscore) with optional duration in seconds and priority<br>
  1037. effectargs can also be set as very last argument - must be a JSON string without any whitespace
  1038. </li>
  1039. <li>
  1040. <i>gamma &lt;1.90,1.90,1.90&gt;</i><br>
  1041. adjust gamma of each color separately (comma separated) (R,G,B)<br>
  1042. values from 0.00 to 5.00 in steps of 0.01
  1043. </li>
  1044. <li>
  1045. <i>luminanceGain &lt;1.00&gt;</i><br>
  1046. adjust luminanceGain<br>
  1047. values from 0.00 to 5.00 in steps of 0.01
  1048. </li>
  1049. <li>
  1050. <i>luminanceMinimum &lt;0.00&gt;</i><br>
  1051. adjust luminanceMinimum<br>
  1052. values from 0.00 to 5.00 in steps of 0.01
  1053. </li>
  1054. <li>
  1055. <i>mode &lt;clearall|effect|off|rgb&gt;</i><br>
  1056. set the light in the specific mode with its previous value
  1057. </li>
  1058. <li>
  1059. <i>off</i><br>
  1060. set the light off while the color is black
  1061. </li>
  1062. <li>
  1063. <i>on</i><br>
  1064. set the light on and restore previous state
  1065. </li>
  1066. <li>
  1067. <i>rgb &lt;RRGGBB&gt; [duration] [priority]</i><br>
  1068. set color in RGB hex format with optional duration in seconds and priority
  1069. </li>
  1070. <li>
  1071. <i>saturationGain &lt;1.10&gt;</i><br>
  1072. adjust saturationGain<br>
  1073. values from 0.00 to 5.00 in steps of 0.01
  1074. </li>
  1075. <li>
  1076. <i>saturationLGain &lt;1.00&gt;</i><br>
  1077. adjust saturationLGain<br>
  1078. values from 0.00 to 5.00 in steps of 0.01
  1079. </li>
  1080. <li>
  1081. <i>threshold &lt;0.16,0.16,0.16&gt;</i><br>
  1082. adjust threshold of each color separately (comma separated) (R,G,B)<br>
  1083. values from 0.00 to 1.00 in steps of 0.01
  1084. </li>
  1085. <li>
  1086. <i>toggle</i><br>
  1087. toggles the light between on and off
  1088. </li>
  1089. <li>
  1090. <i>toggleMode</i><br>
  1091. toggles through all modes
  1092. </li>
  1093. <li>
  1094. <i>valueGain &lt;1.70&gt;</i><br>
  1095. adjust valueGain<br>
  1096. values from 0.00 to 5.00 in steps of 0.01
  1097. </li>
  1098. <li>
  1099. <i>whitelevel &lt;0.70,0.80,0.90&gt;</i><br>
  1100. adjust whitelevel of each color separately (comma separated) (R,G,B)<br>
  1101. values from 0.00 to 1.00 in steps of 0.01
  1102. </li>
  1103. </ul>
  1104. <br>
  1105. <a name="Hyperion_get"></a>
  1106. <p><b>Get</b></p>
  1107. <ul>
  1108. <li>
  1109. <i>configFiles</i><br>
  1110. get the available config files in directory from attribute hyperionConfigDir<br>
  1111. Will only work properly if at least two config files are found. File names must have no spaces and must end with .config.json .
  1112. </li>
  1113. <li>
  1114. <i>devStateIcon</i><br>
  1115. get the current devStateIcon
  1116. </li>
  1117. <li>
  1118. <i>statusRequest</i><br>
  1119. get the state of the Hyperion server,<br>
  1120. get also the internals of Hyperion including available effects
  1121. </li>
  1122. </ul>
  1123. <br>
  1124. <a name="Hyperion_attr"></a>
  1125. <p><b>Attributes</b></p>
  1126. <ul>
  1127. <li>
  1128. <i>disable</i><br>
  1129. stop polling and disconnect<br>
  1130. default: 0
  1131. </li>
  1132. <li>
  1133. <i>hyperionBin</i><br>
  1134. path to the hyperion daemon<br>
  1135. OpenELEC users may set hyperiond.sh as daemon<br>
  1136. default: /usr/bin/hyperiond
  1137. </li>
  1138. <li>
  1139. <i>hyperionConfigDir</i><br>
  1140. path to the hyperion configuration files<br>
  1141. default: /etc/hyperion/
  1142. </li>
  1143. <li>
  1144. <i>hyperionCustomEffects</i><br>
  1145. space separated list of JSON strings (without spaces - please replace spaces in effect names with underlines)<br>
  1146. must include name (as diplay name), oname (name of the base effect) and args (the different effect args), only this order is allowed (if different an error will be thrown on attribute save and the attribut value will not be saved).<br>
  1147. example: {"name":"Knight_Rider_speed_2","oname":"Knight_rider","args":{"color":[255,0,255],"speed":2}} {"name":"Knight_Rider_speed_4","oname":"Knight_rider","args":{"color":[0,0,255],"speed":4}}
  1148. </li>
  1149. <li>
  1150. <i>hyperionDefaultDuration</i><br>
  1151. default duration<br>
  1152. default: 0 = infinity
  1153. </li>
  1154. <li>
  1155. <i>hyperionDefaultPriority</i><br>
  1156. default priority<br>
  1157. default: 0 = highest priority
  1158. </li>
  1159. <li>
  1160. <i>hyperionDimStep</i><br>
  1161. dim step for dimDown/dimUp<br>
  1162. default: 10 (percent)
  1163. </li>
  1164. <li>
  1165. <i>hyperionGainStep</i><br>
  1166. valueGain step for valueGainDown/valueGainUp<br>
  1167. default: 0.1
  1168. </li>
  1169. <li>
  1170. <i>hyperionNoSudo</i><br>
  1171. disable sudo for non-root ssh user<br>
  1172. default: 0
  1173. </li>
  1174. <li>
  1175. <i>hyperionSshUser</i><br>
  1176. user name for executing SSH commands<br>
  1177. default: pi
  1178. </li>
  1179. <li>
  1180. <i>hyperionToggleModes</i><br>
  1181. modes and order of toggleMode as comma separated list (min. 2 modes, max. 4 modes, each mode only once)<br>
  1182. default: clearall,rgb,effect,off
  1183. </li>
  1184. <li>
  1185. <i>hyperionVersionCheck</i><br>
  1186. disable hyperion version check to (maybe) support prior versions<br>
  1187. DO THIS AT YOUR OWN RISK! FHEM MAY CRASH UNEXPECTEDLY!<br>
  1188. default: 1
  1189. </li>
  1190. <li>
  1191. <i>queryAfterSet</i><br>
  1192. If set to 0 the state of the Hyperion server will not be queried after setting, instead the state will be queried on next interval query.<br>
  1193. This is only used if periodically polling is enabled, without this polling the state will be queried automatically after set.<br>
  1194. default: 1
  1195. </li>
  1196. </ul>
  1197. <br>
  1198. <a name="Hyperion_read"></a>
  1199. <p><b>Readings</b></p>
  1200. <ul>
  1201. <li>
  1202. <i>adjustBlue</i><br>
  1203. each color of blue separately (comma separated) (R,G,B)
  1204. </li>
  1205. <li>
  1206. <i>adjustGreen</i><br>
  1207. each color of green separately (comma separated) (R,G,B)
  1208. </li>
  1209. <li>
  1210. <i>adjustRed</i><br>
  1211. each color of red separately (comma separated) (R,G,B)
  1212. </li>
  1213. <li>
  1214. <i>blacklevel</i><br>
  1215. blacklevel of each color separately (comma separated) (R,G,B)
  1216. </li>
  1217. <li>
  1218. <i>colorTemperature</i><br>
  1219. temperature of each color separately (comma separated) (R,G,B)
  1220. </li>
  1221. <li>
  1222. <i>configFile</i><br>
  1223. active/previously loaded configuration file, double extension (.config.json) will be omitted
  1224. </li>
  1225. <li>
  1226. <i>correction</i><br>
  1227. correction of each color separately (comma separated) (R,G,B)
  1228. </li>
  1229. <li>
  1230. <i>dim</i><br>
  1231. active/previous dim value (rgb light)
  1232. </li>
  1233. <li>
  1234. <i>duration</i><br>
  1235. active/previous/remaining primary duration in seconds or infinite
  1236. </li>
  1237. <li>
  1238. <i>effect</i><br>
  1239. active/previous effect
  1240. </li>
  1241. <li>
  1242. <i>effectArgs</i><br>
  1243. active/previous effect arguments as JSON
  1244. </li>
  1245. <li>
  1246. <i>gamma</i><br>
  1247. gamma for each color separately (comma separated) (R,G,B)
  1248. </li>
  1249. <li>
  1250. <i>id</i><br>
  1251. id of the Hyperion server
  1252. </li>
  1253. <li>
  1254. <i>lastError</i><br>
  1255. last occured error while communicating with the Hyperion server
  1256. </li>
  1257. <li>
  1258. <i>luminanceGain</i><br>
  1259. current luminanceGain
  1260. </li>
  1261. <li>
  1262. <i>luminanceMinimum</i><br>
  1263. current luminanceMinimum
  1264. </li>
  1265. <li>
  1266. <i>mode</i><br>
  1267. current mode
  1268. </li>
  1269. <li>
  1270. <i>mode_before_off</i><br>
  1271. previous mode before off
  1272. </li>
  1273. <li>
  1274. <i>priority</i><br>
  1275. active/previous priority
  1276. </li>
  1277. <li>
  1278. <i>rgb</i><br>
  1279. active/previous rgb
  1280. </li>
  1281. <li>
  1282. <i>saturationGain</i><br>
  1283. active saturationGain
  1284. </li>
  1285. <li>
  1286. <i>saturationLGain</i><br>
  1287. active saturationLGain
  1288. </li>
  1289. <li>
  1290. <i>serverResponse</i><br>
  1291. last Hyperion server response (success/ERROR)
  1292. </li>
  1293. <li>
  1294. <i>state</i><br>
  1295. current state
  1296. </li>
  1297. <li>
  1298. <i>threshold</i><br>
  1299. threshold of each color separately (comma separated) (R,G,B)
  1300. </li>
  1301. <li>
  1302. <i>valueGain</i><br>
  1303. valueGain - gain of the Ambilight
  1304. </li>
  1305. <li>
  1306. <i>whitelevel</i><br>
  1307. whitelevel of each color separately (comma separated) (R,G,B)
  1308. </li>
  1309. </ul>
  1310. </ul>
  1311. =end html
  1312. =begin html_DE
  1313. <a name="Hyperion"></a>
  1314. <h3>Hyperion</h3>
  1315. <ul>
  1316. Mit <i>Hyperion</i> ist es m&ouml;glich auf einem Hyperion Server die Farbe oder den Effekt einzustellen.<br>
  1317. Es ist auch m&ouml;glich eine komplette Farbkalibrierung vorzunehmen (&Auml;nderungen sind tempor&auml;r und werden nicht in die Konfigurationsdatei geschrieben).<br>
  1318. Der Hyperion Server muss dem JSON Server aktiviert haben.<br>
  1319. Es ist auch m&ouml;glich Hyperion mit verschiedenen Konfigurationsdateien zu starten (z.B. mit anderem Eingang/Grabber)<br>
  1320. <br>
  1321. <a name="Hyperion_define"></a>
  1322. <p><b>Define</b></p>
  1323. <ul>
  1324. <code>define &lt;name&gt; Hyperion &lt;IP oder HOSTNAME&gt; &lt;PORT&gt; [&lt;INTERVAL&gt;]</code><br>
  1325. </ul>
  1326. <br>
  1327. &lt;INTERVAL&gt; ist optional f&uuml;r automatisches Abfragen.<br>
  1328. <br>
  1329. <i>Nach dem Definieren des Ger&auml;tes wird einmalig und automatisch "get &lt;name&gt; statusRequest" aufgerufen um den aktuellen Status und die verf&uuml;gbaren Effekte vom Hyperion Server zu holen.</i><br>
  1330. <br>
  1331. Beispiel f&uuml;r Hyperion auf dem lokalen System:
  1332. <br><br>
  1333. <ul>
  1334. <code>define Ambilight Hyperion localhost 19444 10</code><br>
  1335. </ul>
  1336. <br>
  1337. Beispiel f&uuml;r Hyperion auf einem entfernten System:
  1338. <br><br>
  1339. <ul>
  1340. <code>define Ambilight Hyperion 192.168.1.4 19444 10</code><br>
  1341. </ul>
  1342. <br>
  1343. <a name="Hyperion_set"></a>
  1344. <p><b>set &lt;ben&ouml;tigt&gt; [optional]</b></p>
  1345. <ul>
  1346. <li>
  1347. <i>addEffect &lt;eigener_name&gt;</i><br>
  1348. f&uuml;gt den aktuellen Effekt mit dem &uuml;bergebenen Namen den eigenen Effekten hinzu<br>
  1349. kann nachtr&auml;glich im Attribut hyperionCustomEffects ge&auml;ndert werden<br>
  1350. Ger&auml;t muss dazu im Effekt Modus in einen nicht-eigenen Effekt sein und der &uuml;bergebene Name muss ein einmaliger Effektname sein
  1351. </li>
  1352. <li>
  1353. <i>adjustBlue &lt;0,0,255&gt;</i><br>
  1354. Justiert jede Farbe von Blau separat (Komma separiert) (R,G,B)<br>
  1355. Werte von 0 bis 255 in Schritten von 1
  1356. </li>
  1357. <li>
  1358. <i>adjustGreen &lt;0,255,0&gt;</i><br>
  1359. Justiere jede Farbe von Gr&uuml;n separat (Komma separiert) (R,G,B)<br>
  1360. Werte von 0 bis 255 in Schritten von 1
  1361. </li>
  1362. <li>
  1363. <i>adjustRed &lt;255,0,0&gt;</i><br>
  1364. Justiert jede Farbe von Rot separat (Komma separiert) (R,G,B)<br>
  1365. Werte von 0 bis 255 in Schritten von 1
  1366. </li>
  1367. <li>
  1368. <i>blacklevel &lt;0.00,0.00,0.00&gt;</i><br>
  1369. Justiert den Schwarzwert von jeder Farbe separat (Komma separiert) (R,G,B)<br>
  1370. Werte von 0.00 bis 1.00 in Schritten von 0.01
  1371. </li>
  1372. <li>
  1373. <i>clear &lt;1000&gt;</i><br>
  1374. einen bestimmten Priorit&auml;tskanal l&ouml;schen
  1375. </li>
  1376. <li>
  1377. <i>clearall</i><br>
  1378. alle Priorit&auml;tskan&auml;le l&ouml;schen / Umschaltung auf Ambilight
  1379. </li>
  1380. <li>
  1381. <i>colorTemperature &lt;255,255,255&gt;</i><br>
  1382. Justiert die Temperatur von jeder Farbe separat (Komma separiert) (R,G,B)<br>
  1383. Werte von 0 bis 255 in Schritten von 1
  1384. </li>
  1385. <li>
  1386. <i>configFile &lt;Dateiname&gt;</i><br>
  1387. Neustart des Hyperion Servers mit der angegebenen Konfigurationsdatei (Dateien werden automatisch aufgelistet aus Verzeichnis welches im Attribut hyperionConfigDir angegeben ist)<br>
  1388. Bitte die doppelte Endung weglassen (.config.json)<br>
  1389. Nur verf&uuml;gbar nach erfolgreichem "get &lt;name&gt; configFiles"
  1390. </li>
  1391. <li>
  1392. <i>correction &lt;255,255,255&gt;</i><br>
  1393. Justiert die Korrektur von jeder Farbe separat (Komma separiert) (R,G,B)<br>
  1394. Werte von 0 bis 255 in Schritten von 1
  1395. </li>
  1396. <li>
  1397. <i>dim &lt;Prozent&gt; [Dauer] [Priorit&auml;t]</i><br>
  1398. Dimmt das RGB Licht auf angegebenen Prozentwert, mit optionaler Dauer in Sekunden und optionaler Priorit&auml;t
  1399. </li>
  1400. <li>
  1401. <i>dimDown [delta]</i><br>
  1402. Abdunkeln des RGB Lichts um angegebenen Prozentwert oder um Prozentwert der im Attribut hyperionDimStep eingestellt ist (Voreinstellung: 10)
  1403. </li>
  1404. <li>
  1405. <i>dimUp [delta]</i><br>
  1406. Aufhellen des RGB Lichts um angegebenen Prozentwert oder um Prozentwert der im Attribut hyperionDimStep eingestellt ist (Voreinstellung: 10)
  1407. </li>
  1408. <li>
  1409. <i>effect &lt;effect&gt; [Dauer] [Priorit&auml;t] [effectargs]</i><br>
  1410. Stellt gew&auml;hlten Effekt ein (ersetzte Leerzeichen mit Unterstrichen) mit optionaler Dauer in Sekunden und optionaler Priorit&auml;t<br>
  1411. effectargs k&ouml;nnen ebenfalls &uuml;bermittelt werden - muss ein JSON String ohne Leerzeichen sein
  1412. </li>
  1413. <li>
  1414. <i>gamma &lt;1.90,1.90,1.90&gt;</i><br>
  1415. Justiert Gamma von jeder Farbe separat (Komma separiert) (R,G,B)<br>
  1416. Werte von 0.00 bis 5.00 in Schritten von 0.01
  1417. </li>
  1418. <li>
  1419. <i>luminanceGain &lt;1.00&gt;</i><br>
  1420. Justiert Helligkeit<br>
  1421. Werte von 0.00 bis 5.00 in Schritten von 0.01
  1422. </li>
  1423. <li>
  1424. <i>luminanceMinimum &lt;0.00&gt;</i><br>
  1425. Justiert Hintergrundbeleuchtung<br>
  1426. Werte von 0.00 bis 5.00 in Schritten von 0.01
  1427. </li>
  1428. <li>
  1429. <i>mode &lt;clearall|effect|off|rgb&gt;</i><br>
  1430. Setzt das Licht im gew&auml;hlten Modus mit dem zuletzt f&uuml;r diesen Modus eingestellten Wert
  1431. </li>
  1432. <li>
  1433. <i>off</i><br>
  1434. Schaltet aus mit Farbe schwarz
  1435. </li>
  1436. <li>
  1437. <i>on</i><br>
  1438. Schaltet mit letztem Modus und letztem Wert ein
  1439. </li>
  1440. <li>
  1441. <i>rgb &lt;RRGGBB&gt; [Dauer] [Priorit&auml;t]</i><br>
  1442. Setzt Farbe im RGB Hex Format mit optionaler Dauer in Sekunden und optionaler Priorit&auml;t
  1443. </li>
  1444. <li>
  1445. <i>saturationGain &lt;1.10&gt;</i><br>
  1446. Justiert S&auml;ttigung<br>
  1447. Werte von 0.00 bis 5.00 in Schritten von 0.01
  1448. </li>
  1449. <li>
  1450. <i>saturationLGain &lt;1.00&gt;</i><br>
  1451. Justiert minimale S&auml;ttigung<br>
  1452. Werte von 0.00 bis 5.00 in Schritten von 0.01
  1453. </li>
  1454. <li>
  1455. <i>threshold &lt;0.16,0.16,0.16&gt;</i><br>
  1456. Justiert den Schwellenwert von jeder Farbe separat (Komma separiert) (R,G,B)<br>
  1457. Werte von 0.00 bis 1.00 in Schritten von 0.01
  1458. </li>
  1459. <li>
  1460. <i>toggle</i><br>
  1461. Schaltet zwischen an und aus hin und her
  1462. </li>
  1463. <li>
  1464. <i>toggleMode</i><br>
  1465. Schaltet alle Modi durch
  1466. </li>
  1467. <li>
  1468. <i>valueGain &lt;1.70&gt;</i><br>
  1469. Justiert Helligkeit vom Ambilight<br>
  1470. Werte von 0.00 bis 5.00 in Schritten von 0.01
  1471. </li>
  1472. <li>
  1473. <i>whitelevel &lt;0.70,0.80,0.90&gt;</i><br>
  1474. Justiert den Wei&szlig;wert von jeder Farbe separat (Komma separiert) (R,G,B)<br>
  1475. Werte von 0.00 bis 1.00 in Schritten von 0.01
  1476. </li>
  1477. </ul>
  1478. <br>
  1479. <a name="Hyperion_get"></a>
  1480. <p><b>Get</b></p>
  1481. <ul>
  1482. <li>
  1483. <i>configFiles</i><br>
  1484. Holt die verf&uuml;gbaren Konfigurationsdateien aus dem Verzeichnis vom Attribut hyperionConfigDir<br>
  1485. Es m&uuml;ssen mindestens zwei Konfigurationsdateien im Verzeichnis vorhanden sein. Die Dateien d&uuml;rfen keine Leerzeichen enthalten und m&uuml;ssen mit .config.json enden!
  1486. </li>
  1487. <li>
  1488. <i>devStateIcon</i><br>
  1489. Zeigt den Wert des aktuellen devStateIcon
  1490. </li>
  1491. <li>
  1492. <i>statusRequest</i><br>
  1493. Holt den aktuellen Status vom Hyperion Server,<br>
  1494. holt auch die Internals vom Hyperion Server inklusive verf&uuml;gbarer Effekte
  1495. </li>
  1496. </ul>
  1497. <br>
  1498. <a name="Hyperion_attr"></a>
  1499. <p><b>Attribute</b></p>
  1500. <ul>
  1501. <li>
  1502. <i>disable</i><br>
  1503. Abfragen beenden und Verbindung trennen<br>
  1504. Voreinstellung: 0
  1505. </li>
  1506. <li>
  1507. <i>hyperionBin</i><br>
  1508. Pfad zum Hyperion Daemon<br>
  1509. OpenELEC Benutzer m&uuml;ssen eventuell hyperiond.sh als Daemon einstellen<br>
  1510. Voreinstellung: /usr/bin/hyperiond
  1511. </li>
  1512. <li>
  1513. <i>hyperionConfigDir</i><br>
  1514. Pfad zu den Hyperion Konfigurationsdateien<br>
  1515. Voreinstellung: /etc/hyperion/
  1516. </li>
  1517. <li>
  1518. <i>hyperionCustomEffects</i><br>
  1519. Leerzeichen separierte Liste von JSON Strings (ohne Leerzeichen - bitte Leerzeichen in Effektnamen durch Unterstriche ersetzen)<br>
  1520. muss name (als Anzeigename), oname (Name des basierenden Effekts) und args (die eigentlichen unterschiedlichen Effekt Argumente) beinhalten (auch genau in dieser Reihenfolge, sonst kommt beim &Uuml;bernehmen des Attributs ein Fehler und das Attribut wird nicht gespeichert)<br>
  1521. Beispiel: {"name":"Knight_Rider_speed_2","oname":"Knight_rider","args":{"color":[255,0,255],"speed":2}} {"name":"Knight_Rider_speed_4","oname":"Knight_rider","args":{"color":[0,0,255],"speed":4}}
  1522. </li>
  1523. <li>
  1524. <i>hyperionDefaultDuration</i><br>
  1525. Voreinstellung f&uuml;r Dauer<br>
  1526. Voreinstellung: 0 = unendlich
  1527. </li>
  1528. <li>
  1529. <i>hyperionDefaultPriority</i><br>
  1530. Voreinstellung f&uuml;r Priorit&auml;t<br>
  1531. Voreinstellung: 0 = h&ouml;chste Priorit&auml;t
  1532. </li>
  1533. <li>
  1534. <i>hyperionDimStep</i><br>
  1535. Dimmstufen f&uuml;r dimDown/dimUp<br>
  1536. Voreinstellung: 10 (Prozent)
  1537. </li>
  1538. <li>
  1539. <i>hyperionGainStep</i><br>
  1540. valueGain Dimmstufen f&uuml;r valueGainDown/valueGainUp<br>
  1541. Voreinstellung: 0.1
  1542. </li>
  1543. <li>
  1544. <i>hyperionNoSudo</i><br>
  1545. Deaktiviert sudo f&uuml;r nicht root SSH Benutzer<br>
  1546. Voreinstellung: 0
  1547. </li>
  1548. <li>
  1549. <i>hyperionSshUser</i><br>
  1550. Benutzername mit dem SSH Befehle ausgef&uuml;hrt werden sollen<br>
  1551. Voreinstellung: pi
  1552. </li>
  1553. <li>
  1554. <i>hyperionToggleModes</i><br>
  1555. Modi und Reihenfolge von toggleMode als kommaseparierte Liste (min. 2 Werte, max. 4 Werte, jeder Mode nur 1x)<br>
  1556. Voreinstellung: clearall,rgb,effect,off
  1557. </li>
  1558. <li>
  1559. <i>hyperionVersionCheck</i><br>
  1560. Deaktiviert Hyperion Version&uuml;berpr&uuml;fung um (eventuell) &auml;ltere Hyperion Versionen zu unterst&uuml;tzen<br>
  1561. DAS GESCHIEHT AUF EIGENE VERANTWORTUNG! FHEM K&Ouml;NNTE UNERWARTET ABST&Uuml;RTZEN!<br>
  1562. Voreinstellung: 1
  1563. </li>
  1564. <li>
  1565. <i>queryAfterSet</i><br>
  1566. Wenn gesetzt auf 0 wird der Status des Hyperion Server nach einem set Befehl nicht abgerufen, stattdessen wird der Status zum n&auml;chsten eingestellten Interval abgerufen.<br>
  1567. Das wird nur verwendet wenn das priodische Abfragen aktiviert ist, ohne dieses Abfragen wird der Status automatisch nach dem set Befehl abgerufen.<br>
  1568. Voreinstellung: 1
  1569. </li>
  1570. </ul>
  1571. <br>
  1572. <a name="Hyperion_read"></a>
  1573. <p><b>Readings</b></p>
  1574. <ul>
  1575. <li>
  1576. <i>adjustBlue</i><br>
  1577. jede Farbe von Blau separat (Komma separiert) (R,G,B)
  1578. </li>
  1579. <li>
  1580. <i>adjustGreen</i><br>
  1581. jede Farbe von Gr&uuml;n separat (Komma separiert) (R,G,B)
  1582. </li>
  1583. <li>
  1584. <i>adjustRed</i><br>
  1585. jede Farbe von Rot separat (Komma separiert) (R,G,B)
  1586. </li>
  1587. <li>
  1588. <i>blacklevel</i><br>
  1589. Schwarzwert von jeder Farbe separat (Komma separiert) (R,G,B)
  1590. </li>
  1591. <li>
  1592. <i>colorTemperature</i><br>
  1593. Temperatur von jeder Farbe separat (Komma separiert) (R,G,B)
  1594. </li>
  1595. <li>
  1596. <i>configFile</i><br>
  1597. aktive/zuletzt geladene Konfigurationsdatei, doppelte Endung (.config.json) wird weggelassen
  1598. </li>
  1599. <li>
  1600. <i>correction</i><br>
  1601. Korrektur von jeder Farbe separat (Komma separiert) (R,G,B)
  1602. </li>
  1603. <li>
  1604. <i>dim</i><br>
  1605. aktive/letzte Dimmstufe (RGB Licht)
  1606. </li>
  1607. <li>
  1608. <i>duration</i><br>
  1609. aktive/letzte/verbleibende prim&auml;re Dauer in Sekunden oder infinite f&uuml;r unendlich
  1610. </li>
  1611. <li>
  1612. <i>effect</i><br>
  1613. aktiver/letzter Effekt
  1614. </li>
  1615. <li>
  1616. <i>effectArgs</i><br>
  1617. aktive/letzte Effekt Argumente als JSON
  1618. </li>
  1619. <li>
  1620. <i>gamma</i><br>
  1621. Gamma von jeder Farbe separat (Komma separiert) (R,G,B)
  1622. </li>
  1623. <li>
  1624. <i>id</i><br>
  1625. ID vom Hyperion Server
  1626. </li>
  1627. <li>
  1628. <i>lastError</i><br>
  1629. letzter aufgetretener Fehler w&auml;hrend der Kommunikation mit dem Hyperion Server
  1630. </li>
  1631. <li>
  1632. <i>luminanceGain</i><br>
  1633. aktive Helligkeit
  1634. </li>
  1635. <li>
  1636. <i>luminanceMinimum</i><br>
  1637. aktive Hintergrundbeleuchtung
  1638. </li>
  1639. <li>
  1640. <i>mode</i><br>
  1641. aktiver Modus
  1642. </li>
  1643. <li>
  1644. <i>mode_before_off</i><br>
  1645. letzter Modus vor aus
  1646. </li>
  1647. <li>
  1648. <i>priority</i><br>
  1649. aktive/letzte Priorit&auml;t
  1650. </li>
  1651. <li>
  1652. <i>rgb</i><br>
  1653. aktive/letzte RGB Farbe
  1654. </li>
  1655. <li>
  1656. <i>saturationGain</i><br>
  1657. aktive S&auml;ttigung
  1658. </li>
  1659. <li>
  1660. <i>saturationLGain</i><br>
  1661. aktive minimale S&auml;ttigung
  1662. </li>
  1663. <li>
  1664. <i>serverResponse</i><br>
  1665. letzte Hyperion Server Antwort (success/ERROR)
  1666. </li>
  1667. <li>
  1668. <i>state</i><br>
  1669. aktiver Status
  1670. </li>
  1671. <li>
  1672. <i>threshold</i><br>
  1673. Schwellenwert von jeder Farbe separat (Komma separiert) (R,G,B)
  1674. </li>
  1675. <li>
  1676. <i>valueGain</i><br>
  1677. aktive Helligkeit vom Ambilight
  1678. </li>
  1679. <li>
  1680. <i>whitelevel</i><br>
  1681. Wei&szlig;wert von jeder Farbe separat (Komma separiert) (R,G,B)
  1682. </li>
  1683. </ul>
  1684. </ul>
  1685. =end html_DE
  1686. =cut