diverse set Befehle, aktivieren von Eventverarveitung, automatisches anlegen der Player, Fehlerbehandlung bei unsauberen JSON
This commit is contained in:
parent
2a0eb3a723
commit
18ef7f7fa9
158
21_HEOSMaster.pm
158
21_HEOSMaster.pm
@ -45,16 +45,19 @@ use JSON;
|
||||
use Net::Telnet;
|
||||
|
||||
|
||||
my $version = "0.1.17";
|
||||
my $version = "0.1.28";
|
||||
|
||||
|
||||
my %heosCmds = (
|
||||
'enableEvents' => 'system/register_for_change_events?enable=',
|
||||
'getPlayers' => 'player/get_players',
|
||||
'getPlayerState' => 'player/get_player_info?',
|
||||
'setPlayState' => 'player/set_play_state?',
|
||||
'setMute' => 'player/set_mute?',
|
||||
'setVolume' => 'player/set_volume?'
|
||||
'enableChangeEvents' => 'system/register_for_change_events?enable=',
|
||||
'getPlayers' => 'player/get_players',
|
||||
'getPlayerInfo' => 'player/get_player_info?',
|
||||
'getPlayerState' => 'player/get_player_state?',
|
||||
'setPlayState' => 'player/set_play_state?',
|
||||
'setMute' => 'player/set_mute?',
|
||||
'setVolume' => 'player/set_volume?',
|
||||
'getNowPlayingMedia' => 'player/get_now_playing_media?',
|
||||
'eventChangeVolume' => 'event/player_volume_changed'
|
||||
);
|
||||
|
||||
|
||||
@ -73,6 +76,8 @@ sub HEOSMaster_Attr(@);
|
||||
sub HEOSMaster_firstRun($);
|
||||
sub HEOSMaster_ResponseProcessing($$);
|
||||
sub HEOSMaster_WriteReadings($$);
|
||||
sub HEOSMaster_GetPlayers($);
|
||||
sub HEOSMaster_PreResponseProsessing($$);
|
||||
|
||||
|
||||
|
||||
@ -85,7 +90,7 @@ sub HEOSMaster_Initialize($) {
|
||||
$hash->{ReadFn} = "HEOSMaster_Read";
|
||||
$hash->{WriteFn} = "HEOSMaster_Write";
|
||||
$hash->{Clients} = ":HEOSPlayer:";
|
||||
$hash->{MatchList} = { "1:HEOSPlayer" => '.*{"command":."player.*' };
|
||||
$hash->{MatchList} = { "1:HEOSPlayer" => '.*{"command":."player.*|.*{"command":."event\/player.*' };
|
||||
|
||||
|
||||
# Consumer
|
||||
@ -134,7 +139,8 @@ sub HEOSMaster_Define($$) {
|
||||
|
||||
if( $init_done ) {
|
||||
|
||||
InternalTimer( gettimeofday()+1, 'HEOSMaster_firstRun', $hash, 0 ) if( ($hash->{HOST}) );
|
||||
HEOSMaster_firstRun($hash);
|
||||
|
||||
} else {
|
||||
|
||||
InternalTimer( gettimeofday()+15, 'HEOSMaster_firstRun', $hash, 0 ) if( ($hash->{HOST}) );
|
||||
@ -197,6 +203,7 @@ sub HEOSMaster_Set($@) {
|
||||
my ($arg, @params) = @args;
|
||||
|
||||
my $action;
|
||||
my $heosCmd;
|
||||
|
||||
if($cmd eq 'reopen') {
|
||||
return "usage: reopen" if( @args != 0 );
|
||||
@ -209,29 +216,37 @@ sub HEOSMaster_Set($@) {
|
||||
} elsif($cmd eq 'getPlayers') {
|
||||
return "usage: getPlayers" if( @args != 0 );
|
||||
|
||||
$action = $cmd;
|
||||
HEOSMaster_GetPlayers($hash);
|
||||
|
||||
} elsif($cmd eq 'send') {
|
||||
return "usage: send" if( @args != 0 );
|
||||
return undef;
|
||||
|
||||
} elsif($cmd eq 'enableChangeEvents') {
|
||||
return "usage: enableChangeEvents" if( @args != 1 );
|
||||
|
||||
$heosCmd = $cmd;
|
||||
$action = join(' ',@args);
|
||||
|
||||
} elsif($cmd eq 'eventSend') {
|
||||
return "usage: enableChangeEvents" if( @args != 0 );
|
||||
|
||||
HEOSMaster_send($hash);
|
||||
|
||||
return undef;
|
||||
return undef;
|
||||
|
||||
} else {
|
||||
my $list = "";
|
||||
$list .= "reopen:noArg getPlayers:noArg send:noArg";
|
||||
$list .= "reopen:noArg getPlayers:noArg enableChangeEvents:on,off";
|
||||
return "Unknown argument $cmd, choose one of $list";
|
||||
}
|
||||
|
||||
HEOSMaster_Write($hash,$action,undef);
|
||||
HEOSMaster_Write($hash,$heosCmd,$action);
|
||||
}
|
||||
|
||||
sub HEOSMaster_send($) {
|
||||
|
||||
my $hash = shift;
|
||||
|
||||
HEOSMaster_Write($hash,'getPlayerState',"pid=-512565195");
|
||||
HEOSMaster_Write($hash,'eventChangeVolume',undef);
|
||||
|
||||
}
|
||||
|
||||
sub HEOSMaster_firstRun($) {
|
||||
@ -239,21 +254,22 @@ sub HEOSMaster_firstRun($) {
|
||||
my $hash = shift;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
#if( !IsDisabled($name) ) {
|
||||
HEOSMaster_Open($hash) if( !IsDisabled($name) );
|
||||
}
|
||||
|
||||
sub HEOSMaster_GetPlayers($) {
|
||||
|
||||
my $hash = shift;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
HEOSMaster_Open($hash);
|
||||
if( $hash->{CD} ) {
|
||||
|
||||
HEOSMaster_Write($hash,$heosCmds{enableEvents},'on');
|
||||
Log3 $name, 3, "HEOSMaster ($name) - enable events at HEOS CLI";
|
||||
|
||||
} else {
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - failed enable events at HEOS CLI";
|
||||
}
|
||||
#}
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
HEOSMaster_Write($hash,'getPlayers',undef);
|
||||
Log3 $name, 3, "HEOSMaster ($name) - getPlayers";
|
||||
}
|
||||
|
||||
sub HEOSMaster_Open($) {
|
||||
@ -281,6 +297,8 @@ sub HEOSMaster_Open($) {
|
||||
readingsSingleUpdate($hash, 'state', 'connected', 1 );
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - Socket Connected";
|
||||
|
||||
HEOSMaster_GetPlayers($hash);
|
||||
}
|
||||
|
||||
sub HEOSMaster_Close($) {
|
||||
@ -303,7 +321,7 @@ sub HEOSMaster_Write($@) {
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $string = "heos://$heosCmds{$heosCmd}";
|
||||
$string .= "${value}" if(defined($value));
|
||||
$string .= "${value}" if(defined($value) or $value ne '&');
|
||||
$string .= "\r\n";
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - WriteFn called";
|
||||
@ -326,7 +344,7 @@ sub HEOSMaster_Read($) {
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - ReadFn gestartet";
|
||||
|
||||
$len = sysread($hash->{CD},$buf,1024);
|
||||
$len = sysread($hash->{CD},$buf,4096);
|
||||
|
||||
if( !defined($len) || !$len ) {
|
||||
Log 1, "Länge? !!!!!!!!!!";
|
||||
@ -335,13 +353,60 @@ sub HEOSMaster_Read($) {
|
||||
|
||||
unless( defined $buf) {
|
||||
Log3 $name, 3, "HEOSMaster ($name) - Keine Daten empfangen";
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
if( $buf !~ m/^[\[{].*[}\]]$/ ) {
|
||||
Log3 $name, 3, "HEOSMaster ($name) - invalid json detected. start preprocessing";
|
||||
HEOSMaster_PreResponseProsessing($hash,$buf);
|
||||
return;
|
||||
}
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - Daten: $buf";
|
||||
HEOSMaster_ResponseProcessing($hash,$buf);
|
||||
}
|
||||
|
||||
sub HEOSMaster_PreResponseProsessing($$) {
|
||||
|
||||
my ($hash,$response) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - pre processing respone data";
|
||||
|
||||
my $len = length($response);
|
||||
my @letterArray = split("",$response);
|
||||
|
||||
my $letter = "";
|
||||
my $count = 0;
|
||||
my $marker = 0;
|
||||
my $json;
|
||||
|
||||
for(my $i = 0; $i < $len; $i++) {
|
||||
|
||||
$marker = 1 if($count > 0);
|
||||
$letter = $letterArray[0];
|
||||
$json .= $letter;
|
||||
|
||||
$count++ if($letter eq '{');
|
||||
$count-- if($letter eq '}');
|
||||
|
||||
|
||||
|
||||
if( $count == 0 and $marker == 1) {
|
||||
|
||||
HEOSMaster_ResponseProcessing($hash,$json);
|
||||
$json = "";
|
||||
$marker = 0;
|
||||
}
|
||||
|
||||
shift(@letterArray);
|
||||
}
|
||||
|
||||
#my $rest = join(' ',@letterArray); # currupted data, rest array
|
||||
#Log3 $name, 3, "HEOSMaster ($name) - found corrupt data in buffer: $rest" if( defined($rest) and ($rest) );
|
||||
}
|
||||
|
||||
sub HEOSMaster_ResponseProcessing($$) {
|
||||
|
||||
my ($hash,$json) = @_;
|
||||
@ -349,28 +414,27 @@ sub HEOSMaster_ResponseProcessing($$) {
|
||||
|
||||
my $decode_json;
|
||||
|
||||
|
||||
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - JSON String: $json";
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - JSON String: $json";
|
||||
|
||||
return Log3 $name, 3, "HEOSMaster ($name) - empty answer received"
|
||||
unless( defined($json));
|
||||
|
||||
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - json detected: $json";
|
||||
$decode_json = decode_json($json);
|
||||
|
||||
return Log3 $name, 3, "HEOSMaster ($name) - decode_json has no Hash"
|
||||
unless(ref($decode_json) eq "HASH");
|
||||
|
||||
|
||||
if( defined($decode_json->{heos}{result}) and defined($decode_json->{heos}{command}) ) {
|
||||
if( (defined($decode_json->{heos}{result}) and defined($decode_json->{heos}{command})) or ($decode_json->{heos}{command} =~ /^system/) ) {
|
||||
|
||||
HEOSMaster_WriteReadings($hash,$decode_json);
|
||||
Log3 $name, 3, "HEOSMaster ($name) - call Sub HEOSMaster_WriteReadings";
|
||||
}
|
||||
|
||||
if( $decode_json->{heos}{command} =~ /^player/ ) {
|
||||
if( $decode_json->{heos}{command} =~ /^player/ or $decode_json->{heos}{command} =~ /^event\/player/ ) {
|
||||
if( ref($decode_json->{payload}) eq "ARRAY" and scalar(@{$decode_json->{payload}}) > 0) {
|
||||
|
||||
foreach my $payload (@{$decode_json->{payload}}) {
|
||||
@ -383,18 +447,23 @@ sub HEOSMaster_ResponseProcessing($$) {
|
||||
Log3 $name, 3, "HEOSMaster ($name) - call Dispatcher";
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} elsif( defined($decode_json->{payload}{pid}) ) {
|
||||
|
||||
Dispatch($hash,$json,undef);
|
||||
Log3 $name, 3, "HEOSMaster ($name) - call Dispatcher";
|
||||
return;
|
||||
|
||||
} elsif( $decode_json->{heos}{message} =~ /^pid=/ ) {
|
||||
|
||||
Dispatch($hash,$json,undef);
|
||||
Log3 $name, 3, "HEOSMaster ($name) - call Dispatcher";
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log3 $name, 3, "HEOSMaster ($name) - no Match for processing data";
|
||||
}
|
||||
@ -403,9 +472,16 @@ sub HEOSMaster_WriteReadings($$) {
|
||||
|
||||
my ($hash,$decode_json) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $value;
|
||||
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
if ( $decode_json->{heos}{command} =~ /register_for_change_events/ ) {
|
||||
my @value = split('=', $decode_json->{heos}{message});
|
||||
$value = $value[1];
|
||||
readingsBulkUpdate( $hash, 'enableChangeEvents', "$value" );
|
||||
}
|
||||
|
||||
readingsBulkUpdate( $hash, "lastCommand", $decode_json->{heos}{command} );
|
||||
readingsBulkUpdate( $hash, "lastResult", $decode_json->{heos}{result} );
|
||||
|
||||
|
136
21_HEOSPlayer.pm
136
21_HEOSPlayer.pm
@ -33,7 +33,7 @@ use warnings;
|
||||
use JSON;
|
||||
|
||||
|
||||
my $version = "0.1.17";
|
||||
my $version = "0.1.28";
|
||||
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ sub HEOSPlayer_Parse($$);
|
||||
sub HEOSPlayer_WriteReadings($$);
|
||||
sub HEOSPlayer_Set($$@);
|
||||
sub HEOSPlayer_GetUpdate($);
|
||||
sub HEOSPlayer_PreProcessingReadings($$);
|
||||
|
||||
|
||||
|
||||
@ -55,7 +56,7 @@ sub HEOSPlayer_Initialize($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{Match} = '.*{"command":."player.*';
|
||||
$hash->{Match} = '.*{"command":."player.*|.*{"command":."event/player.*';
|
||||
|
||||
# Provider
|
||||
$hash->{SetFn} = "HEOSPlayer_Set";
|
||||
@ -134,7 +135,7 @@ sub HEOSPlayer_Define($$) {
|
||||
|
||||
if( $init_done ) {
|
||||
HEOSPlayer_GetUpdate($hash);
|
||||
} else {
|
||||
} else {
|
||||
InternalTimer( gettimeofday()+15, "HEOSPlayer_GetUpdate", $hash, 0 );
|
||||
}
|
||||
|
||||
@ -153,7 +154,7 @@ sub HEOSPlayer_Undef($$) {
|
||||
|
||||
my $code = abs($pid);
|
||||
$code = $hash->{IODev}->{NAME} ."-". $code if( defined($hash->{IODev}->{NAME}) );
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - undefined with Code: $code";
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - device deleted with Code: $code";
|
||||
delete($modules{HEOSPlayer}{defptr}{$code});
|
||||
|
||||
return undef;
|
||||
@ -194,16 +195,27 @@ sub HEOSPlayer_Set($$@) {
|
||||
|
||||
my ($hash, $name, @aa) = @_;
|
||||
my ($cmd, @args) = @aa;
|
||||
|
||||
|
||||
my $pid = $hash->{PID};
|
||||
my $action;
|
||||
my $heosCmd;
|
||||
my $string = "pid=$pid";
|
||||
|
||||
|
||||
if( $cmd eq 'statusRequest' ) {
|
||||
return "usage: statusRequest" if( @args != 0 );
|
||||
if( $cmd eq 'getPlayerInfo' ) {
|
||||
return "usage: getPlayerInfo" if( @args != 0 );
|
||||
|
||||
HEOSPlayer_GetUpdate($hash);
|
||||
return undef;
|
||||
$heosCmd = 'getPlayerInfo';
|
||||
|
||||
} elsif( $cmd eq 'getPlayerState' ) {
|
||||
return "usage: getPlayerState" if( @args != 0 );
|
||||
|
||||
$heosCmd = 'getPlayerState';
|
||||
|
||||
} elsif( $cmd eq 'getNowPlayingMedia' ) {
|
||||
return "usage: getNowPlayingMedia" if( @args != 0 );
|
||||
|
||||
$heosCmd = 'getNowPlayingMedia';
|
||||
|
||||
} elsif( $cmd eq 'play' ) {
|
||||
return "usage: play" if( @args != 0 );
|
||||
@ -236,12 +248,16 @@ sub HEOSPlayer_Set($$@) {
|
||||
$action = "level=$args[0]";
|
||||
|
||||
} else {
|
||||
my $list = "statusRequest:noArg play:noArg stop:noArg pause:noArg mute:on,off volume:slider,0,5,100";
|
||||
my $list = "getPlayerInfo:noArg getPlayerState:noArg play:noArg stop:noArg pause:noArg mute:on,off volume:slider,0,5,100";
|
||||
return "Unknown argument $cmd, choose one of $list";
|
||||
}
|
||||
|
||||
IOWrite($hash,"$heosCmd","pid=$hash->{PID}&$action");
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - IOWrite: pid=$hash->{PID}&state=$action IODevHash=$hash->{IODev}";
|
||||
#IOWrite($hash,"$heosCmd","pid=$hash->{PID}&$action");
|
||||
|
||||
$string .= "&$action" if( defined($action));
|
||||
|
||||
IOWrite($hash,"$heosCmd","$string");
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - IOWrite: $heosCmd${string} IODevHash=$hash->{IODev}";
|
||||
|
||||
return undef;
|
||||
}
|
||||
@ -250,7 +266,11 @@ sub HEOSPlayer_GetUpdate($) {
|
||||
|
||||
my $hash = shift;
|
||||
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
|
||||
IOWrite($hash,'getPlayerState',"pid=$hash->{PID}");
|
||||
IOWrite($hash,'getPlayerInfo',"pid=$hash->{PID}");
|
||||
|
||||
return undef;
|
||||
}
|
||||
@ -291,8 +311,8 @@ sub HEOSPlayer_Parse($$) {
|
||||
|
||||
} else {
|
||||
|
||||
return Log3 $name, 3, "result not success"
|
||||
unless($decode_json->{heos}{result} eq "success");
|
||||
#return Log3 $name, 3, "result not success"
|
||||
#unless($decode_json->{heos}{result} eq "success"); # Klappt bei Events nicht!! Lieber Fehlermeldung im Reading
|
||||
|
||||
|
||||
if( defined($decode_json->{payload}{pid}) ) {
|
||||
@ -328,30 +348,27 @@ sub HEOSPlayer_WriteReadings($$) {
|
||||
|
||||
my ($hash,$decode_json) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $value;
|
||||
|
||||
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - write data to readings";
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - processing data to write readings";
|
||||
|
||||
|
||||
|
||||
|
||||
############################
|
||||
#### Status des Players
|
||||
|
||||
#### Aufbereiten der Daten soweit nötig (bei Events zum Beispiel)
|
||||
|
||||
my ($reading,$value) = HEOSPlayer_PreProcessingReadings($hash,$decode_json)
|
||||
if( $decode_json->{heos}{message} =~ /^pid=/ );
|
||||
|
||||
|
||||
############################
|
||||
#### schreiben der Readings
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate( $hash, $reading, $value ) if( defined($reading) and defined($value));
|
||||
|
||||
if ( $decode_json->{heos}{command} =~ /set_play_state/ ) {
|
||||
my @value = split('&', $decode_json->{heos}{message});
|
||||
$value = substr($value[1],6);
|
||||
readingsBulkUpdate( $hash, 'state', "$value" );
|
||||
|
||||
} elsif ( $decode_json->{heos}{command} =~ /set_volume/ ) {
|
||||
my @value = split('&', $decode_json->{heos}{message});
|
||||
$value = substr($value[1],6);
|
||||
readingsBulkUpdate( $hash, 'volume', "$value" );
|
||||
|
||||
} else {
|
||||
readingsBulkUpdate( $hash, 'state', 'Unknown' );
|
||||
}
|
||||
|
||||
### PlayerInfos
|
||||
readingsBulkUpdate( $hash, 'name', $decode_json->{payload}{name} );
|
||||
readingsBulkUpdate( $hash, 'gid', $decode_json->{payload}{gid} );
|
||||
readingsBulkUpdate( $hash, 'model', $decode_json->{payload}{model} );
|
||||
@ -360,15 +377,64 @@ sub HEOSPlayer_WriteReadings($$) {
|
||||
readingsBulkUpdate( $hash, 'lineout', $decode_json->{payload}{lineout} );
|
||||
readingsBulkUpdate( $hash, 'control', $decode_json->{payload}{control} );
|
||||
readingsBulkUpdate( $hash, 'ip-address', $decode_json->{payload}{ip} );
|
||||
|
||||
Log3 $name, 5, "HEOSPlayer ($name) - readings set for $name";
|
||||
|
||||
### playing Infos
|
||||
readingsBulkUpdate( $hash, 'type', $decode_json->{payload}{type} );
|
||||
readingsBulkUpdate( $hash, 'song', $decode_json->{payload}{song} );
|
||||
readingsBulkUpdate( $hash, 'album', $decode_json->{payload}{album} );
|
||||
readingsBulkUpdate( $hash, 'artist', $decode_json->{payload}{artist} );
|
||||
readingsBulkUpdate( $hash, 'imageUrl', $decode_json->{payload}{image_url} );
|
||||
readingsBulkUpdate( $hash, 'mid', $decode_json->{payload}{mid} );
|
||||
readingsBulkUpdate( $hash, 'qid', $decode_json->{payload}{qid} );
|
||||
readingsBulkUpdate( $hash, 'sid', $decode_json->{payload}{sid} );
|
||||
readingsBulkUpdate( $hash, 'station', $decode_json->{payload}{station} );
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
|
||||
Log3 $name, 5, "HEOSPlayer ($name) - readings set for $name";
|
||||
return undef;
|
||||
}
|
||||
|
||||
###############
|
||||
## little Helpers
|
||||
|
||||
sub HEOSPlayer_PreProcessingReadings($$) {
|
||||
|
||||
my ($hash,$decode_json) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $reading;
|
||||
my $value;
|
||||
|
||||
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - preprocessing readings";
|
||||
|
||||
if ( $decode_json->{heos}{command} =~ /play_state/ ) {
|
||||
|
||||
my @value = split('&', $decode_json->{heos}{message});
|
||||
$value = substr($value[1],6);
|
||||
$reading = 'state';
|
||||
|
||||
} elsif ( $decode_json->{heos}{command} =~ /set_volume/ ) {
|
||||
|
||||
my @value = split('&', $decode_json->{heos}{message});
|
||||
$value = substr($value[1],6);
|
||||
$reading = 'volume';
|
||||
|
||||
} elsif ( $decode_json->{heos}{command} =~ /volume_changed/ ) {
|
||||
|
||||
my @value = split('&', $decode_json->{heos}{message});
|
||||
$value = substr($value[1],6);
|
||||
$reading = 'volume';
|
||||
|
||||
} else {
|
||||
|
||||
Log3 $name, 3, "HEOSPlayer ($name) - no match found";
|
||||
}
|
||||
|
||||
return($reading,$value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user