mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@12060 2b470e98-0d58-463d-a4d8-8e2adae1ed80
1137 lines
41 KiB
Perl
1137 lines
41 KiB
Perl
#####################################################################################
|
|
# $Id$
|
|
#
|
|
# Usage
|
|
#
|
|
# define <name> Hyperion <IP or HOSTNAME> <PORT> <INTERVAL>
|
|
#
|
|
#####################################################################################
|
|
|
|
package main;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Color;
|
|
|
|
use JSON;
|
|
use SetExtensions;
|
|
|
|
sub Hyperion_Call($$$){};
|
|
|
|
my %Hyperion_sets =
|
|
(
|
|
"adjustRed" => "textField",
|
|
"adjustGreen" => "textField",
|
|
"adjustBlue" => "textField",
|
|
"blacklevel" => "textField",
|
|
"colorTemperature" => "textField",
|
|
"dim" => "slider,0,1,100",
|
|
"dimDown" => "noArg",
|
|
"dimUp" => "noArg",
|
|
"correction" => "textField",
|
|
"clear" => "textField",
|
|
"clearall" => "noArg",
|
|
"gamma" => "textField",
|
|
"luminanceGain" => "slider,0,0.010,1.999,1",
|
|
"luminanceMinimum" => "slider,0,0.010,1.999,1",
|
|
"mode" => "clearall,effect,off,rgb",
|
|
"off" => "noArg",
|
|
"on" => "noArg",
|
|
"rgb" => "colorpicker,RGB",
|
|
"saturationGain" => "slider,0,0.010,1.999,1",
|
|
"saturationLGain" => "slider,0,0.010,1.999,1",
|
|
"threshold" => "textField",
|
|
"toggle" => "noArg",
|
|
"valueGain" => "slider,0,0.010,1.999,1",
|
|
"whitelevel" => "textField"
|
|
);
|
|
|
|
my $Hyperion_webCmd = "rgb:effect:mode:toggle:on:off";
|
|
my $Hyperion_webCmd_config = "rgb:effect:configFile:mode:toggle:on:off";
|
|
|
|
my $Hyperion_homebridgeMapping = "On=state,subtype=TV.Licht,valueOn=/rgb.*/,cmdOff=off,cmdOn=mode+rgb ".
|
|
"On=state,subtype=Umgebungslicht,valueOn=clearall,cmdOff=off,cmdOn=clearall ".
|
|
"On=state,subtype=Effekt,valueOn=/effect.*/,cmdOff=off,cmdOn=mode+effect ";
|
|
# "On=state,subtype=Knight.Rider,valueOn=/.*Knight_rider/,cmdOff=off,cmdOn=effect+Knight_rider " .
|
|
# "On=configFile,subtype=Eingang.HDMI,valueOn=hyperion-hdmi,cmdOff=configFile+hyperion,cmdOn=configFile+hyperion-hdmi ";
|
|
|
|
sub Hyperion_Initialize($)
|
|
{
|
|
my ($hash) = @_;
|
|
$hash->{AttrFn} = "Hyperion_Attr";
|
|
$hash->{DefFn} = "Hyperion_Define";
|
|
$hash->{GetFn} = "Hyperion_Get";
|
|
$hash->{SetFn} = "Hyperion_Set";
|
|
$hash->{UndefFn} = "Hyperion_Undef";
|
|
$hash->{AttrList} = "disable:1 ".
|
|
"hyperionBin ".
|
|
"hyperionConfigDir ".
|
|
"hyperionDefaultDuration ".
|
|
"hyperionDefaultPriority ".
|
|
"hyperionDimStep ".
|
|
"hyperionNoSudo:1 ".
|
|
"hyperionSshUser ".
|
|
"queryAfterSet:0 ".
|
|
$readingFnAttributes;
|
|
FHEM_colorpickerInit();
|
|
}
|
|
|
|
sub Hyperion_Define($$)
|
|
{
|
|
my ($hash,$def) = @_;
|
|
my @args = split("[ \t]+",$def);
|
|
return "Usage: define <name> Hyperion <IP> <PORT> [<INTERVAL>]" if (@args < 4);
|
|
my ($name,$type,$host,$port,$interval) = @args;
|
|
if (defined($interval))
|
|
{
|
|
$hash->{INTERVAL} = $interval;
|
|
}
|
|
else
|
|
{
|
|
delete $hash->{INTERVAL};
|
|
}
|
|
$hash->{STATE} = "Initialized";
|
|
$hash->{IP} = $host;
|
|
$hash->{PORT} = $port;
|
|
$hash->{helper}{sets} = join(" ",map {"$_:$Hyperion_sets{$_}"} keys %Hyperion_sets);
|
|
$interval = undef unless defined($interval);
|
|
$interval = 5 if ($interval < 5);
|
|
RemoveInternalTimer($hash);
|
|
if ($init_done)
|
|
{
|
|
Hyperion_GetUpdate($hash);
|
|
}
|
|
else
|
|
{
|
|
InternalTimer(gettimeofday() + $interval,"Hyperion_GetUpdate",$hash,0);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub Hyperion_Undef($$)
|
|
{
|
|
my ($hash,$name) = @_;
|
|
RemoveInternalTimer($hash);
|
|
return undef;
|
|
}
|
|
|
|
sub Hyperion_list2array($$)
|
|
{
|
|
my ($list,$round) = @_;
|
|
my @arr;
|
|
foreach my $part (split(",",$list))
|
|
{
|
|
$part = sprintf($round,$part) * 1;
|
|
push @arr,$part;
|
|
}
|
|
return \@arr;
|
|
}
|
|
|
|
sub Hyperion_isLocal($)
|
|
{
|
|
my ($hash) = @_;
|
|
my $ip = $hash->{IP};
|
|
return 1 if ($ip eq "localhost" || $ip eq "127.0.0.1");
|
|
return undef;
|
|
}
|
|
|
|
sub Hyperion_Get($@)
|
|
{
|
|
my ($hash,$name,$cmd) = @_;
|
|
my $params = "configFiles:noArg devStateIcon:noArg statusRequest:noArg";
|
|
return "get $name needs one parameter: $params" if (!defined($cmd));
|
|
|
|
if ($cmd eq "configFiles")
|
|
{
|
|
Hyperion_GetConfigs($hash);
|
|
}
|
|
elsif ($cmd eq "devStateIcon")
|
|
{
|
|
return Hyperion_devStateIcon($hash);
|
|
}
|
|
elsif ($cmd eq "statusRequest")
|
|
{
|
|
Hyperion_Call($hash,$cmd,undef);
|
|
}
|
|
else
|
|
{
|
|
return "Unknown argument $cmd for $name, choose one of $params";
|
|
}
|
|
}
|
|
|
|
sub Hyperion_GetHttpResponse($$$)
|
|
{
|
|
my ($hash,$cmd,$data) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $host = $hash->{IP};
|
|
my $port = $hash->{PORT};
|
|
my $url = "http://$host:$port/";
|
|
my $param = {
|
|
url => $url,
|
|
data => "$data\n",
|
|
# noshutdown => 0,
|
|
loglevel => 3,
|
|
cmd => $cmd,
|
|
# keepalive => 1,
|
|
# header => "",
|
|
hash => $hash,
|
|
# path => "",
|
|
callback => \&Hyperion_ParseHttpResponse
|
|
};
|
|
|
|
# HttpUtils_NonblockingGet($param);
|
|
|
|
Log3 $name,5,"$name: sending data: $data";
|
|
|
|
readingsBeginUpdate($hash);
|
|
|
|
my $conn = IO::Socket::INET->new(PeerAddr=>"$host:$port",Timeout=>4);
|
|
|
|
if (!$conn)
|
|
{
|
|
my $error = "Can't connect to http://$host:$port";
|
|
readingsBulkUpdate($hash,"state","ERROR") if (Value($name) ne "ERROR");
|
|
readingsBulkUpdate($hash,"serverResponse","ERROR: $error");
|
|
readingsBulkUpdate($hash,"lastError",$error) if (ReadingsVal($name,"lastError","") ne $error);
|
|
undef $conn;
|
|
return undef;
|
|
}
|
|
|
|
syswrite $conn,"$data\n";
|
|
my $ret = <$conn>;
|
|
$ret =~ s/\s+$//;
|
|
shutdown $conn,1 if (!defined($param->{noshutdown}));
|
|
Log3 $name,5,"$name: Hyperion_GetHttpResponse returned data: $ret";
|
|
|
|
if ($ret eq '{"success":true}')
|
|
{
|
|
my $obj = from_json($data);
|
|
my $dur = (defined($obj->{duration})) ? $obj->{duration} / 1000 : "infinite";
|
|
readingsBulkUpdate($hash,"duration",$dur) if (ReadingsVal($name,"duration","infinite") ne $dur);
|
|
readingsBulkUpdate($hash,"priority",$obj->{priority}) if (defined($obj->{priority}) && $obj->{priority} > -1 && ReadingsVal($name,"priority",0) != $obj->{priority});
|
|
fhem ("sleep 1; get $name statusRequest") if (AttrVal($name,"queryAfterSet",1) == 1 || !defined($hash->{INTERVAL}));
|
|
return undef;
|
|
}
|
|
elsif ($ret ne '"success":false')
|
|
{
|
|
Hyperion_ParseHttpResponse($param,undef,$ret);
|
|
}
|
|
else
|
|
{
|
|
Hyperion_ParseHttpResponse($param,$ret,$ret);
|
|
}
|
|
readingsEndUpdate($hash,1);
|
|
}
|
|
|
|
sub Hyperion_ParseHttpResponse($$$)
|
|
{
|
|
my ($param,$err,$result) = @_;
|
|
my $hash = $param->{hash};
|
|
my $name = $hash->{NAME};
|
|
my %Hyperion_sets_local = %Hyperion_sets;
|
|
Log3 $name,5,"$name: url ".$param->{url}." returned: $result";
|
|
if (!defined($err))
|
|
{
|
|
my $obj = eval { from_json($result) };
|
|
my $data = $obj->{info};
|
|
|
|
|
|
###### BETA Phase
|
|
# delete old reading temperature
|
|
fhem("deletereading $name temperature") if (defined(ReadingsVal($name,"temperature",undef)));
|
|
# delete old reading config
|
|
fhem("deletereading $name config") if (defined(ReadingsVal($name,"config",undef)));
|
|
#################
|
|
|
|
|
|
my $prio = ($data->{priorities}->[0]->{priority}) ? $data->{priorities}->[0]->{priority} : undef;
|
|
my $adj = $data->{adjustment}->[0];
|
|
my $col = $data->{activeLedColor}->[0]->{'HEX Value'}->[0];
|
|
my $configs = ReadingsVal($name,".configs",undef);
|
|
my $corr = $data->{correction}->[0];
|
|
my $effects = $data->{effects};
|
|
my $effectList = join(",",map {"$_->{name}"} @{$effects});
|
|
$effectList =~ s/ /_/g;
|
|
my $script = $data->{activeEffects}->[0]->{script};
|
|
my $temp = $data->{temperature}->[0];
|
|
my $trans = $data->{transform}->[0];
|
|
my $id = $trans->{id};
|
|
my $adjR = join(",",@{$adj->{redAdjust}});
|
|
my $adjG = join(",",@{$adj->{greenAdjust}});
|
|
my $adjB = join(",",@{$adj->{blueAdjust}});
|
|
my $corS = join(",",@{$corr->{correctionValues}});
|
|
my $temP = join(",",@{$temp->{correctionValues}});
|
|
my $blkL = sprintf("%.3f",$trans->{blacklevel}->[0]).",".sprintf("%.3f",$trans->{blacklevel}->[1]).",".sprintf("%.3f",$trans->{blacklevel}->[2]);
|
|
my $gamM = sprintf("%.3f",$trans->{gamma}->[0]).",".sprintf("%.3f",$trans->{gamma}->[1]).",".sprintf("%.3f",$trans->{gamma}->[2]);
|
|
my $thrE = sprintf("%.3f",$trans->{threshold}->[0]).",".sprintf("%.3f",$trans->{threshold}->[1]).",".sprintf("%.3f",$trans->{threshold}->[2]);
|
|
my $whiL = sprintf("%.3f",$trans->{whitelevel}->[0]).",".sprintf("%.3f",$trans->{whitelevel}->[1]).",".sprintf("%.3f",$trans->{whitelevel}->[2]);
|
|
my $lumG = sprintf("%.3f",$trans->{luminanceGain});
|
|
my $lumM = (defined($trans->{luminanceMinimum})) ? sprintf("%.3f",$trans->{luminanceMinimum}) : undef;
|
|
my $satG = sprintf("%.3f",$trans->{saturationGain});
|
|
my $satL = (defined($trans->{saturationLGain})) ? sprintf("%.3f",$trans->{saturationLGain}) : undef;
|
|
my $valG = sprintf("%.3f",$trans->{valueGain});
|
|
$Hyperion_sets_local{effect} = $effectList if (length $effectList > 0);
|
|
if (defined($configs))
|
|
{
|
|
$Hyperion_sets_local{configFile} = $configs;
|
|
$attr{$name}{webCmd} = $Hyperion_webCmd_config if (!defined($attr{$name}{webCmd}) || AttrVal($name,"webCmd","") eq $Hyperion_webCmd);
|
|
}
|
|
$attr{$name}{alias} = "Ambilight" if (!defined($attr{$name}{alias}));
|
|
$attr{$name}{devStateIcon} = '{(Hyperion_devStateIcon($name),"toggle")}' if (!defined($attr{$name}{devStateIcon}));
|
|
$attr{$name}{group} = "colordimmer" if (!defined($attr{$name}{group}));
|
|
$attr{$name}{homebridgeMapping} = $Hyperion_homebridgeMapping if (!defined($attr{$name}{homebridgeMapping}));
|
|
$attr{$name}{icon} = "light_led_stripe_rgb" if (!defined($attr{$name}{icon}));
|
|
$attr{$name}{lightSceneParamsToSave} = "state" if (!defined($attr{$name}{lightSceneParamsToSave}));
|
|
$attr{$name}{room} = "Hyperion" if (!defined($attr{$name}{room}));
|
|
$attr{$name}{userattr} = "lightSceneParamsToSave" if (!defined($attr{$name}{userattr}) && index($attr{"global"}{userattr},"lightSceneParamsToSave") == -1);
|
|
$attr{$name}{userattr} = "lightSceneParamsToSave ".$attr{$name}{userattr} if (defined($attr{$name}{userattr}) && index($attr{$name}{userattr},"lightSceneParamsToSave") == -1 && index($attr{"global"}{userattr},"lightSceneParamsToSave") == -1);
|
|
$attr{$name}{userattr} = "homebridgeMapping" if (!defined($attr{$name}{userattr}) && index($attr{"global"}{userattr},"homebridgeMapping") == -1);
|
|
$attr{$name}{userattr} = "homebridgeMapping ".$attr{$name}{userattr} if (defined($attr{$name}{userattr}) && index($attr{$name}{userattr},"homebridgeMapping") == -1 && index($attr{"global"}{userattr},"homebridgeMapping") == -1);
|
|
$attr{$name}{webCmd} = $Hyperion_webCmd if (!defined($attr{$name}{webCmd}) || (defined($attr{$name}{webCmd}) && !defined($Hyperion_sets_local{configFile})));
|
|
$attr{$name}{webCmd} = $Hyperion_webCmd_config if (defined($attr{$name}{webCmd}) && defined($Hyperion_sets_local{configFile}) && $attr{$name}{webCmd} eq $Hyperion_webCmd);
|
|
$hash->{helper}{sets} = join(" ",map {"$_:$Hyperion_sets_local{$_}"} keys %Hyperion_sets_local);
|
|
$hash->{hostname} = $data->{hostname} if ((defined($data->{hostname}) && !defined($hash->{hostname})) || (defined($data->{hostname}) && $hash->{hostname} ne $data->{hostname}));
|
|
$hash->{build_version} = $data->{hyperion_build}->[0]->{version} if ((defined($data->{hyperion_build}->[0]->{version}) && !defined($hash->{build_version})) || (defined($data->{hyperion_build}->[0]->{version}) && $hash->{build_version} ne $data->{hyperion_build}->[0]->{version}));
|
|
$hash->{build_time} = $data->{hyperion_build}->[0]->{time} if ((defined($data->{hyperion_build}->[0]->{time}) && !defined($hash->{build_time})) || (defined($data->{hyperion_build}->[0]->{time}) && $hash->{build_time} ne $data->{hyperion_build}->[0]->{time}));
|
|
readingsBeginUpdate($hash);
|
|
readingsBulkUpdate($hash,"priority",$prio) if (defined($prio) && $prio ne ReadingsVal($name,"priority",""));
|
|
readingsBulkUpdate($hash,"adjustRed",$adjR) if ($adjR ne ReadingsVal($name,"adjustRed",""));
|
|
readingsBulkUpdate($hash,"adjustGreen",$adjG) if ($adjG ne ReadingsVal($name,"adjustGreen",""));
|
|
readingsBulkUpdate($hash,"adjustBlue",$adjB) if ($adjB ne ReadingsVal($name,"adjustBlue",""));
|
|
readingsBulkUpdate($hash,"blacklevel",$blkL) if ($blkL ne ReadingsVal($name,"blacklevel",""));
|
|
readingsBulkUpdate($hash,"dim",0) if (!defined(ReadingsVal($name,"dim",undef)));
|
|
readingsBulkUpdate($hash,"configFile","") if (!defined(ReadingsVal($name,"configFile",undef)));
|
|
readingsBulkUpdate($hash,"colorTemperature",$temP) if ($temP ne ReadingsVal($name,"colorTemperature",""));
|
|
readingsBulkUpdate($hash,"correction",$corS) if ($corS ne ReadingsVal($name,"correction",""));
|
|
readingsBulkUpdate($hash,"effect",(split(",",$effectList))[0]) if (!defined(ReadingsVal($name,"effect",undef)));
|
|
readingsBulkUpdate($hash,".effects", $effectList) if ($effectList && ReadingsVal($name,".effects","") ne $effectList);
|
|
readingsBulkUpdate($hash,"duration","infinite") if (!defined(ReadingsVal($name,"duration",undef)));
|
|
readingsBulkUpdate($hash,"gamma",$gamM) if ($gamM ne ReadingsVal($name,"gamma",""));
|
|
readingsBulkUpdate($hash,"id",$id) if ($id ne ReadingsVal($name,"id",""));
|
|
readingsBulkUpdate($hash,"lastError","") if (!defined(ReadingsVal($name,"lastError",undef)));
|
|
readingsBulkUpdate($hash,"luminanceGain",$lumG) if ($lumG ne ReadingsVal($name,"luminanceGain",""));
|
|
readingsBulkUpdate($hash,"luminanceMinimum",$lumM) if (defined($lumM) && $lumM ne ReadingsVal($name,"luminanceMinimum",""));
|
|
readingsBulkUpdate($hash,"priority",0) if (!defined(ReadingsVal($name,"priority",undef)));
|
|
readingsBulkUpdate($hash,"rgb","ff0d0d") if (!defined(ReadingsVal($name,"rgb",undef)));
|
|
readingsBulkUpdate($hash,"saturationGain",$satG) if ($satG ne ReadingsVal($name,"saturationGain",""));
|
|
readingsBulkUpdate($hash,"saturationLGain",$satL) if (defined($satL) && $satL ne ReadingsVal($name,"saturationLGain",""));
|
|
readingsBulkUpdate($hash,"threshold",$thrE) if ($thrE ne ReadingsVal($name,"threshold",""));
|
|
readingsBulkUpdate($hash,"valueGain",$valG) if ($valG ne ReadingsVal($name,"valueGain",""));
|
|
readingsBulkUpdate($hash,"whitelevel",$whiL) if ($whiL ne ReadingsVal($name,"whitelevel",""));
|
|
if ($script)
|
|
{
|
|
my $args = $data->{activeEffects}->[0]->{args};
|
|
foreach my $e (@$effects)
|
|
{
|
|
if ($e->{script} eq $script)
|
|
{
|
|
my $arg = $e->{args};
|
|
my $x = JSON->new->convert_blessed->canonical->encode($arg);
|
|
my $y = JSON->new->convert_blessed->canonical->encode($args);
|
|
|
|
if ("$x" eq "$y")
|
|
{
|
|
my $en = $e->{name};
|
|
$en =~ s/ /_/g;
|
|
readingsBulkUpdate($hash,"effect",$en) if (ReadingsVal($name,"effect","") ne $en);
|
|
readingsBulkUpdate($hash,"mode","effect") if (ReadingsVal($name,"mode","") ne "effect");
|
|
readingsBulkUpdate($hash,"state","effect $en") if (Value($name) ne "effect $en");
|
|
readingsBulkUpdate($hash,"previous_mode","effect") if (ReadingsVal($name,"previous_mode","effect") ne "effect");
|
|
Log3 $name,4,"$name: effect $en";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
elsif ($col)
|
|
{
|
|
my $rgb = lc ((split ('x',$col))[1]);
|
|
$rgb =~ m/^(..)(..)(..)/;
|
|
my ($r,$g,$b) = Color::hex2rgb($rgb);
|
|
my ($h,$s,$v) = Color::rgb2hsv($r / 255,$g / 255,$b / 255);
|
|
my $dim = int($v * 100);
|
|
readingsBulkUpdate($hash,"rgb",$rgb) if (ReadingsVal($name,"rgb","") ne $rgb);
|
|
readingsBulkUpdate($hash,"dim",$dim) if (ReadingsVal($name,"dim",0) != $dim);
|
|
readingsBulkUpdate($hash,"mode","rgb") if (ReadingsVal($name,"mode","") ne "rgb");
|
|
readingsBulkUpdate($hash,"previous_mode","rgb") if (ReadingsVal($name,"previous_mode","") ne "rgb");
|
|
readingsBulkUpdate($hash,"state","rgb $rgb") if (Value($name) ne "rgb $rgb");
|
|
Log3 $name,4,"$name: rgb $rgb";
|
|
}
|
|
else
|
|
{
|
|
if ($prio)
|
|
{
|
|
Log3 $name,4,"$name Hyperion_ParseHttpResponse clearall priority: $prio";
|
|
readingsBulkUpdate($hash,"mode","clearall") if (ReadingsVal($name,"mode","") ne "clearall");
|
|
readingsBulkUpdate($hash,"previous_mode","clearall") if (ReadingsVal($name,"previous_mode","") ne "clearall");
|
|
readingsBulkUpdate($hash,"state","clearall") if (Value($name) ne "clearall");
|
|
Log3 $name,4,"$name: clearall";
|
|
}
|
|
else
|
|
{
|
|
readingsBulkUpdate($hash,"mode","off") if (ReadingsVal($name,"mode","") ne "off");
|
|
readingsBulkUpdate($hash,"state","off") if (Value($name) ne "off");
|
|
Log3 $name,4,"$name: off";
|
|
}
|
|
}
|
|
readingsBulkUpdate($hash,"serverResponse","success");
|
|
readingsEndUpdate($hash,1);
|
|
}
|
|
else
|
|
{
|
|
Log3 $name,5,"$name: error while requesting ".$param->{url}." - $result";
|
|
readingsSingleUpdate($hash,"state","ERROR",1) if (Value($name) ne "ERROR");
|
|
readingsSingleUpdate($hash,"serverResponse","ERROR: error while requesting ".$param->{url}." - $result",1);
|
|
readingsSingleUpdate($hash,"lastError",$err,1);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub Hyperion_GetConfigs($)
|
|
{
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $ip = $hash->{IP};
|
|
my $dir = AttrVal($name,"hyperionConfigDir","/etc/hyperion/");
|
|
my $com = "ls $dir 2>/dev/null";
|
|
my @files;
|
|
if (Hyperion_isLocal($hash))
|
|
{
|
|
@files = Hyperion_listFilesInDir($hash,$com);
|
|
}
|
|
else
|
|
{
|
|
my $user = AttrVal($name,"hyperionSshUser","pi");
|
|
my $cmd = qx(which ssh);
|
|
chomp($cmd);
|
|
$cmd .= " $user\@$ip $com";
|
|
@files = Hyperion_listFilesInDir($hash,$cmd);
|
|
}
|
|
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)?" if (scalar(@files) == 0);
|
|
if (scalar(@files) > 0)
|
|
{
|
|
my $configs = join(",",@files);
|
|
readingsSingleUpdate($hash,".configs",$configs,1) if (ReadingsVal($name,".configs","") ne $configs);
|
|
$attr{$name}{webCmd} = $Hyperion_webCmd_config if (AttrVal($name,"webCmd","") eq $Hyperion_webCmd);
|
|
}
|
|
else
|
|
{
|
|
fhem("deletereading $name .configs") if (defined(ReadingsVal($name,".configs",undef)));
|
|
$attr{$name}{webCmd} = $Hyperion_webCmd if (AttrVal($name,"webCmd","") eq $Hyperion_webCmd_config);
|
|
}
|
|
# fhem("trigger WEB JS:location.reload(true)");
|
|
Hyperion_GetUpdate($hash);
|
|
return "Found at least one config file. Please refresh this page to see the result.";
|
|
}
|
|
|
|
sub Hyperion_listFilesInDir($$)
|
|
{
|
|
my ($hash,$cmd) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $fh;
|
|
my @filelist;
|
|
if (open($fh,"$cmd|"))
|
|
{
|
|
my @files = <$fh>;
|
|
my $count = scalar(@files);
|
|
for (my $i = 0; $i < $count; $i++)
|
|
{
|
|
my $file = $files[$i];
|
|
$file =~ s/\s+//gm;
|
|
next if ($file !~ /\w+\.config\.json$/);
|
|
$file =~ s/.config.json$//gm;
|
|
push @filelist,$file;
|
|
Log3 $name,4,"$name: Hyperion_listFilesInDir matching file: \"$file\"";
|
|
}
|
|
close($fh);
|
|
}
|
|
return @filelist;
|
|
}
|
|
|
|
sub Hyperion_GetUpdate(@)
|
|
{
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
if ($hash->{INTERVAL})
|
|
{
|
|
RemoveInternalTimer($hash);
|
|
InternalTimer(gettimeofday() + $hash->{INTERVAL},"Hyperion_GetUpdate",$hash,1);
|
|
}
|
|
return undef if (IsDisabled($name) > 0);
|
|
Hyperion_Call($hash,"statusRequest",undef);
|
|
return undef;
|
|
}
|
|
|
|
sub Hyperion_Set($@)
|
|
{
|
|
my ($hash,$name,@aa) = @_;
|
|
my ($cmd,@args) = @aa;
|
|
my $value = (defined($args[0])) ? $args[0] : undef;
|
|
return "\"set $name\" needs at least one argument and maximum five arguments" if (scalar(@aa) < 1 || scalar(@aa) > 4);
|
|
my $duration = (defined($args[1])) ? int($args[1]) : int(AttrVal($name,"hyperionDefaultDuration",0));
|
|
my $priority = (defined($args[2])) ? int($args[2]) : int(AttrVal($name,"hyperionDefaultPriority",0));
|
|
my $sets = $hash->{helper}{sets};
|
|
my %obj;
|
|
Log3 $name,4,"$name: Hyperion_Set cmd: $cmd" if (defined($cmd));
|
|
Log3 $name,4,"$name: Hyperion_Set value: $value" if (defined($value) && $value ne "");
|
|
Log3 $name,4,"$name: Hyperion_Set duration: $duration, priority: $priority";
|
|
if ($cmd eq "configFile")
|
|
{
|
|
$value = $value.".config.json";
|
|
my $confdir = AttrVal($name,"hyperionConfigDir","/etc/hyperion/");
|
|
my $binpath = AttrVal($name,"hyperionBin","/usr/bin/hyperiond");
|
|
my $bin = (split("/",$binpath))[scalar(split("/",$binpath)) - 1];
|
|
my $user = AttrVal($name,"hyperionSshUser","pi");
|
|
my $ip = $hash->{IP};
|
|
my $sudo = ($user eq "root" || int(AttrVal($name,"hyperionNoSudo",0)) == 1) ? "" : "sudo ";
|
|
my $command = $sudo."killall $bin; sleep 1; ".$sudo."$binpath $confdir$value > /dev/null 2>&1 &";
|
|
my $status;
|
|
my $fh;
|
|
if (Hyperion_isLocal($hash))
|
|
{
|
|
if (open($fh,"$command|"))
|
|
{
|
|
$status = <$fh>;
|
|
close($fh);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
my $com = qx(which ssh);
|
|
chomp($com);
|
|
$com .= " $user\@$ip '$command'";
|
|
if (open($fh,"$com|"))
|
|
{
|
|
$status = <$fh>;
|
|
close($fh);
|
|
}
|
|
}
|
|
if (!$status)
|
|
{
|
|
Log3 $name,4,"$name: restarted Hyperion with $binpath $confdir$value";
|
|
$value =~ s/.config.json$//;
|
|
readingsSingleUpdate($hash,"configFile",$value,1);
|
|
return undef;
|
|
}
|
|
else
|
|
{
|
|
Log3 $name,4,"$name: NOT restarted Hyperion with $binpath $confdir$value, status: $status";
|
|
readingsSingleUpdate($hash,"serverResponse","ERROR: $status",1);
|
|
return "$name NOT restarted Hyperion with $binpath $confdir$value, status: $status";
|
|
}
|
|
}
|
|
elsif ($cmd eq "rgb")
|
|
{
|
|
return "Value of $cmd has to be in RGB hex format like ffffff or 3f7d90" if ($value !~ /^(\d|[a-f]){6}$/);
|
|
my ($r,$g,$b) = Color::hex2rgb($value);
|
|
$obj{color} = [$r,$g,$b];
|
|
$obj{command} = "color";
|
|
$obj{priority} = $priority * 1;
|
|
$obj{duration} = $duration * 1000 if ($duration > 0);
|
|
}
|
|
elsif ($cmd eq "dim")
|
|
{
|
|
return "Value of $cmd has to be between 1 and 100" if ($value !~ /^(\d+)$/ || int($1) > 100 || int($1) < 1);
|
|
my $rgb = ReadingsVal($name,"rgb","ffffff");
|
|
$value = $value + 1 if ($cmd eq "dim" && $value < 100);
|
|
$value = $value / 100;
|
|
my ($r,$g,$b) = Color::hex2rgb($rgb);
|
|
my ($h,$s,$v) = Color::rgb2hsv($r / 255,$g / 255,$b / 255);
|
|
my ($rn,$gn,$bn);
|
|
($rn,$gn,$bn) = Color::hsv2rgb($h,$s,$value) if ($cmd eq "dim");
|
|
$rn = int($rn * 255);
|
|
$gn = int($gn * 255);
|
|
$bn = int($bn * 255);
|
|
$obj{color} = [$rn,$gn,$bn];
|
|
$obj{command} = "color";
|
|
$obj{priority} = $priority * 1;
|
|
$obj{duration} = $duration * 1000 if ($duration > 0);
|
|
}
|
|
elsif ($cmd eq "dimUp" || $cmd eq "dimDown")
|
|
{
|
|
return "Value of $cmd has to be between 1 and 99" if (defined($value) && $value =~ /°(\d+)$/ && int($1) < 1 && int($1) > 99);
|
|
my $dim = int(ReadingsVal($name,"dim",100));
|
|
my $dimStep = (defined($value)) ? int($value) : int(AttrVal($name,"hyperionDimStep",5));
|
|
my $dimUp = ($dim + $dimStep < 100) ? $dim + $dimStep : 100;
|
|
my $dimDown = ($dim - $dimStep > 0) ? $dim - $dimStep : 0;
|
|
fhem("set $name dim $dimUp") if ($cmd eq "dimUp");
|
|
fhem("set $name dim $dimDown") if ($cmd eq "dimDown");
|
|
return undef;
|
|
}
|
|
elsif ($cmd eq "effect")
|
|
{
|
|
return "Effect $value is not available in the effect list of $name!" if ($value !~ /^(\w+)?((_)\w+){0,}$/ || index(ReadingsVal($name,".effects",""),$value) == -1);
|
|
$value =~ s/_/ /g;
|
|
my %ef = ("name" => $value);
|
|
$obj{effect} = \%ef;
|
|
$obj{command} = "effect";
|
|
$obj{priority} = $priority * 1;
|
|
$obj{duration} = $duration * 1000 if ($duration > 0);
|
|
}
|
|
elsif ($cmd eq "clearall")
|
|
{
|
|
return "$cmd need no additional value of $value" if (defined($value));
|
|
$obj{command} = $cmd;
|
|
}
|
|
elsif ($cmd eq "clear")
|
|
{
|
|
return "Value of $cmd has to be between 0 and 65536 in steps of 1" if ($value !~ /^(\d+)$/ || int $1 < 0 || int $1 > 65536);
|
|
$value = int $value;
|
|
$obj{command} = $cmd;
|
|
$obj{priority} = $value * 1;
|
|
}
|
|
elsif ($cmd eq "off")
|
|
{
|
|
return "$cmd need no additional value of $value" if (defined($value));
|
|
$obj{command} = "color";
|
|
$obj{color} = [0,0,0];
|
|
$obj{priority} = 0;
|
|
}
|
|
elsif ($cmd eq "on")
|
|
{
|
|
return "$cmd need no additional value of $value" if (defined($value));
|
|
my $rmode = ReadingsVal($name,"previous_mode","rgb");
|
|
my $rrgb = ReadingsVal($name,"rgb","");
|
|
my $reffect = ReadingsVal($name,"effect","");
|
|
my ($r,$g,$b) = Color::hex2rgb($rrgb);
|
|
if ($rmode eq "rgb")
|
|
{
|
|
fhem ("set ".$name." $rmode $rrgb");
|
|
}
|
|
elsif ($rmode eq "effect")
|
|
{
|
|
fhem ("set ".$name." $rmode $reffect");
|
|
}
|
|
elsif ($rmode eq "clearall")
|
|
{
|
|
fhem ("set ".$name." clearall");
|
|
}
|
|
return undef;
|
|
}
|
|
elsif ($cmd eq "toggle")
|
|
{
|
|
return "$cmd need no additional value of $value" if (defined($value));
|
|
my $rstate = Value($name);
|
|
if ($rstate ne "off")
|
|
{
|
|
fhem ("set ".$name." off");
|
|
}
|
|
else
|
|
{
|
|
fhem ("set ".$name." on");
|
|
}
|
|
return undef;
|
|
}
|
|
elsif ($cmd eq "mode")
|
|
{
|
|
return "The value of mode has to be rgb,effect,clearall,off" if ($value !~ /^(off|clearall|rgb|effect)$/);
|
|
Log3 $name,4,"$name: cmd: $cmd, value: $value";
|
|
my $rmode = $value;
|
|
my $rrgb = ReadingsVal($name,"rgb","");
|
|
my $reffect = ReadingsVal($name,"effect","");
|
|
my ($r,$g,$b) = Color::hex2rgb($rrgb);
|
|
if ($rmode eq "rgb")
|
|
{
|
|
fhem ("set ".$name." $rmode $rrgb");
|
|
}
|
|
elsif ($rmode eq "effect")
|
|
{
|
|
fhem ("set ".$name." $rmode $reffect");
|
|
}
|
|
elsif ($rmode eq "clearall")
|
|
{
|
|
fhem ("set ".$name." clearall");
|
|
}
|
|
elsif ($rmode eq "off")
|
|
{
|
|
fhem ("set ".$name." $rmode");
|
|
}
|
|
return undef;
|
|
}
|
|
elsif ( $cmd eq "luminanceGain" ||
|
|
$cmd eq "luminanceMinimum" ||
|
|
$cmd eq "saturationGain" ||
|
|
$cmd eq "saturationLGain" ||
|
|
$cmd eq "valueGain"
|
|
)
|
|
{
|
|
return "The value of $cmd has to be between 0.000 an 1.999 in steps of 0.001." if ($value !~ /^(\d)(\.\d)?(\d{1,2})?$/ || int $1 > 1);
|
|
$value = sprintf("%.3f",$value) * 1;
|
|
my %tr = ($cmd => $value);
|
|
$obj{command} = "transform";
|
|
$obj{transform} = \%tr;
|
|
}
|
|
elsif ($cmd eq "blacklevel" ||
|
|
$cmd eq "gamma" ||
|
|
$cmd eq "threshold" ||
|
|
$cmd eq "whitelevel"
|
|
)
|
|
{
|
|
return "Each of the three comma separated values of $cmd has to be between 0.000 an 9.999 in steps of 0.001" if ($value !~ /^(\d)(\.\d)?(\d{1,2})?$/ || int $1 > 9);
|
|
my $arr = Hyperion_list2array($value,"%.3f");
|
|
my %ar = ($cmd => $arr);
|
|
$obj{command} = "transform";
|
|
$obj{transform} = \%ar;
|
|
}
|
|
elsif ($cmd eq "correction" || $cmd eq "colorTemperature")
|
|
{
|
|
$cmd = "temperature" if ($cmd eq "colorTemperature");
|
|
return "Each of the three comma separated values of $cmd has to be between 0 an 255 in steps of 1" if ($value !~ /^(\d{1,3})?,(\d{1,3})?,(\d{1,3})?$/ || int $1 > 255 || int $2 > 255 || int $3 > 255);
|
|
my $arr = Hyperion_list2array($value,"%d");
|
|
my %ar = ("correctionValues" => $arr);
|
|
$obj{command} = $cmd;
|
|
$obj{$cmd} = \%ar;
|
|
}
|
|
elsif ( $cmd eq "adjustRed" ||
|
|
$cmd eq "adjustGreen" ||
|
|
$cmd eq "adjustBlue"
|
|
)
|
|
{
|
|
return "Each of the three comma separated values of $cmd has to be between 0 an 255 in steps of 1" if ($value !~ /^(\d{1,3})?,(\d{1,3})?,(\d{1,3})?$/ || int $1 > 255 || int $2 > 255 || int $3 > 255);
|
|
$cmd = "redAdjust" if ($cmd eq "adjustRed");
|
|
$cmd = "greenAdjust" if ($cmd eq "adjustGreen");
|
|
$cmd = "blueAdjust" if ($cmd eq "adjustBlue");
|
|
my $arr = Hyperion_list2array($value,"%d");
|
|
my %ar = ($cmd => $arr);
|
|
$obj{command} = "adjustment";
|
|
$obj{adjustment} = \%ar;
|
|
}
|
|
if (scalar keys %obj)
|
|
{
|
|
Log3 $name,5,"$name: $cmd obj json: ".encode_json(\%obj);
|
|
SetExtensionsCancel($hash);
|
|
Hyperion_Call($hash,$cmd,\%obj);
|
|
}
|
|
else
|
|
{
|
|
return SetExtensions($hash,$sets,$name,@aa) ;
|
|
}
|
|
}
|
|
|
|
sub Hyperion_Attr(@)
|
|
{
|
|
my ($cmd,$name,$attr_name,$attr_value) = @_;
|
|
my $hash = $defs{$name};
|
|
my $err = undef;
|
|
my $local = ($hash->{IP} eq "localhost" || $hash->{IP} eq "127.0.0.1") ? "" : undef;
|
|
if ($cmd eq "set")
|
|
{
|
|
if ($attr_name eq "hyperionBin")
|
|
{
|
|
if ($attr_value !~ /^(\/.+){2,}$/)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Must be a path like /usr/bin/hyperiond.";
|
|
}
|
|
elsif (defined($local) && !-e $attr_value)
|
|
{
|
|
$err = "The given file $attr_value is not an available file.";
|
|
}
|
|
}
|
|
elsif ($attr_name eq "hyperionConfigDir")
|
|
{
|
|
if ($attr_value !~ /^\/(.+\/){2,}/)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Must be a path with trailing slash like /etc/hyperion/.";
|
|
}
|
|
elsif (defined($local) && !-d $attr_value)
|
|
{
|
|
$err = "The given directory $attr_value is not an available directory.";
|
|
}
|
|
else
|
|
{
|
|
Hyperion_GetConfigs($hash);
|
|
Hyperion_Call($hash,$cmd,undef);
|
|
}
|
|
}
|
|
elsif ($attr_name eq "hyperionDefaultPriority" || $attr_name eq "hyperionDefaultDuration")
|
|
{
|
|
if ($attr_value !~ /^(\d+)$/ || $1 < 0 || $1 > 65536)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Must be a number between 0 and 65536.";
|
|
}
|
|
}
|
|
elsif ($attr_name eq "hyperionDimStep")
|
|
{
|
|
if ($attr_value !~ /^(\d+)$/ || $1 < 1 || $1 > 50)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Must be between 1 and 50 in steps of 1, default is 5.";
|
|
}
|
|
}
|
|
elsif ($attr_name eq "hyperionNoSudo")
|
|
{
|
|
if ($attr_value !~ /^1$/)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Can only be value 1.";
|
|
}
|
|
}
|
|
elsif ($attr_name eq "hyperionSshUser")
|
|
{
|
|
if ($attr_value !~ /^\w+$/)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Must be a name like pi or fhem.";
|
|
}
|
|
else
|
|
{
|
|
Hyperion_GetConfigs($hash);
|
|
Hyperion_Call($hash,$cmd,undef);
|
|
}
|
|
}
|
|
elsif ($attr_name eq "queryAfterSet")
|
|
{
|
|
if ($attr_value !~ /^0$/)
|
|
{
|
|
$err = "Invalid value $attr_value for attribute $attr_name. Must be 0 when set, default is 1.";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Hyperion_Call($hash,$cmd,undef);
|
|
}
|
|
return $err if (defined($err));
|
|
return;
|
|
}
|
|
|
|
sub Hyperion_Call($$$)
|
|
{
|
|
my ($hash,$cmd,$obj) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $json = (defined($obj)) ? encode_json($obj) : encode_json({ "command" => "serverinfo" });
|
|
Log3 $name,5,"$name: Hyperion_Call: json object: $json";
|
|
Hyperion_GetHttpResponse($hash,$cmd,$json);
|
|
}
|
|
|
|
sub Hyperion_devStateIcon($;$)
|
|
{
|
|
my ($hash,$state) = @_;
|
|
$hash = $defs{ $hash } if (ref($hash) ne "HASH");
|
|
return undef if (!$hash);
|
|
my $name = $hash->{NAME};
|
|
my $rgb = ReadingsVal($name,"rgb","");
|
|
my $dim = ReadingsVal($name,"dim",10);
|
|
my $ico = (int($dim / 10) * 10 < 10) ? 10 : int($dim / 10) * 10;
|
|
return ".*:off:toggle" if (Value($name) eq "off");
|
|
return ".*:light_exclamation" if (Value($name) eq "ERROR");
|
|
return ".*:light_question" if (Value($name) eq "Initialized");
|
|
return ".*:light_light_dim_$ico@#".$rgb.":toggle" if (Value($name) ne "off" && ReadingsVal($name,"mode","") eq "rgb");
|
|
return ".*:light_led_stripe_rgb@#FFFF00:toggle" if (Value($name) ne "off" && ReadingsVal($name,"mode","") eq "effect");
|
|
return ".*:it_television@#0000FF:toggle" if (Value($name) ne "off" && ReadingsVal($name,"mode","") eq "clearall");
|
|
}
|
|
|
|
1;
|
|
|
|
=pod
|
|
=item device
|
|
=item summary provides access to the Hyperion JSON server
|
|
=item summary_DE stellt Zugang zum Hyperion JSON Server zur Verfügung
|
|
=begin html
|
|
|
|
<a name="Hyperion"></a>
|
|
<h3>Hyperion</h3>
|
|
<ul>
|
|
With <i>Hyperion</i> it is possible to change the color or start an effect on a hyperion server.<br>
|
|
It's also possible to control the complete color calibration (changes are temorary and will not be written to the config file).<br>
|
|
The Hyperion server must have enabled the JSON server.<br>
|
|
You can also restart Hyperion with different configuration files (p.e. switch input)<br>
|
|
<br>
|
|
<a name="Hyperion_define"></a>
|
|
<p><b>Define</b></p>
|
|
<ul>
|
|
<code>define <name> Hyperion <IP or HOSTNAME> <PORT> [<INTERVAL>]</code><br>
|
|
</ul>
|
|
<br>
|
|
<INTERVAL> is optional for polling.<br>
|
|
<br>
|
|
<i>After defining "get <name> statusRequest" will be called once automatically to get the list of available effects and the current state of the Hyperion server.</i><br>
|
|
<br>
|
|
Example for running Hyperion on local system:
|
|
<br><br>
|
|
<ul>
|
|
<code>define Ambilight Hyperion localhost 19444 10</code><br>
|
|
</ul>
|
|
<br>
|
|
Example for running Hyperion on remote system:
|
|
<br><br>
|
|
<ul>
|
|
<code>define Ambilight Hyperion 192.168.1.4 19444 10</code><br>
|
|
</ul>
|
|
<br>
|
|
<a name="Hyperion_set"></a>
|
|
<p><b>set <required> [optional]</b></p>
|
|
<ul>
|
|
<li>
|
|
<i>adjustBlue <0,0,255></i><br>
|
|
adjust each color of blue separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>adjustGreen <0,255,0></i><br>
|
|
adjust each color of green separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>adjustRed <255,0,0></i><br>
|
|
adjust each color of red separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>blacklevel <0.000,0.000,0.000></i><br>
|
|
adjust blacklevel of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>clear <1000></i><br>
|
|
clear a specific priority channel
|
|
</li>
|
|
<li>
|
|
<i>clearall</i><br>
|
|
clear all priority channels / switch to Ambilight mode
|
|
</li>
|
|
<li>
|
|
<i>colorTemperature <255,255,255></i><br>
|
|
adjust temperature of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>configFile <filename></i><br>
|
|
restart the Hyperion server with the given configuration file (files will be listed automatically from the given directory in attribute hyperionConfigDir)<br>
|
|
please omit the double extension of the file name (.config.json)
|
|
</li>
|
|
<li>
|
|
<i>correction <255,255,255></i><br>
|
|
adjust correction of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>dim <percent> [duration] [priority]</i><br>
|
|
dim the rgb light with optional duration in seconds and priority
|
|
</li>
|
|
<li>
|
|
<i>dimDown [delta]</i><br>
|
|
dim down rgb light by steps defined in attribute hyperionDimStep or by given value (default: 10)
|
|
</li>
|
|
<li>
|
|
<i>dimUp [delta]</i><br>
|
|
dim up rgb light by steps defined in attribute hyperionDimStep or by given value (default: 10)
|
|
</li>
|
|
<li>
|
|
<i>effect <effect> [duration] [priority]</i><br>
|
|
set effect (replace blanks with underscore) with optional duration in seconds and priority
|
|
</li>
|
|
<li>
|
|
<i>gamma <1.900,1.900,1.900></i><br>
|
|
adjust gamma of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>luminanceGain <1.000></i><br>
|
|
adjust luminanceGain (max. value 1.999)
|
|
</li>
|
|
<li>
|
|
<i>luminanceMinimum <0.000></i><br>
|
|
adjust luminanceMinimum (max. value 1.999)
|
|
</li>
|
|
<li>
|
|
<i>mode <clearall|effect|off|rgb></i><br>
|
|
set the light in the specific mode with its previous value
|
|
</li>
|
|
<li>
|
|
<i>off</i><br>
|
|
set the light off while the color is black
|
|
</li>
|
|
<li>
|
|
<i>on</i><br>
|
|
set the light on and restore previous state
|
|
</li>
|
|
<li>
|
|
<i>rgb <RRGGBB> [duration] [priority]</i><br>
|
|
set color in RGB Hex format with optional duration in seconds and priority
|
|
</li>
|
|
<li>
|
|
<i>saturationGain <1.100></i><br>
|
|
adjust saturationGain (max. value 1.999)
|
|
</li>
|
|
<li>
|
|
<i>saturationLGain <1.000></i><br>
|
|
adjust saturationLGain (max. value 1.999)
|
|
</li>
|
|
<li>
|
|
<i>threshold <0.160,0.160,0.160></i><br>
|
|
adjust threshold of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>toggle</i><br>
|
|
toggles the light between on and off
|
|
</li>
|
|
<li>
|
|
<i>valueGain <1.700></i><br>
|
|
adjust valueGain (max. value 1.999)
|
|
</li>
|
|
<li>
|
|
<i>whitelevel <0.700,0.800,0.900></i><br>
|
|
adjust whitelevel of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
<a name="Hyperion_get"></a>
|
|
<p><b>Get</b></p>
|
|
<ul>
|
|
<li>
|
|
<i>configFiles</i><br>
|
|
get the available config files in directory from attribute hyperionConfigDir
|
|
</li>
|
|
<li>
|
|
<i>devStateIcon</i><br>
|
|
get the current devStateIcon
|
|
</li>
|
|
<li>
|
|
<i>statusRequest</i><br>
|
|
get the currently set effect or color from the Hyperion server,<br>
|
|
get the internals of Hyperion including available effects
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
<a name="Hyperion_attr"></a>
|
|
<p><b>Attributes</b></p>
|
|
<ul>
|
|
<li>
|
|
<i>hyperionBin</i><br>
|
|
path to the hyperion executable, if not set it's /usr/bin/hyperiond
|
|
</li>
|
|
<li>
|
|
<i>hyperionConfigDir</i><br>
|
|
path to the hyperion configuration files, if not set it's /etc/hyperion/
|
|
</li>
|
|
<li>
|
|
<i>hyperionDefaultDuration</i><br>
|
|
default duration, if not set it's infinity
|
|
</li>
|
|
<li>
|
|
<i>hyperionNoSudo</i><br>
|
|
disable sudo for non-root users
|
|
</li>
|
|
<li>
|
|
<i>hyperionDefaultPriority</i><br>
|
|
default priority, if not set it's 0
|
|
</li>
|
|
<li>
|
|
<i>hyperionDimStep</i><br>
|
|
dim step for dimDown/dimUp, if not set it's 5 (percent)
|
|
</li>
|
|
<li>
|
|
<i>hyperionSshUser</i><br>
|
|
user for executing SSH commands
|
|
</li>
|
|
<li>
|
|
<i>queryAfterSet</i><br>
|
|
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>
|
|
This is only used when polling is enabled, without polling the state will be queried automatically after set.
|
|
</li>
|
|
</ul>
|
|
<br>
|
|
<a name="Hyperion_read"></a>
|
|
<p><b>Readings</b></p>
|
|
<ul>
|
|
<li>
|
|
<i>adjustBlue</i><br>
|
|
each color of blue separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>adjustGreen</i><br>
|
|
each color of green separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>adjustRed</i><br>
|
|
each color of red separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>blacklevel</i><br>
|
|
blacklevel of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>colorTemperature</i><br>
|
|
temperature of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>configFile</i><br>
|
|
active/previously loaded configuration file, double extension (.config.json) will be omitted
|
|
</li>
|
|
<li>
|
|
<i>correction</i><br>
|
|
correction of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>dim</i><br>
|
|
active/previous dim value (rgb light)
|
|
</li>
|
|
<li>
|
|
<i>duration</i><br>
|
|
active/previous duration in seconds or infinite
|
|
</li>
|
|
<li>
|
|
<i>effect</i><br>
|
|
active/previous effect
|
|
</li>
|
|
<li>
|
|
<i>gamma</i><br>
|
|
gamma for each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>id</i><br>
|
|
id of the Hyperion server
|
|
</li>
|
|
<li>
|
|
<i>lastError</i><br>
|
|
last occured error while communicating with the Hyperion server
|
|
</li>
|
|
<li>
|
|
<i>luminanceGain</i><br>
|
|
luminanceGain
|
|
</li>
|
|
<li>
|
|
<i>luminanceMinimum</i><br>
|
|
luminanceMinimum
|
|
</li>
|
|
<li>
|
|
<i>mode</i><br>
|
|
current mode
|
|
</li>
|
|
<li>
|
|
<i>previous_mode</i><br>
|
|
previous mode before off
|
|
</li>
|
|
<li>
|
|
<i>priority</i><br>
|
|
active/previous priority
|
|
</li>
|
|
<li>
|
|
<i>rgb</i><br>
|
|
active/previous rgb
|
|
</li>
|
|
<li>
|
|
<i>saturationGain</i><br>
|
|
active/previous saturationGain
|
|
</li>
|
|
<li>
|
|
<i>saturationLGain</i><br>
|
|
active/previous saturationLGain
|
|
</li>
|
|
<li>
|
|
<i>serverResponse</i><br>
|
|
last Hyperion server response (success/ERROR)
|
|
</li>
|
|
<li>
|
|
<i>state</i><br>
|
|
current state
|
|
</li>
|
|
<li>
|
|
<i>threshold</i><br>
|
|
threshold of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
<li>
|
|
<i>valueGain</i><br>
|
|
valueGain - gain of the Ambilight
|
|
</li>
|
|
<li>
|
|
<i>whitelevel</i><br>
|
|
whitelevel of each color separately (comma separated) (R,G,B)
|
|
</li>
|
|
</ul>
|
|
</ul>
|
|
|
|
=end html
|
|
=cut
|