From 308e80d62d406ee6faab40cf98dab8be648d4909 Mon Sep 17 00:00:00 2001 From: betateilchen <> Date: Sun, 10 Jan 2021 20:48:32 +0000 Subject: [PATCH] 55_Volumio.pm: just for fun git-svn-id: https://svn.fhem.de/fhem/trunk@23507 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/betateilchen/55_Volumio.pm | 217 ++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 fhem/contrib/betateilchen/55_Volumio.pm diff --git a/fhem/contrib/betateilchen/55_Volumio.pm b/fhem/contrib/betateilchen/55_Volumio.pm new file mode 100644 index 000000000..312f68eee --- /dev/null +++ b/fhem/contrib/betateilchen/55_Volumio.pm @@ -0,0 +1,217 @@ +# $Id$ +############################################################################## +# +############################################################################## + +package FHEM::Volumio; ## no critic + +use strict; +use warnings; +use JSON qw( decode_json ); +use Data::Dumper; + +use GPUtils qw(GP_Import GP_Export); + +## Import der FHEM Funktionen + +BEGIN { + # Import from main context + GP_Import( + qw( attr + AttrVal + BlockingInformParent + CommandDefine + CommandDeleteReading + Debug + defs + HttpUtils_NonblockingGet + init_done + InternalTimer + IsDisabled + json2reading + Log3 + parseParams + readingFnAttributes + readingsBeginUpdate + readingsBulkUpdate + readingsEndUpdate + readingsSingleUpdate + ReadingsVal + RemoveInternalTimer ) + ); +} + +#-- Export to main context with different name +GP_Export(qw( Initialize )); + +sub Initialize { + my ($hash) = @_; + + $hash->{DefFn} = \&Define; + $hash->{UndefFn} = \&Undef; + $hash->{SetFn} = \&Set; +# $hash->{AttrFn} = \&Attr; + $hash->{AttrList} = + 'disable:1,0 ' + . 'disabledForIntervals ' + . $readingFnAttributes; + + return; +} + +sub Discover { + my $hash = shift; + + unless $init_done { + InternalTimer(time()+3, \&Discover, $hash, 0); + } else { + my $param = { + url => "http://volumio.local/api/v1/getzones", + timeout => 5, + hash => $hash, + method => "GET", + callback => \&ParseGetzones + }; + HttpUtils_NonblockingGet($param); + + sub ParseGetzones{ + my ($param, $err, $data) = @_; + if ($err ne '') { + readingsSingleUpdate( $param->{hash}, 'state', $err, 0 ); + } else { + json2reading($param->{hash}{NAME},$data); + my $json_object = decode_json($data); + for my $item( @{$json_object->{zones}} ){ + my $n = $item->{name}; + my $i = $item->{id}; $i =~ s/-//g; + my $h = $item->{host}; + my $v = $item->{state}->{volume}; + my $t = $item->{type}; + my $defString = "$n"."_$i Volumio host=$h volume=$v type=$t"; + CommandDefine(undef,$defString); + } + } + } + } + return; +} + +sub Define { + my $hash = shift; + my $def = shift; + my $name = $hash->{NAME}; + + my ( $arrayref, $hashref ) = parseParams($def); + my @a = @{$arrayref}; + my %h = %{$hashref}; + + if (exists $h{host}) { + $hash->{host} = $h{host}; + my $param = { + name => $hash->{NAME}, + type => $h{type}, + volume => $h{volume}, + url => "$h{host}/api/v1/getSystemVersion", + timeout => 5, + hash => $hash, + method => "GET", + callback => sub { + my ($param, $err, $data) = @_; + my $n = $param->{name}; + my $h = $param->{hash}; + $h->{DEF} = "host=$h{host}"; + #$h->{TEMPORARY} = 1; + json2reading($n,$data); + readingsBeginUpdate($h); + readingsBulkUpdate($h,'type',$param->{type}); + readingsBulkUpdate($h,'volume',$param->{volume}); + readingsEndUpdate($h, 0); + } + }; + HttpUtils_NonblockingGet($param); + } else { + InternalTimer(time()+3, \&Discover, $hash, 0); + } + + return; +} + +sub Undef { + my $hash = shift; + RemoveInternalTimer($hash); + return; +} + +sub Set { + my $hash = shift; + my $name = shift; + my $cmd = shift; + my $val = shift; $val //= ''; + + return "Unknown argument $cmd, choose one of volume mute:noArg unmute:noArg " + ."play:noArg pause:noArg play/pause:noArg stop:noArg" if ($cmd eq '?'); + +my $host = $hash->{host}; + + my $url = "$host/api/v1/commands/?cmd="; + $url .= "volume&volume=mute" if(lc($cmd) eq 'mute'); + $url .= "volume&volume=unmute" if(lc($cmd) eq 'unmute'); + $url .= "volume&volume=$val" if(lc($cmd) eq 'volume'); + $url .= "play" if(lc($cmd) eq 'play'); + $url .= "pause" if(lc($cmd) eq 'pause'); + $url .= "toggle" if(lc($cmd) eq 'play/pause'); + $url .= "stop" if(lc($cmd) eq 'stop'); + + my $param = { + url => $url, + timeout => 5, + hash => $hash, + method => "GET", + callback => \&ParseSetResponse, + cmd => $cmd, + val => $val, + }; + HttpUtils_NonblockingGet($param); + + sub ParseSetResponse{ + my ($param, $err, $data) = @_; + my $hash = $param->{hash}; + my $name = $hash->{NAME}; + if ($err ne '') { + readingsSingleUpdate( $param->{hash}, 'state', $err, 1 ); + } else { + if ($param->{cmd} eq 'volume' && $param->{val} !~ m/mute/) { + readingsSingleUpdate($hash, 'volume', $param->{val}, 0) + } + } + } +} + +1; + +################################################################################ +# +# Documentation +# +################################################################################ + +=pod + +=encoding utf8 + +=item helper +=item summary Control Volumio Media Player +=item summary_DE Steuerung des Volumio Media Player + +=begin html + + +

WUup

+ + +=end html + +=cut