diff --git a/fhem/FHEM/59_Wunderground.pm b/fhem/FHEM/59_Wunderground.pm
index 54dd0589e..c3f77d541 100644
--- a/fhem/FHEM/59_Wunderground.pm
+++ b/fhem/FHEM/59_Wunderground.pm
@@ -1,30 +1,7 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 59_Wunderground.pm
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
# http://api.wunderground.com/weather/api
-
+#
package main;
use strict;
@@ -36,9 +13,7 @@ use Encode qw(encode_utf8 decode_utf8);
use Unit;
use Data::Dumper;
-sub Wunderground_Hash2Readings($$;$);
-
-###################################
+# initialize ##################################################################
sub Wunderground_Initialize($) {
my ($hash) = @_;
@@ -47,15 +22,15 @@ sub Wunderground_Initialize($) {
my $webhookFWinstance =
join( ",", devspec2array('TYPE=FHEMWEB:FILTER=TEMPORARY!=1') );
- $hash->{SetFn} = "Wunderground_Set";
$hash->{DefFn} = "Wunderground_Define";
- $hash->{AttrFn} = "Wunderground_Attr";
$hash->{UndefFn} = "Wunderground_Undefine";
+ $hash->{SetFn} = "Wunderground_Set";
+ $hash->{AttrFn} = "Wunderground_Attr";
$hash->{DbLog_splitFn} = "Unit_DbLog_split";
$hash->{parseParams} = 1;
$hash->{AttrList} =
-"disable:0,1 timeout:1,2,3,4,5 pollInterval:300,450,600,750,900 wu_lang:en,de,at,ch,nl,fr,pl wu_pws:1,0 wu_bestfct:1,0 stateReadings stateReadingsFormat:0,1 "
+"disable:0,1 disabledForIntervals do_not_notify:1,0 timeout:1,2,3,4,5 pollInterval:300,450,600,750,900 wu_lang:en,de,at,ch,nl,fr,pl wu_pws:1,0 wu_bestfct:1,0 stateReadings stateReadingsFormat:0,1 "
. "wu_features:multiple-strict,alerts,almanac,astronomy,conditions,currenthurricane,forecast,forecast10day,hourly,hourly10day "
. $readingFnAttributes;
@@ -228,11 +203,116 @@ sub Wunderground_Initialize($) {
'wind_speed' => { rtype => 'kmph', formula_symbol => 'Ws' },
'wind_speed_mph' => { rtype => 'mph', formula_symbol => 'Ws' }
};
-
- return;
}
-#####################################
+# regular Fn ##################################################################
+sub Wunderground_Define($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+ my $infix = "Wunderground";
+
+ Log3 $name, 5, "Wunderground $name: called function Wunderground_Define()";
+
+ eval {
+ require JSON;
+ import JSON qw( decode_json );
+ };
+ return "Please install Perl JSON to use module Wunderground"
+ if ($@);
+
+ if ( int(@$a) < 2 ) {
+ my $msg = "Wrong syntax: define Wunderground ";
+ Log3 $name, 4, $msg;
+ return $msg;
+ }
+
+ $hash->{TYPE} = "Wunderground";
+
+ $hash->{API_KEY} = @$a[2];
+ $hash->{QUERY} = @$a[3];
+
+ $hash->{QUERY} = "pws:" . $hash->{QUERY}
+ if ( $hash->{QUERY} =~ /^[A-Z]{3,}\d{1,}$/ );
+
+ if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
+ fhem 'attr ' . $name . ' stateReadings temp_c humidity';
+ fhem 'attr ' . $name . ' stateReadingsFormat 1';
+ fhem 'attr ' . $name . ' wu_features astronomy,conditions,forecast';
+ }
+
+ # start the status update timer
+ Wunderground_GetStatus( $hash, 2 );
+
+ return undef;
+}
+
+sub Wunderground_Undefine($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+
+ if ( defined( $hash->{fhem}{infix} ) ) {
+ Wunderground_removeExtension( $hash->{fhem}{infix} );
+ }
+
+ Log3 $name, 5,
+ "Wunderground $name: called function Wunderground_Undefine()";
+
+ # Stop the internal GetStatus-Loop and exit
+ RemoveInternalTimer($hash);
+
+ # release reverse pointer
+ delete $modules{Wunderground}{defptr}{$name};
+
+ return undef;
+}
+
+sub Wunderground_Set($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+
+ Log3 $name, 5, "Wunderground $name: called function Wunderground_Set()";
+
+ return "Argument is missing" if ( int(@$a) < 1 );
+
+ my $usage = "Unknown argument " . @$a[1] . ", choose one of update:noArg";
+
+ my $cmd = '';
+ my $result;
+
+ # update
+ if ( lc( @$a[1] ) eq "update" ) {
+ Log3 $name, 3, "Wunderground set $name " . @$a[1];
+ Wunderground_GetStatus($hash);
+ }
+
+ # return usage hint
+ else {
+ return $usage;
+ }
+
+ return $result;
+}
+
+sub Wunderground_Attr(@) {
+ my ( $cmd, $name, $attrName, $attrVal ) = @_;
+ my $hash = $defs{$name};
+
+ Log3 $name, 5, "Wunderground $name: called function Wunderground_Attr()";
+
+ return
+"Invalid value for attribute $attrName: minimum value is 1 second, maximum 5 seconds"
+ if ( $attrVal
+ && $attrName eq "timeout"
+ && ( $attrVal < 1 || $attrVal > 5 ) );
+
+ return
+ "Invalid value for attribute $attrName: minimum value is 300 seconds"
+ if ( $attrVal && $attrName eq "pollInterval" && $attrVal < 300 );
+
+ return undef;
+}
+
+# module Fn ####################################################################
sub Wunderground_GetStatus($;$) {
my ( $hash, $delay ) = @_;
my $name = $hash->{NAME};
@@ -286,102 +366,6 @@ sub Wunderground_GetStatus($;$) {
return;
}
-###################################
-sub Wunderground_Set($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
-
- Log3 $name, 5, "Wunderground $name: called function Wunderground_Set()";
-
- return "Argument is missing" if ( int(@$a) < 1 );
-
- my $usage = "Unknown argument " . @$a[1] . ", choose one of update:noArg";
-
- my $cmd = '';
- my $result;
-
- # update
- if ( lc( @$a[1] ) eq "update" ) {
- Log3 $name, 3, "Wunderground set $name " . @$a[1];
- Wunderground_GetStatus($hash);
- }
-
- # return usage hint
- else {
- return $usage;
- }
-
- return $result;
-}
-
-###################################
-sub Wunderground_Define($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
- my $infix = "Wunderground";
-
- Log3 $name, 5, "Wunderground $name: called function Wunderground_Define()";
-
- eval {
- require JSON;
- import JSON qw( decode_json );
- };
- return "Please install Perl JSON to use module Wunderground"
- if ($@);
-
- if ( int(@$a) < 2 ) {
- my $msg = "Wrong syntax: define Wunderground ";
- Log3 $name, 4, $msg;
- return $msg;
- }
-
- $hash->{TYPE} = "Wunderground";
-
- $hash->{API_KEY} = @$a[2];
- $hash->{QUERY} = @$a[3];
-
- $hash->{QUERY} = "pws:" . $hash->{QUERY}
- if ( $hash->{QUERY} =~ /^[A-Z]{3,}\d{1,}$/ );
-
- if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
- fhem 'attr ' . $name . ' stateReadings temp_c humidity';
- fhem 'attr ' . $name . ' stateReadingsFormat 1';
- fhem 'attr ' . $name . ' wu_features astronomy,conditions,forecast';
- }
-
- # start the status update timer
- Wunderground_GetStatus( $hash, 2 );
-
- return;
-}
-
-###################################
-sub Wunderground_Attr(@) {
- my ( $cmd, $name, $attrName, $attrVal ) = @_;
- my $hash = $defs{$name};
-
- Log3 $name, 5, "Wunderground $name: called function Wunderground_Attr()";
-
- return
-"Invalid value for attribute $attrName: minimum value is 1 second, maximum 5 seconds"
- if ( $attrVal
- && $attrName eq "timeout"
- && ( $attrVal < 1 || $attrVal > 5 ) );
-
- return
- "Invalid value for attribute $attrName: minimum value is 300 seconds"
- if ( $attrVal && $attrName eq "pollInterval" && $attrVal < 300 );
-
- return undef;
-}
-
-############################################################################################################
-#
-# Begin of helper functions
-#
-############################################################################################################
-
-###################################
sub Wunderground_SendCommand($$) {
my ( $hash, $features ) = @_;
my $name = $hash->{NAME};
@@ -420,7 +404,6 @@ sub Wunderground_SendCommand($$) {
return;
}
-###################################
sub Wunderground_ReceiveCommand($$$) {
my ( $param, $err, $data ) = @_;
my $hash = $param->{hash};
@@ -495,7 +478,8 @@ sub Wunderground_ReceiveCommand($$$) {
return;
}
-###################################
+sub Wunderground_Hash2Readings($$;$);
+
sub Wunderground_Hash2Readings($$;$) {
my ( $hash, $h, $r ) = @_;
my $name = $hash->{NAME};
@@ -991,27 +975,6 @@ sub Wunderground_Hash2Readings($$;$) {
return "ok" if ( !$loop );
}
-###################################
-sub Wunderground_Undefine($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
-
- if ( defined( $hash->{fhem}{infix} ) ) {
- Wunderground_removeExtension( $hash->{fhem}{infix} );
- }
-
- Log3 $name, 5,
- "Wunderground $name: called function Wunderground_Undefine()";
-
- # Stop the internal GetStatus-Loop and exit
- RemoveInternalTimer($hash);
-
- # release reverse pointer
- delete $modules{Wunderground}{defptr}{$name};
-
- return;
-}
-
1;
=pod
diff --git a/fhem/FHEM/70_ENIGMA2.pm b/fhem/FHEM/70_ENIGMA2.pm
index 804cb0d57..cdce7fb74 100644
--- a/fhem/FHEM/70_ENIGMA2.pm
+++ b/fhem/FHEM/70_ENIGMA2.pm
@@ -1,68 +1,28 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 70_ENIGMA2.pm
-# An FHEM Perl module for controlling ENIGMA2 based TV receivers
-# via network connection.
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
package main;
-
-#use 5.012;
use strict;
use warnings;
use Data::Dumper;
+use Time::Local;
+use Encode qw(encode_utf8 decode_utf8);
+
use HttpUtils;
-use Encode;
-no if $] >= 5.017011, warnings => 'experimental';
-
-no warnings "all";
-
-sub ENIGMA2_Set($@);
-sub ENIGMA2_Get($@);
-sub ENIGMA2_GetStatus($;$);
-sub ENIGMA2_Define($$);
-sub ENIGMA2_Undefine($$);
-
-#########################
-# Forward declaration for remotecontrol module
-sub ENIGMA2_RClayout_TV();
-sub ENIGMA2_RCmakenotify($$);
-
-###################################
+# initialize ##################################################################
sub ENIGMA2_Initialize($) {
my ($hash) = @_;
Log3 $hash, 5, "ENIGMA2_Initialize: Entering";
- $hash->{parseParams} = 1;
- $hash->{GetFn} = "ENIGMA2_Get";
- $hash->{SetFn} = "ENIGMA2_Set";
$hash->{DefFn} = "ENIGMA2_Define";
$hash->{UndefFn} = "ENIGMA2_Undefine";
+ $hash->{SetFn} = "ENIGMA2_Set";
+ $hash->{GetFn} = "ENIGMA2_Get";
+ $hash->{parseParams} = 1;
$hash->{AttrList} =
-"https:0,1 http-method:GET,POST http-noshutdown:1,0 disable:0,1 bouquet-tv bouquet-radio timeout remotecontrol:standard,advanced,keyboard lightMode:0,1 ignoreState:0,1 macaddr:textField model wakeupCmd:textField WOL_useUdpBroadcast WOL_port WOL_mode:EW,UDP,BOTH "
+"disable:1,0 disabledForIntervals do_not_notify:1,0 https:0,1 http-method:GET,POST http-noshutdown:1,0 disable:0,1 bouquet-tv bouquet-radio timeout remotecontrol:standard,advanced,keyboard lightMode:0,1 ignoreState:0,1 macaddr:textField model wakeupCmd:textField WOL_useUdpBroadcast WOL_port WOL_mode:EW,UDP,BOTH "
. $readingFnAttributes;
$data{RC_layout}{ENIGMA2_DreamMultimedia_DM500_DM800_SVG} =
@@ -76,16 +36,10 @@ sub ENIGMA2_Initialize($) {
$data{RC_layout}{ENIGMA2_DreamMultimedia_RC10_SVG} =
"ENIGMA2_RClayout_RC10_SVG";
$data{RC_layout}{ENIGMA2_DreamMultimedia_RC10} = "ENIGMA2_RClayout_RC10";
-
-# $data{RC_layout}{ENIGMA2_VUplus_Solo2_SVG} = "ENIGMA2_RClayout_VUplusSolo2_SVG";
-# $data{RC_layout}{ENIGMA2_VUplus_Solo2} = "ENIGMA2_RClayout_VUplusSolo2";
$data{RC_layout}{ENIGMA2_VUplus_Duo2_SVG} =
"ENIGMA2_RClayout_VUplusDuo2_SVG";
$data{RC_layout}{ENIGMA2_VUplus_Duo2} = "ENIGMA2_RClayout_VUplusDuo2";
-
-# $data{RC_layout}{ENIGMA2_VUplus_Ultimo_SVG} = "ENIGMA2_RClayout_VUplusUltimo_SVG";
-# $data{RC_layout}{ENIGMA2_VUplus_Ultimo} = "ENIGMA2_RClayout_VUplusUltimo";
- $data{RC_makenotify}{ENIGMA2} = "ENIGMA2_RCmakenotify";
+ $data{RC_makenotify}{ENIGMA2} = "ENIGMA2_RCmakenotify";
# 98_powerMap.pm support
$hash->{powerMap} = {
@@ -104,76 +58,105 @@ sub ENIGMA2_Initialize($) {
},
},
};
-
- return;
}
-#####################################
-sub ENIGMA2_GetStatus($;$) {
- my ( $hash, $update ) = @_;
- my $name = $hash->{NAME};
- my $interval = $hash->{INTERVAL};
-
- Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_GetStatus()";
-
- RemoveInternalTimer($hash);
- InternalTimer( gettimeofday() + $interval, "ENIGMA2_GetStatus", $hash, 0 );
-
- return
- if ( AttrVal( $name, "disable", 0 ) == 1 );
-
- if ( !$update ) {
- ENIGMA2_SendCommand( $hash, "powerstate" );
- }
- else {
- ENIGMA2_SendCommand( $hash, "getcurrent" );
- }
-
- return;
-}
-
-###################################
-sub ENIGMA2_Get($@) {
+# regular Fn ##################################################################
+sub ENIGMA2_Define($$) {
my ( $hash, $a, $h ) = @_;
my $name = shift @$a;
- my $what;
+ my $type = shift @$a;
- Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_Get()";
+ Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_Define()";
- return "argument is missing" if ( int(@$a) < 1 );
+ eval { require XML::Simple; };
+ return "Please install Perl XML::Simple to use module ENIGMA2"
+ if ($@);
- $what = shift @$a;
+ if ( int(@$a) < 1 ) {
+ my $msg =
+ "Wrong syntax: "
+ . "define ENIGMA2 [[[[] []] []]";
+ Log3 $name, 4, $msg;
+ return $msg;
+ }
- if ( $what =~
-/^(power|input|volume|mute|channel|currentMedia|currentTitle|nextTitle|providername|servicevideosize)$/
- )
- {
- if ( ReadingsVal( $name, $what, "" ) ne "" ) {
- return ReadingsVal( $name, $what, "" );
+ $hash->{URL} = shift @$a;
+
+ # use port 80 if not defined
+ my $port = shift @$a || 80;
+ return "Port parameter needs to be of type integer"
+ unless ( $port =~ /^\d+$/ );
+
+ # use interval of 45sec if not defined
+ my $interval = shift @$a || 45;
+ return "Interval parameter needs to be of type integer"
+ unless ( $interval =~ /^\d+$/ );
+ $hash->{INTERVAL} = $interval;
+
+ my $http_user = shift @$a;
+ my $http_passwd = shift @$a;
+ $hash->{URL} = "$http_user:$http_passwd@" . $hash->{URL}
+ if ( $hash->{URL} !~ /^https?:\/\//
+ && $hash->{URL} !~ /^\w+(:\w+)?\@/
+ && $http_user
+ && $http_passwd );
+ $hash->{URL} = "$http_user@" . $hash->{URL}
+ if ( $hash->{URL} !~ /^https?:\/\//
+ && $hash->{URL} !~ /^\w+(:\w+)?\@/
+ && $http_user
+ && !$http_passwd );
+ $hash->{URL} = "http://" . $hash->{URL}
+ unless ( $hash->{URL} =~ /^https?:\/\// || $port eq "443" );
+ $hash->{URL} = "https://" . $hash->{URL}
+ if ( $hash->{URL} !~ /^https?:\/\// && $port eq "443" );
+ $hash->{URL} .= ":$port"
+ unless ( $hash->{URL} =~ /:\d+$/ || $port eq "80" || $port eq "443" );
+ $hash->{URL} .= "/" unless ( $hash->{URL} =~ /\/$/ );
+
+ # set default settings on first define
+ if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
+
+ # use http-method POST for FritzBox environment as GET does not seem to
+ # work properly. Might restrict use to newer
+ # ENIGMA2 Webif versions or use of OWIF only.
+ if ( exists $ENV{CONFIG_PRODUKT_NAME}
+ && defined $ENV{CONFIG_PRODUKT_NAME} )
+ {
+ $attr{$name}{"http-method"} = 'POST';
}
+
+ # default method is GET and should be compatible to most
+ # ENIGMA2 Webif versions
else {
- return "no such reading: $what";
+ $attr{$name}{"http-method"} = 'GET';
}
+ $attr{$name}{webCmd} = 'channel:input';
+ $attr{$name}{devStateIcon} =
+ 'on:rc_GREEN:off off:rc_YELLOW:on absent:rc_STOP:on';
+ $attr{$name}{icon} = 'dreambox';
}
- # streamUrl
- elsif ( $what eq "streamUrl" ) {
- my $device = "etc";
- $device = "phone" if ( defined $a->[0] );
- return
- $hash->{URL}
- . "/web/stream.m3u?ref="
- . urlEncode( ReadingsVal( $name, "servicereference", "-" ) )
- . "&device=$device";
- }
+ # start the status update timer
+ RemoveInternalTimer($hash);
+ InternalTimer( gettimeofday() + 2, "ENIGMA2_GetStatus", $hash, 1 );
- else {
- return
-"Unknown argument $what, choose one of power:noArg input:noArg volume:noArg mute:noArg channel:noArg currentMedia:noArg currentTitle:noArg nextTitle:noArg providername:noArg servicevideosize:noArg streamUrl:,mobile ";
- }
+ return undef;
}
-###################################
+sub ENIGMA2_Undefine($$) {
+ my ( $hash, $arg ) = @_;
+ my $name = $hash->{NAME};
+
+ Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_Undefine()";
+
+ # Stop the internal GetStatus-Loop and exit
+ RemoveInternalTimer($hash);
+
+ return undef;
+}
+
+sub ENIGMA2_Set($@);
+
sub ENIGMA2_Set($@) {
my ( $hash, $a, $h ) = @_;
my $name = shift @$a;
@@ -359,8 +342,8 @@ sub ENIGMA2_Set($@) {
return "wake-up command sent to MAC $macAddr";
}
else {
- return
-"Device MAC address unknown. Please turn on the device manually once or set attribute macaddr.";
+ return "Device MAC address unknown. "
+ . "Please turn on the device manually once or set attribute macaddr.";
}
}
else {
@@ -423,8 +406,8 @@ sub ENIGMA2_Set($@) {
$cmd = "set=set" . $a->[0];
}
else {
- return
-"Argument does not seem to be a valid integer between 0 and 100";
+ return "Argument does not seem to be a "
+ . "valid integer between 0 and 100";
}
$result = ENIGMA2_SendCommand( $hash, "vol", $cmd );
}
@@ -507,8 +490,8 @@ sub ENIGMA2_Set($@) {
$timeout = $timeout2;
}
- return
-"No type argument given, choose one of yesno info message attention"
+ return "No type argument given, "
+ . "choose one of yesno info message attention"
unless ( defined($type) );
return "No timeout argument given"
@@ -605,8 +588,8 @@ sub ENIGMA2_Set($@) {
# channel
elsif ( lc($set) eq "channel" ) {
- return
-"No argument given, choose one of channel channelNumber servicereference "
+ return "No argument given, "
+ . "choose one of channel channelNumber servicereference "
if ( !defined( $a->[0] ) );
if ( defined( $a->[0] )
@@ -773,98 +756,52 @@ sub ENIGMA2_Set($@) {
return $usage;
}
- return;
+ return undef;
}
-###################################
-sub ENIGMA2_Define($$) {
+sub ENIGMA2_Get($@) {
my ( $hash, $a, $h ) = @_;
my $name = shift @$a;
- my $type = shift @$a;
+ my $what;
- Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_Define()";
+ Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_Get()";
- eval { require XML::Simple; };
- return "Please install Perl XML::Simple to use module ENIGMA2"
- if ($@);
+ return "argument is missing" if ( int(@$a) < 1 );
- if ( int(@$a) < 1 ) {
- my $msg =
-"Wrong syntax: define ENIGMA2 [[[[] []] []]";
- Log3 $name, 4, $msg;
- return $msg;
- }
+ $what = shift @$a;
- $hash->{URL} = shift @$a;
-
- # use port 80 if not defined
- my $port = shift @$a || 80;
- return "Port parameter needs to be of type integer"
- unless ( $port =~ /^\d+$/ );
-
- # use interval of 45sec if not defined
- my $interval = shift @$a || 45;
- return "Interval parameter needs to be of type integer"
- unless ( $interval =~ /^\d+$/ );
- $hash->{INTERVAL} = $interval;
-
- my $http_user = shift @$a;
- my $http_passwd = shift @$a;
- $hash->{URL} = "$http_user:$http_passwd@" . $hash->{URL}
- if ( $hash->{URL} !~ /^https?:\/\//
- && $hash->{URL} !~ /^\w+(:\w+)?\@/
- && $http_user
- && $http_passwd );
- $hash->{URL} = "$http_user@" . $hash->{URL}
- if ( $hash->{URL} !~ /^https?:\/\//
- && $hash->{URL} !~ /^\w+(:\w+)?\@/
- && $http_user
- && !$http_passwd );
- $hash->{URL} = "http://" . $hash->{URL}
- unless ( $hash->{URL} =~ /^https?:\/\// || $port eq "443" );
- $hash->{URL} = "https://" . $hash->{URL}
- if ( $hash->{URL} !~ /^https?:\/\// && $port eq "443" );
- $hash->{URL} .= ":$port"
- unless ( $hash->{URL} =~ /:\d+$/ || $port eq "80" || $port eq "443" );
- $hash->{URL} .= "/" unless ( $hash->{URL} =~ /\/$/ );
-
- # set default settings on first define
- if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
-
- # use http-method POST for FritzBox environment as GET does not seem to
- # work properly. Might restrict use to newer
- # ENIGMA2 Webif versions or use of OWIF only.
- if ( exists $ENV{CONFIG_PRODUKT_NAME}
- && defined $ENV{CONFIG_PRODUKT_NAME} )
- {
- $attr{$name}{"http-method"} = 'POST';
+ if ( $what =~
+/^(power|input|volume|mute|channel|currentMedia|currentTitle|nextTitle|providername|servicevideosize)$/
+ )
+ {
+ if ( ReadingsVal( $name, $what, "" ) ne "" ) {
+ return ReadingsVal( $name, $what, "" );
}
-
- # default method is GET and should be compatible to most
- # ENIGMA2 Webif versions
else {
- $attr{$name}{"http-method"} = 'GET';
+ return "no such reading: $what";
}
- $attr{$name}{webCmd} = 'channel:input';
- $attr{$name}{devStateIcon} =
- 'on:rc_GREEN:off off:rc_YELLOW:on absent:rc_STOP:on';
- $attr{$name}{icon} = 'dreambox';
}
- # start the status update timer
- RemoveInternalTimer($hash);
- InternalTimer( gettimeofday() + 2, "ENIGMA2_GetStatus", $hash, 1 );
+ # streamUrl
+ elsif ( $what eq "streamUrl" ) {
+ my $device = "etc";
+ $device = "phone" if ( defined $a->[0] );
+ return
+ $hash->{URL}
+ . "/web/stream.m3u?ref="
+ . urlEncode( ReadingsVal( $name, "servicereference", "-" ) )
+ . "&device=$device";
+ }
- return;
+ else {
+ return "Unknown argument $what, "
+ . "choose one of power:noArg input:noArg volume:noArg mute:noArg channel:noArg currentMedia:noArg currentTitle:noArg nextTitle:noArg providername:noArg servicevideosize:noArg streamUrl:,mobile ";
+ }
+
+ return undef;
}
-############################################################################################################
-#
-# Begin of helper functions
-#
-############################################################################################################
-
-###################################
+# module Fn ####################################################################
sub ENIGMA2_SendCommand($$;$$) {
my ( $hash, $service, $cmd, $type ) = @_;
my $name = $hash->{NAME};
@@ -930,7 +867,7 @@ sub ENIGMA2_SendCommand($$;$$) {
'Accept-Charset' => 'UTF-8',
},
sslargs => {
- SSL_verify_mode => 0,
+ SSL_verify_mode => 'SSL_VERIFY_NONE',
},
}
);
@@ -967,7 +904,7 @@ sub ENIGMA2_SendCommand($$;$$) {
'Accept-Charset' => 'UTF-8',
},
sslargs => {
- SSL_verify_mode => 0,
+ SSL_verify_mode => 'SSL_VERIFY_NONE',
},
}
);
@@ -984,7 +921,6 @@ sub ENIGMA2_SendCommand($$;$$) {
return;
}
-###################################
sub ENIGMA2_ReceiveCommand($$$) {
my ( $param, $err, $data ) = @_;
my $hash = $param->{hash};
@@ -1059,7 +995,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
if ( !defined($cmd) || $cmd eq "" ) {
Log3 $name, 5,
-"ENIGMA2 $name: RES ERROR $service - unable to parse malformed XML: $@\n"
+ "ENIGMA2 $name: "
+ . "RES ERROR $service - unable to parse malformed XML: $@\n"
. $data;
}
else {
@@ -1547,7 +1484,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
}
else {
Log3 $name, 2,
-"ENIGMA2 $name: ERROR: boxinfo could not be read - /about sent malformed response";
+ "ENIGMA2 $name: "
+ . "ERROR: boxinfo could not be read - /about sent malformed response";
}
}
@@ -1580,7 +1518,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
|| $return->{e2service}{$e2reading} eq "True" )
{
Log3 $name, 5,
-"ENIGMA2 $name: transforming value of $reading to lower case";
+ "ENIGMA2 $name: "
+ . "transforming value of $reading to lower case";
$return->{e2service}{$e2reading} =
lc( $return->{e2service}{$e2reading} );
@@ -1615,7 +1554,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
&& $servicetype[2] ne "10" )
{
Log3 $name, 5,
-"ENIGMA2 $name: detected servicereference type: tv";
+ "ENIGMA2 $name: "
+ . "detected servicereference type: tv";
readingsBulkUpdate( $hash, "input", "tv" )
if (
ReadingsVal( $name, "input", "" ) ne "tv" );
@@ -1628,19 +1568,22 @@ sub ENIGMA2_ReceiveCommand($$$) {
)
{
Log3 $name, 5,
-"ENIGMA2 $name: detected servicereference type: radio";
+ "ENIGMA2 $name: "
+ . "detected servicereference type: radio";
readingsBulkUpdateIfChanged( $hash, "input",
"radio" );
}
else {
Log3 $name, 2,
-"ENIGMA2 $name: ERROR: servicereference type could not be detected (neither 'tv' nor 'radio')";
+ "ENIGMA2 $name: "
+ . "ERROR: servicereference type could not be detected (neither 'tv' nor 'radio')";
}
}
}
else {
Log3 $name, 5,
-"ENIGMA2 $name: received no value for reading $reading";
+ "ENIGMA2 $name: "
+ . "received no value for reading $reading";
if ( ReadingsVal( $name, $reading, "" ) ne "-" ) {
readingsBulkUpdate( $hash, $reading, "-" );
@@ -1692,7 +1635,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
&& $eventNow->{$e2reading} ne "" )
{
Log3 $name, 5,
-"ENIGMA2 $name: detected valid reading $e2reading for current event";
+ "ENIGMA2 $name: "
+ . "detected valid reading $e2reading for current event";
if ( ReadingsVal( $name, $reading, "" ) ne
$eventNow->{$e2reading} )
@@ -1708,7 +1652,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
}
else {
Log3 $name, 5,
-"ENIGMA2 $name: no valid reading $e2reading found for current event";
+ "ENIGMA2 $name: "
+ . "no valid reading $e2reading found for current event";
if ( ReadingsVal( $name, $reading, "" ) ne "-" ) {
readingsBulkUpdate( $hash, $reading, "-" );
@@ -1727,7 +1672,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
&& $eventNext->{$e2reading} ne "" )
{
Log3 $name, 5,
-"ENIGMA2 $name: detected valid reading $e2reading for next event";
+ "ENIGMA2 $name: "
+ . "detected valid reading $e2reading for next event";
if ( ReadingsVal( $name, $readingN, "" ) ne
$eventNext->{$e2reading} )
@@ -1743,7 +1689,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
}
else {
Log3 $name, 5,
-"ENIGMA2 $name: no valid reading $e2reading found for next event";
+ "ENIGMA2 $name: "
+ . "no valid reading $e2reading found for next event";
if ( ReadingsVal( $name, $readingN, "" ) ne "-" ) {
readingsBulkUpdate( $hash, $readingN, "-" );
@@ -1823,7 +1770,8 @@ sub ENIGMA2_ReceiveCommand($$$) {
}
else {
Log3 $name, 2,
-"ENIGMA2 $name: ERROR: current service info could not be read - /getcurrent sent malformed response";
+ "ENIGMA2 $name: "
+ . "ERROR: current service info could not be read - /getcurrent sent malformed response";
}
}
@@ -2018,13 +1966,13 @@ sub ENIGMA2_ReceiveCommand($$$) {
$readingname = "recordings" . $ri . "_servicename";
readingsBulkUpdateIfChanged( $hash, $readingname, $2 )
if ( $recordings{$ri}{servicename} =~
-/^(\s*[\[\(\{].*[\]\)\}]\s*)?([\s\w\(\)_-]+)(\s*[\[\(\{].*[\]\)\}]\s*)?$/
+m/^(\s*[\[\(\{].*[\]\)\}]\s*)?([\s\w\(\)_-]+)(\s*[\[\(\{].*[\]\)\}]\s*)?$/
);
$readingname = "recordings" . $ri . "_name";
readingsBulkUpdateIfChanged( $hash, $readingname, $2 )
if ( $recordings{$ri}{name} =~
-/^(\s*[\[\(\{].*[\]\)\}]\s*)?([\s\w\(\)_-]+)(\s*[\[\(\{].*[\]\)\}]\s*)?$/
+m/^(\s*[\[\(\{].*[\]\)\}]\s*)?([\s\w\(\)_-]+)(\s*[\[\(\{].*[\]\)\}]\s*)?$/
);
}
}
@@ -2192,20 +2140,29 @@ sub ENIGMA2_ReceiveCommand($$$) {
return;
}
-###################################
-sub ENIGMA2_Undefine($$) {
- my ( $hash, $arg ) = @_;
- my $name = $hash->{NAME};
+sub ENIGMA2_GetStatus($;$) {
+ my ( $hash, $update ) = @_;
+ my $name = $hash->{NAME};
+ my $interval = $hash->{INTERVAL};
- Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_Undefine()";
+ Log3 $name, 5, "ENIGMA2 $name: called function ENIGMA2_GetStatus()";
- # Stop the internal GetStatus-Loop and exit
RemoveInternalTimer($hash);
+ InternalTimer( gettimeofday() + $interval, "ENIGMA2_GetStatus", $hash, 0 );
+
+ return
+ if ( AttrVal( $name, "disable", 0 ) == 1 );
+
+ if ( !$update ) {
+ ENIGMA2_SendCommand( $hash, "powerstate" );
+ }
+ else {
+ ENIGMA2_SendCommand( $hash, "getcurrent" );
+ }
return;
}
-###################################
sub ENIGMA2_GetStateAV($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -2227,316 +2184,6 @@ sub ENIGMA2_GetStateAV($) {
}
}
-###################################
-sub ENIGMA2_wake ($$) {
- if ( !$modules{WOL}{LOADED}
- && -f "$attr{global}{modpath}/FHEM/98_WOL.pm" )
- {
- my $ret = CommandReload( undef, "98_WOL" );
- return $ret if ($ret);
- }
- elsif ( !-f "$attr{global}{modpath}/FHEM/98_WOL.pm" ) {
- return "Missing module: $attr{global}{modpath}/FHEM/98_WOL.pm";
- }
-
- my ( $name, $mac ) = @_;
- my $hash = $defs{$name};
- my $host =
- AttrVal( $name, "WOL_useUdpBroadcast",
- AttrVal( $name, "useUdpBroadcast", "255.255.255.255" ) );
- my $port = AttrVal( $name, "WOL_port", "9" );
- my $mode = lc( AttrVal( $name, "WOL_mode", "UDP" ) );
-
- Log3 $name, 4,
- "ENIGMA2 $name: Waking up by sending Wake-On-Lan magic package to "
- . $mac;
-
- if ( $mode eq "both" || $mode eq "ew" ) {
- WOL_by_ew( $hash, $mac );
- }
- if ( $mode eq "both" || $mode eq "udp" ) {
- WOL_by_udp( $hash, $mac, $host, $port );
- }
-}
-
-#####################################
-# Callback from 95_remotecontrol for command makenotify.
-sub ENIGMA2_RCmakenotify($$) {
- my ( $nam, $ndev ) = @_;
- my $nname = "notify_$nam";
-
- fhem( "define $nname notify $nam set $ndev remoteControl " . '$EVENT', 1 );
- Log3 undef, 2, "[remotecontrol:ENIGMA2] Notify created: $nname";
- return "Notify created by ENIGMA2: $nname";
-}
-
-#####################################
-# RC layouts
-
-# Dreambox DM500 + DM800 with SVG
-sub ENIGMA2_RClayout_DM800_SVG() {
- my @row;
-
- $row[0] = ":rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
- $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[2] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
- $row[3] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
- $row[4] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
- $row[5] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
- $row[6] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[7] = "VOLUMEUP:rc_VOLPLUS.svg,MUTE:rc_MUTE.svg,CHANNELUP:rc_UP.svg";
- $row[8] =
- "VOLUMEDOWN:rc_VOLMINUS.svg,EXIT:rc_EXIT.svg,CHANNELDOWN:rc_DOWN.svg";
- $row[9] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[10] = "INFO:rc_INFO.svg,UP:rc_UP.svg,MENU:rc_MENU.svg";
- $row[11] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
- $row[12] = "AUDIO:rc_AUDIO.svg,DOWN:rc_DOWN.svg,VIDEO:rc_VIDEO.svg";
- $row[13] = ":rc_BLANK.svg,EXIT:rc_EXIT.svg,:rc_BLANK.svg";
-
- $row[14] =
-"RED:rc_REWred.svg,GREEN:rc_PLAYgreen.svg,YELLOW:rc_PAUSEyellow.svg,BLUE:rc_FFblue.svg";
- $row[15] =
-"TV:rc_TVstop.svg,RADIO:rc_RADIOred.svg,TEXT:rc_TEXT.svg,HELP:rc_HELP.svg";
-
- $row[16] = "attr rc_iconpath icons/remotecontrol";
- $row[17] = "attr rc_iconprefix black_btn_";
- return @row;
-}
-
-# Dreambox DM500 + DM800 with PNG
-sub ENIGMA2_RClayout_DM800() {
- my @row;
-
- $row[0] = ":blank,:blank,POWER:POWEROFF";
- $row[1] = ":blank,:blank,:blank";
-
- $row[2] = "1,2,3";
- $row[3] = "4,5,6";
- $row[4] = "7,8,9";
- $row[5] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
- $row[6] = ":blank,:blank,:blank";
-
- $row[7] = "VOLUMEUP:VOLUP,MUTE,CHANNELUP:CHUP2";
- $row[8] = "VOLUMEDOWN:VOLDOWN,EXIT,CHANNELDOWN:CHDOWN2";
- $row[9] = ":blank,:blank,:blank";
-
- $row[10] = "INFO,UP,MENU";
- $row[11] = "LEFT,OK,RIGHT";
- $row[12] = "AUDIO,DOWN,VIDEO";
- $row[13] = ":blank,:blank,:blank";
-
- $row[14] = "RED:REWINDred,GREEN:PLAYgreen,YELLOW:PAUSEyellow,BLUE:FFblue";
- $row[15] = "TV:TVstop,RADIO:RADIOred,TEXT,HELP";
-
- $row[16] = "attr rc_iconpath icons/remotecontrol";
- $row[17] = "attr rc_iconprefix black_btn_";
- return @row;
-}
-
-# Dreambox DM800se + DM8000 with SVG
-sub ENIGMA2_RClayout_DM8000_SVG() {
- my @row;
-
- $row[0] = ":rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
- $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[2] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
- $row[3] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
- $row[4] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
- $row[5] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
- $row[6] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[7] = "VOLUMEUP:rc_VOLPLUS.svg,MUTE:rc_MUTE.svg,CHANNELUP:rc_UP.svg";
- $row[8] =
- "VOLUMEDOWN:rc_VOLMINUS.svg,EXIT:rc_EXIT.svg,CHANNELDOWN:rc_DOWN.svg";
- $row[9] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[10] = "INFO:rc_INFO.svg,UP:rc_UP.svg,MENU:rc_MENU.svg";
- $row[11] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
- $row[12] = "AUDIO:rc_AUDIO.svg,DOWN:rc_DOWN.svg,VIDEO:rc_VIDEO.svg";
- $row[13] = ":rc_BLANK.svg,EXIT:rc_EXIT.svg,:rc_BLANK.svg";
-
- $row[14] =
- "RED:rc_RED.svg,GREEN:rc_GREEN.svg,YELLOW:rc_YELLOW.svg,BLUE:rc_BLUE.svg";
- $row[15] =
-"REWIND:rc_REW.svg,PLAY:rc_PLAY.svg,STOP:rc_STOP.svg,FASTFORWARD:rc_FF.svg";
- $row[16] =
- "TV:rc_TV.svg,RADIO:rc_RADIO.svg,TEXT:rc_TEXT.svg,RECORD:rc_REC.svg";
-
- $row[17] = "attr rc_iconpath icons/remotecontrol";
- $row[18] = "attr rc_iconprefix black_btn_";
- return @row;
-}
-
-# Dreambox DM800se + DM8000 with PNG
-sub ENIGMA2_RClayout_DM8000() {
- my @row;
-
- $row[0] = ":blank,:blank,POWER:POWEROFF";
- $row[1] = ":blank,:blank,:blank";
-
- $row[2] = "1,2,3";
- $row[3] = "4,5,6";
- $row[4] = "7,8,9";
- $row[5] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
- $row[6] = ":blank,:blank,:blank";
-
- $row[7] = "VOLUMEUP:VOLUP,MUTE,CHANNELUP:CHUP2";
- $row[8] = "VOLUMEDOWN:VOLDOWN,EXIT,CHANNELDOWN:CHDOWN2";
- $row[9] = ":blank,:blank,:blank";
-
- $row[10] = "INFO,UP,MENU";
- $row[11] = "LEFT,OK,RIGHT";
- $row[12] = "AUDIO,DOWN,VIDEO";
- $row[13] = ":blank,:blank,:blank";
-
- $row[14] = "RED,GREEN,YELLOW,BLUE";
- $row[15] = "REWIND,PLAY,STOP,FASTFORWARD:FF";
- $row[16] = "TV,RADIO,TEXT,RECORD:REC";
-
- $row[17] = "attr rc_iconpath icons/remotecontrol";
- $row[18] = "attr rc_iconprefix black_btn_";
- return @row;
-}
-
-# Dreambox RC10 with SVG
-sub ENIGMA2_RClayout_RC10_SVG() {
- my @row;
-
- $row[0] = ":rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
- $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[2] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
- $row[3] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
- $row[4] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
- $row[5] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
- $row[6] =
- "RED:rc_RED.svg,GREEN:rc_GREEN.svg,YELLOW:rc_YELLOW.svg,BLUE:rc_BLUE.svg";
- $row[7] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[8] = "INFO:rc_INFO.svg,UP:rc_UP.svg,MENU:rc_MENU.svg";
- $row[9] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
- $row[10] = "AUDIO:rc_AUDIO.svg,DOWN:rc_DOWN.svg,VIDEO:rc_VIDEO.svg";
- $row[11] = ":rc_BLANK.svg,EXIT:rc_EXIT.svg,:rc_BLANK.svg";
-
- $row[12] = "VOLUMEUP:rc_VOLPLUS.svg,:rc_BLANK.svg,CHANNELUP:rc_UP.svg";
- $row[13] =
- "VOLUMEDOWN:rc_VOLMINUS.svg,MUTE:rc_MUTE.svg,CHANNELDOWN:rc_DOWN.svg";
- $row[14] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[15] =
-"REWIND:rc_REW.svg,PLAY:rc_PLAY.svg,STOP:rc_STOP.svg,FASTFORWARD:rc_FF.svg";
- $row[16] =
- "TV:rc_TV.svg,RADIO:rc_RADIO.svg,TEXT:rc_TEXT.svg,RECORD:rc_REC.svg";
-
- $row[17] = "attr rc_iconpath icons";
- $row[18] = "attr rc_iconprefix rc_";
- return @row;
-}
-
-# Dreambox RC10 with PNG
-sub ENIGMA2_RClayout_RC10() {
- my @row;
-
- $row[0] = ":blank,:blank,POWER:POWEROFF";
- $row[1] = ":blank,:blank,:blank";
-
- $row[2] = "1,2,3";
- $row[3] = "4,5,6";
- $row[4] = "7,8,9";
- $row[5] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
- $row[6] = "RED,GREEN,YELLOW,BLUE";
- $row[7] = ":blank,:blank,:blank";
-
- $row[8] = "INFO,UP,MENU";
- $row[9] = "LEFT,OK,RIGHT";
- $row[10] = "AUDIO,DOWN,VIDEO";
- $row[11] = ":blank,EXIT,:blank";
-
- $row[12] = "VOLUMEUP:VOLUP,:blank,CHANNELUP:CHUP2";
- $row[13] = "VOLUMEDOWN:VOLDOWN,MUTE,CHANNELDOWN:CHDOWN2";
- $row[14] = ":blank,:blank,:blank";
-
- $row[15] = "REWIND,PLAY,STOP,FASTFORWARD:FF";
- $row[16] = "TV,RADIO,TEXT,RECORD:REC";
-
- $row[17] = "attr rc_iconpath icons/remotecontrol";
- $row[18] = "attr rc_iconprefix black_btn_";
- return @row;
-}
-
-# VU+ Duo2 with SVG
-sub ENIGMA2_RClayout_VUplusDuo2_SVG() {
- my @row;
-
- $row[0] = ":rc_BLANK.svg,MUTE:rc_MUTE.svg,POWER:rc_POWER.svg";
- $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[2] = "REWIND:rc_REW.svg,PLAY:rc_PLAY.svg,FASTFORWARD:rc_FF.svg";
- $row[3] = "RECORD:rc_REC.svg,STOP:rc_STOP.svg,VIDEO:rc_VIDEO.svg";
- $row[4] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[5] = "TV:rc_TV.svg,AUDIO:rc_AUDIO.svg,RADIO:rc_RADIO.svg";
- $row[6] = "TEXT:rc_TEXT.svg,HELP:rc_HELP.svg,AV:rc_AV.svg";
- $row[7] = "INFO:rc_EPG.svg,MENU:rc_MENU.svg,EXIT:rc_EXIT.svg";
- $row[8] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[9] = "VOLUMEUP:rc_VOLPLUS.svg,UP:rc_UP.svg,CHANNELUP:rc_PLUS.svg";
- $row[10] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
- $row[11] =
- "VOLUMEDOWN:rc_VOLMINUS.svg,DOWN:rc_DOWN.svg,CHANNELDOWN:rc_MINUS.svg";
-
- $row[12] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
-
- $row[13] =
- "RED:rc_RED.svg,GREEN:rc_GREEN.svg,YELLOW:rc_YELLOW.svg,BLUE:rc_BLUE.svg";
- $row[14] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
- $row[15] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
- $row[16] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
- $row[17] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
-
- $row[18] = "attr rc_iconpath icons";
- $row[19] = "attr rc_iconprefix rc_";
- return @row;
-}
-
-# VU+ Duo2 with PNG
-sub ENIGMA2_RClayout_VUplusDuo2() {
- my @row;
-
- $row[0] = ":blank,MUTE,POWER:POWEROFF";
- $row[1] = ":blank,:blank,:blank";
-
- $row[2] = "REWIND,PLAY,FASTFORWARD:FF";
- $row[3] = "RECORD:REC,STOP,VIDEO";
- $row[4] = ":blank,:blank,:blank";
-
- $row[5] = "TV,AUDIO,RADIO:RADIO";
- $row[6] = "TEXT,HELP,AV";
- $row[7] = "INFO,MENU,EXIT";
- $row[8] = ":blank,:blank,:blank";
-
- $row[9] = "VOLUMEUP:VOLUP,UP,CHANNELUP:CHUP2";
- $row[10] = "LEFT,OK,RIGHT";
- $row[11] = "VOLUMEDOWN:VOLDOWN,DOWN,CHANNELDOWN:CHDOWN2";
-
- $row[12] = ":blank,:blank,:blank";
-
- $row[13] = "RED,GREEN,YELLOW,BLUE";
- $row[14] = "1,2,3";
- $row[15] = "4,5,6";
- $row[16] = "7,8,9";
- $row[17] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
-
- $row[18] = "attr rc_iconpath icons/remotecontrol";
- $row[19] = "attr rc_iconprefix black_btn_";
- return @row;
-}
-
-###################################
sub ENIGMA2_GetRemotecontrolCommand($) {
my ($command) = @_;
my $commands = {
@@ -2855,6 +2502,306 @@ sub ENIGMA2_GetRemotecontrolCommand($) {
}
}
+sub ENIGMA2_wake ($$) {
+ if ( !$modules{WOL}{LOADED}
+ && -f "$attr{global}{modpath}/FHEM/98_WOL.pm" )
+ {
+ my $ret = CommandReload( undef, "98_WOL" );
+ return $ret if ($ret);
+ }
+ elsif ( !-f "$attr{global}{modpath}/FHEM/98_WOL.pm" ) {
+ return "Missing module: $attr{global}{modpath}/FHEM/98_WOL.pm";
+ }
+
+ my ( $name, $mac ) = @_;
+ my $hash = $defs{$name};
+ my $host =
+ AttrVal( $name, "WOL_useUdpBroadcast",
+ AttrVal( $name, "useUdpBroadcast", "255.255.255.255" ) );
+ my $port = AttrVal( $name, "WOL_port", "9" );
+ my $mode = lc( AttrVal( $name, "WOL_mode", "UDP" ) );
+
+ Log3 $name, 4,
+ "ENIGMA2 $name: Waking up by sending Wake-On-Lan magic package to "
+ . $mac;
+
+ if ( $mode eq "both" || $mode eq "ew" ) {
+ WOL_by_ew( $hash, $mac );
+ }
+ if ( $mode eq "both" || $mode eq "udp" ) {
+ WOL_by_udp( $hash, $mac, $host, $port );
+ }
+}
+
+sub ENIGMA2_RCmakenotify($$) {
+ my ( $nam, $ndev ) = @_;
+ my $nname = "notify_$nam";
+
+ fhem( "define $nname notify $nam set $ndev remoteControl " . '$EVENT', 1 );
+ Log3 undef, 2, "[remotecontrol:ENIGMA2] Notify created: $nname";
+ return "Notify created by ENIGMA2: $nname";
+}
+
+sub ENIGMA2_RClayout_DM800_SVG() {
+ my @row;
+
+ $row[0] = ":rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
+ $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[2] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
+ $row[3] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
+ $row[4] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
+ $row[5] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
+ $row[6] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[7] = "VOLUMEUP:rc_VOLPLUS.svg,MUTE:rc_MUTE.svg,CHANNELUP:rc_UP.svg";
+ $row[8] =
+ "VOLUMEDOWN:rc_VOLMINUS.svg,EXIT:rc_EXIT.svg,CHANNELDOWN:rc_DOWN.svg";
+ $row[9] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[10] = "INFO:rc_INFO.svg,UP:rc_UP.svg,MENU:rc_MENU.svg";
+ $row[11] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
+ $row[12] = "AUDIO:rc_AUDIO.svg,DOWN:rc_DOWN.svg,VIDEO:rc_VIDEO.svg";
+ $row[13] = ":rc_BLANK.svg,EXIT:rc_EXIT.svg,:rc_BLANK.svg";
+
+ $row[14] =
+ "RED:rc_REWred.svg,GREEN:rc_PLAYgreen.svg,"
+ . "YELLOW:rc_PAUSEyellow.svg,BLUE:rc_FFblue.svg";
+ $row[15] =
+ "TV:rc_TVstop.svg,RADIO:rc_RADIOred.svg,"
+ . "TEXT:rc_TEXT.svg,HELP:rc_HELP.svg";
+
+ $row[16] = "attr rc_iconpath icons/remotecontrol";
+ $row[17] = "attr rc_iconprefix black_btn_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_DM800() {
+ my @row;
+
+ $row[0] = ":blank,:blank,POWER:POWEROFF";
+ $row[1] = ":blank,:blank,:blank";
+
+ $row[2] = "1,2,3";
+ $row[3] = "4,5,6";
+ $row[4] = "7,8,9";
+ $row[5] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
+ $row[6] = ":blank,:blank,:blank";
+
+ $row[7] = "VOLUMEUP:VOLUP,MUTE,CHANNELUP:CHUP2";
+ $row[8] = "VOLUMEDOWN:VOLDOWN,EXIT,CHANNELDOWN:CHDOWN2";
+ $row[9] = ":blank,:blank,:blank";
+
+ $row[10] = "INFO,UP,MENU";
+ $row[11] = "LEFT,OK,RIGHT";
+ $row[12] = "AUDIO,DOWN,VIDEO";
+ $row[13] = ":blank,:blank,:blank";
+
+ $row[14] = "RED:REWINDred,GREEN:PLAYgreen,YELLOW:PAUSEyellow,BLUE:FFblue";
+ $row[15] = "TV:TVstop,RADIO:RADIOred,TEXT,HELP";
+
+ $row[16] = "attr rc_iconpath icons/remotecontrol";
+ $row[17] = "attr rc_iconprefix black_btn_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_DM8000_SVG() {
+ my @row;
+
+ $row[0] = ":rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
+ $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[2] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
+ $row[3] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
+ $row[4] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
+ $row[5] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
+ $row[6] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[7] = "VOLUMEUP:rc_VOLPLUS.svg,MUTE:rc_MUTE.svg,CHANNELUP:rc_UP.svg";
+ $row[8] =
+ "VOLUMEDOWN:rc_VOLMINUS.svg,EXIT:rc_EXIT.svg,CHANNELDOWN:rc_DOWN.svg";
+ $row[9] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[10] = "INFO:rc_INFO.svg,UP:rc_UP.svg,MENU:rc_MENU.svg";
+ $row[11] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
+ $row[12] = "AUDIO:rc_AUDIO.svg,DOWN:rc_DOWN.svg,VIDEO:rc_VIDEO.svg";
+ $row[13] = ":rc_BLANK.svg,EXIT:rc_EXIT.svg,:rc_BLANK.svg";
+
+ $row[14] =
+ "RED:rc_RED.svg,GREEN:rc_GREEN.svg,"
+ . "YELLOW:rc_YELLOW.svg,BLUE:rc_BLUE.svg";
+ $row[15] =
+ "REWIND:rc_REW.svg,PLAY:rc_PLAY.svg,"
+ . "STOP:rc_STOP.svg,FASTFORWARD:rc_FF.svg";
+ $row[16] =
+ "TV:rc_TV.svg,RADIO:rc_RADIO.svg,TEXT:rc_TEXT.svg,RECORD:rc_REC.svg";
+
+ $row[17] = "attr rc_iconpath icons/remotecontrol";
+ $row[18] = "attr rc_iconprefix black_btn_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_DM8000() {
+ my @row;
+
+ $row[0] = ":blank,:blank,POWER:POWEROFF";
+ $row[1] = ":blank,:blank,:blank";
+
+ $row[2] = "1,2,3";
+ $row[3] = "4,5,6";
+ $row[4] = "7,8,9";
+ $row[5] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
+ $row[6] = ":blank,:blank,:blank";
+
+ $row[7] = "VOLUMEUP:VOLUP,MUTE,CHANNELUP:CHUP2";
+ $row[8] = "VOLUMEDOWN:VOLDOWN,EXIT,CHANNELDOWN:CHDOWN2";
+ $row[9] = ":blank,:blank,:blank";
+
+ $row[10] = "INFO,UP,MENU";
+ $row[11] = "LEFT,OK,RIGHT";
+ $row[12] = "AUDIO,DOWN,VIDEO";
+ $row[13] = ":blank,:blank,:blank";
+
+ $row[14] = "RED,GREEN,YELLOW,BLUE";
+ $row[15] = "REWIND,PLAY,STOP,FASTFORWARD:FF";
+ $row[16] = "TV,RADIO,TEXT,RECORD:REC";
+
+ $row[17] = "attr rc_iconpath icons/remotecontrol";
+ $row[18] = "attr rc_iconprefix black_btn_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_RC10_SVG() {
+ my @row;
+
+ $row[0] = ":rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
+ $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[2] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
+ $row[3] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
+ $row[4] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
+ $row[5] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
+ $row[6] =
+ "RED:rc_RED.svg,GREEN:rc_GREEN.svg,YELLOW:rc_YELLOW.svg,BLUE:rc_BLUE.svg";
+ $row[7] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[8] = "INFO:rc_INFO.svg,UP:rc_UP.svg,MENU:rc_MENU.svg";
+ $row[9] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
+ $row[10] = "AUDIO:rc_AUDIO.svg,DOWN:rc_DOWN.svg,VIDEO:rc_VIDEO.svg";
+ $row[11] = ":rc_BLANK.svg,EXIT:rc_EXIT.svg,:rc_BLANK.svg";
+
+ $row[12] = "VOLUMEUP:rc_VOLPLUS.svg,:rc_BLANK.svg,CHANNELUP:rc_UP.svg";
+ $row[13] =
+ "VOLUMEDOWN:rc_VOLMINUS.svg,MUTE:rc_MUTE.svg,CHANNELDOWN:rc_DOWN.svg";
+ $row[14] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[15] =
+ "REWIND:rc_REW.svg,PLAY:rc_PLAY.svg,"
+ . "STOP:rc_STOP.svg,FASTFORWARD:rc_FF.svg";
+ $row[16] =
+ "TV:rc_TV.svg,RADIO:rc_RADIO.svg,TEXT:rc_TEXT.svg,RECORD:rc_REC.svg";
+
+ $row[17] = "attr rc_iconpath icons";
+ $row[18] = "attr rc_iconprefix rc_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_RC10() {
+ my @row;
+
+ $row[0] = ":blank,:blank,POWER:POWEROFF";
+ $row[1] = ":blank,:blank,:blank";
+
+ $row[2] = "1,2,3";
+ $row[3] = "4,5,6";
+ $row[4] = "7,8,9";
+ $row[5] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
+ $row[6] = "RED,GREEN,YELLOW,BLUE";
+ $row[7] = ":blank,:blank,:blank";
+
+ $row[8] = "INFO,UP,MENU";
+ $row[9] = "LEFT,OK,RIGHT";
+ $row[10] = "AUDIO,DOWN,VIDEO";
+ $row[11] = ":blank,EXIT,:blank";
+
+ $row[12] = "VOLUMEUP:VOLUP,:blank,CHANNELUP:CHUP2";
+ $row[13] = "VOLUMEDOWN:VOLDOWN,MUTE,CHANNELDOWN:CHDOWN2";
+ $row[14] = ":blank,:blank,:blank";
+
+ $row[15] = "REWIND,PLAY,STOP,FASTFORWARD:FF";
+ $row[16] = "TV,RADIO,TEXT,RECORD:REC";
+
+ $row[17] = "attr rc_iconpath icons/remotecontrol";
+ $row[18] = "attr rc_iconprefix black_btn_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_VUplusDuo2_SVG() {
+ my @row;
+
+ $row[0] = ":rc_BLANK.svg,MUTE:rc_MUTE.svg,POWER:rc_POWER.svg";
+ $row[1] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[2] = "REWIND:rc_REW.svg,PLAY:rc_PLAY.svg,FASTFORWARD:rc_FF.svg";
+ $row[3] = "RECORD:rc_REC.svg,STOP:rc_STOP.svg,VIDEO:rc_VIDEO.svg";
+ $row[4] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[5] = "TV:rc_TV.svg,AUDIO:rc_AUDIO.svg,RADIO:rc_RADIO.svg";
+ $row[6] = "TEXT:rc_TEXT.svg,HELP:rc_HELP.svg,AV:rc_AV.svg";
+ $row[7] = "INFO:rc_EPG.svg,MENU:rc_MENU.svg,EXIT:rc_EXIT.svg";
+ $row[8] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[9] = "VOLUMEUP:rc_VOLPLUS.svg,UP:rc_UP.svg,CHANNELUP:rc_PLUS.svg";
+ $row[10] = "LEFT:rc_LEFT.svg,OK:rc_OK.svg,RIGHT:rc_RIGHT.svg";
+ $row[11] =
+ "VOLUMEDOWN:rc_VOLMINUS.svg,DOWN:rc_DOWN.svg,CHANNELDOWN:rc_MINUS.svg";
+
+ $row[12] = ":rc_BLANK.svg,:rc_BLANK.svg,:rc_BLANK.svg";
+
+ $row[13] =
+ "RED:rc_RED.svg,GREEN:rc_GREEN.svg,YELLOW:rc_YELLOW.svg,BLUE:rc_BLUE.svg";
+ $row[14] = "1:rc_1.svg,2:rc_2.svg,3:rc_3.svg";
+ $row[15] = "4:rc_4.svg,5:rc_5.svg,6:rc_6.svg";
+ $row[16] = "7:rc_7.svg,8:rc_8.svg,9:rc_9.svg";
+ $row[17] = "LEFTBRACE:rc_PREVIOUS.svg,0:rc_0.svg,RIGHTBRACE:rc_NEXT.svg";
+
+ $row[18] = "attr rc_iconpath icons";
+ $row[19] = "attr rc_iconprefix rc_";
+ return @row;
+}
+
+sub ENIGMA2_RClayout_VUplusDuo2() {
+ my @row;
+
+ $row[0] = ":blank,MUTE,POWER:POWEROFF";
+ $row[1] = ":blank,:blank,:blank";
+
+ $row[2] = "REWIND,PLAY,FASTFORWARD:FF";
+ $row[3] = "RECORD:REC,STOP,VIDEO";
+ $row[4] = ":blank,:blank,:blank";
+
+ $row[5] = "TV,AUDIO,RADIO:RADIO";
+ $row[6] = "TEXT,HELP,AV";
+ $row[7] = "INFO,MENU,EXIT";
+ $row[8] = ":blank,:blank,:blank";
+
+ $row[9] = "VOLUMEUP:VOLUP,UP,CHANNELUP:CHUP2";
+ $row[10] = "LEFT,OK,RIGHT";
+ $row[11] = "VOLUMEDOWN:VOLDOWN,DOWN,CHANNELDOWN:CHDOWN2";
+
+ $row[12] = ":blank,:blank,:blank";
+
+ $row[13] = "RED,GREEN,YELLOW,BLUE";
+ $row[14] = "1,2,3";
+ $row[15] = "4,5,6";
+ $row[16] = "7,8,9";
+ $row[17] = "LEFTBRACE:LEFT2,0:0,RIGHTBRACE:RIGHT2";
+
+ $row[18] = "attr rc_iconpath icons/remotecontrol";
+ $row[19] = "attr rc_iconprefix black_btn_";
+ return @row;
+}
+
1;
=pod
diff --git a/fhem/FHEM/70_ONKYO_AVR.pm b/fhem/FHEM/70_ONKYO_AVR.pm
index e415c5472..f12c000cb 100644
--- a/fhem/FHEM/70_ONKYO_AVR.pm
+++ b/fhem/FHEM/70_ONKYO_AVR.pm
@@ -1,57 +1,16 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 70_ONKYO_AVR.pm
-# An FHEM Perl module for controlling ONKYO A/V receivers
-# via network connection.
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
package main;
-
use strict;
use warnings;
-use Time::HiRes qw(usleep);
+use Data::Dumper;
use Symbol qw;
use File::Path;
use File::stat;
use File::Temp;
use File::Copy;
-use Data::Dumper;
-$Data::Dumper::Sortkeys = 1;
-
-sub ONKYO_AVR_Set($$$);
-sub ONKYO_AVR_Get($$$);
-sub ONKYO_AVR_Define($$$);
-sub ONKYO_AVR_Undefine($$);
-sub ONKYO_AVR_Notify($$);
-sub ONKYO_AVR_Shutdown($);
-
-#########################
-# Forward declaration for remotecontrol module
-sub ONKYO_AVR_RClayout_TV();
-sub ONKYO_AVR_RCmakenotify($$);
-
-###################################
+# initialize ##################################################################
sub ONKYO_AVR_Initialize($) {
my ($hash) = @_;
@@ -60,16 +19,13 @@ sub ONKYO_AVR_Initialize($) {
require "$attr{global}{modpath}/FHEM/DevIo.pm";
require "$attr{global}{modpath}/FHEM/ONKYOdb.pm";
- # Provider
- $hash->{ReadFn} = "ONKYO_AVR_Read";
- $hash->{WriteFn} = "ONKYO_AVR_Write";
- $hash->{ReadyFn} = "ONKYO_AVR_Ready";
-
- # Normal devices
$hash->{DefFn} = "ONKYO_AVR_Define";
$hash->{UndefFn} = "ONKYO_AVR_Undefine";
- $hash->{GetFn} = "ONKYO_AVR_Get";
$hash->{SetFn} = "ONKYO_AVR_Set";
+ $hash->{GetFn} = "ONKYO_AVR_Get";
+ $hash->{ReadFn} = "ONKYO_AVR_Read";
+ $hash->{WriteFn} = "ONKYO_AVR_Write";
+ $hash->{ReadyFn} = "ONKYO_AVR_Ready";
$hash->{NotifyFn} = "ONKYO_AVR_Notify";
$hash->{ShutdownFn} = "ONKYO_AVR_Shutdown";
$hash->{parseParams} = 1;
@@ -77,6 +33,7 @@ sub ONKYO_AVR_Initialize($) {
no warnings 'qw';
my @attrList = qw(
do_not_notify:1,0
+ disabledForIntervals
volumeSteps:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
inputs
disable:0,1
@@ -111,36 +68,7 @@ sub ONKYO_AVR_Initialize($) {
};
}
-sub ONKYO_AVR_addExtension($$$) {
- my ( $name, $func, $link ) = @_;
-
- my $url = "?/$link";
-
- return 0
- if ( defined( $data{FWEXT}{$url} )
- && $data{FWEXT}{$url}{deviceName} ne $name );
-
- Log3 $name, 2,
- "ONKYO_AVR $name: Registering ONKYO_AVR for webhook URI $url ...";
- $data{FWEXT}{$url}{deviceName} = $name;
- $data{FWEXT}{$url}{FUNC} = $func;
- $data{FWEXT}{$url}{LINK} = $link;
-
- return 1;
-}
-
-###################################
-sub ONKYO_AVR_removeExtension($) {
- my ($link) = @_;
-
- my $url = "?/$link";
- my $name = $data{FWEXT}{$url}{deviceName};
- Log3 $name, 2,
- "ONKYO_AVR $name: Unregistering ONKYO_AVR for webhook URI $url...";
- delete $data{FWEXT}{$url};
-}
-
-###################################
+# regular Fn ##################################################################
sub ONKYO_AVR_Define($$$) {
my ( $hash, $a, $h ) = @_;
my $name = $hash->{NAME};
@@ -228,195 +156,10 @@ sub ONKYO_AVR_Define($$$) {
}
);
}
+
+ return undef;
}
-#####################################
-sub ONKYO_AVR_DevInit($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- if ( lc( ReadingsVal( $name, "state", "?" ) ) eq "opened" ) {
- DoTrigger( $name, "CONNECTED" );
- }
- else {
- DoTrigger( $name, "DISCONNECTED" );
- }
-}
-
-#------------------------------------------------------------------------------
-sub ONKYO_AVR_CGI() {
- my ($request) = @_;
-
- # data received
- if ( $request =~ m,^\?\/ONKYO_AVR\/cover\/(.+)\.(.+)$, ) {
-
- Log3 undef, 5, "ONKYO_AVR: sending cover $1.$2";
-
- if ( $1 eq "empty" && $2 eq "jpg" ) {
- FW_serveSpecial( 'sonos_empty', 'jpg',
- AttrVal( "global", "modpath", "." ) . '/FHEM/lib/UPnP', 1 );
- }
- else {
- FW_serveSpecial(
- $1,
- $2,
- AttrVal( "global", "modpath", "." )
- . '/www/images/default/ONKYO_AVR',
- 1
- );
- }
-
- return ( undef, undef );
- }
-
- # no data received
- else {
- Log3 undef, 5, "ONKYO_AVR: received malformed request\n$request";
- }
-
- return ( "text/plain; charset=utf-8", "Call failure: " . $request );
-}
-
-#####################################
-sub ONKYO_AVR_Notify($$) {
- my ( $hash, $dev ) = @_;
- my $name = $hash->{NAME};
- my $devName = $dev->{NAME};
- my $definedZones = scalar keys %{ $modules{ONKYO_AVR_ZONE}{defptr}{$name} };
- my $presence = ReadingsVal( $name, "presence", "-" );
-
- return
- if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
-
- # work on global events related to us
- if ( $devName eq "global" ) {
- foreach my $change ( @{ $dev->{CHANGED} } ) {
- if ( $change !~ /^(\w+)\s(\w+)\s?(\w*)\s?(.*)$/
- || $2 ne $name )
- {
- return;
- }
-
- # DEFINED
- # MODIFIED
- elsif ( $1 eq "DEFINED" || $1 eq "MODIFIED" ) {
- Log3 $hash, 5,
- "ONKYO_AVR "
- . $name
- . ": processing my global event $1: $3 -> $4";
-
- if ( lc( ReadingsVal( $name, "state", "?" ) ) eq "opened" ) {
- DoTrigger( $name, "CONNECTED" );
- }
- else {
- DoTrigger( $name, "DISCONNECTED" );
- }
- }
-
- # unknown event
- else {
- Log3 $hash, 5,
- "ONKYO_AVR "
- . $name
- . ": WONT BE processing my global event $1: $3 -> $4";
- }
- }
-
- return;
- }
-
- # do nothing for any other device
- elsif ( $devName ne $name ) {
- return;
- }
-
- readingsBeginUpdate($hash);
-
- foreach my $change ( @{ $dev->{CHANGED} } ) {
-
- # DISCONNECTED
- if ( $change eq "DISCONNECTED" ) {
- Log3 $hash, 5, "ONKYO_AVR " . $name . ": processing change $change";
-
- # disable connectionCheck and wait
- # until DevIo reopened the connection
- RemoveInternalTimer($hash);
-
- readingsBulkUpdate( $hash, "presence", "absent" )
- if ( $presence ne "absent" );
-
- readingsBulkUpdate( $hash, "power", "off" )
- if ( ReadingsVal( $name, "power", "on" ) ne "off" );
-
- # stateAV
- my $stateAV = ONKYO_AVR_GetStateAV($hash);
- readingsBulkUpdate( $hash, "stateAV", $stateAV )
- if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
-
- # send to slaves
- if ( $definedZones > 1 ) {
- Log3 $name, 5,
- "ONKYO_AVR $name: Dispatching state change to slaves";
- Dispatch(
- $hash,
- {
- "presence" => "absent",
- "power" => "off",
- },
- undef
- );
- }
- }
-
- # CONNECTED
- elsif ( $change eq "CONNECTED" ) {
- Log3 $hash, 5, "ONKYO_AVR " . $name . ": processing change $change";
-
- readingsBulkUpdate( $hash, "presence", "present" )
- if ( $presence ne "present" );
-
- # stateAV
- my $stateAV = ONKYO_AVR_GetStateAV($hash);
- readingsBulkUpdate( $hash, "stateAV", $stateAV )
- if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
-
- ONKYO_AVR_SendCommand( $hash, "power", "query" );
- ONKYO_AVR_SendCommand( $hash, "network-standby", "query" );
- ONKYO_AVR_SendCommand( $hash, "input", "query" );
- ONKYO_AVR_SendCommand( $hash, "mute", "query" );
- ONKYO_AVR_SendCommand( $hash, "volume", "query" );
- ONKYO_AVR_SendCommand( $hash, "sleep", "query" );
- ONKYO_AVR_SendCommand( $hash, "audio-information", "query" );
- ONKYO_AVR_SendCommand( $hash, "video-information", "query" );
- ONKYO_AVR_SendCommand( $hash, "listening-mode", "query" );
- ONKYO_AVR_SendCommand( $hash, "video-picture-mode", "query" );
- ONKYO_AVR_SendCommand( $hash, "phase-matching-bass", "query" );
- ONKYO_AVR_SendCommand( $hash, "center-temporary-level", "query" );
- ONKYO_AVR_SendCommand( $hash, "subwoofer-temporary-level",
- "query" );
- fhem
-"sleep 1 quiet;get $name remoteControl net-receiver-information query quiet";
-
- # send to slaves
- if ( $definedZones > 1 ) {
- Log3 $name, 5,
- "ONKYO_AVR $name: Dispatching state change to slaves";
- Dispatch(
- $hash,
- {
- "presence" => "present",
- },
- undef
- );
- }
-
- }
- }
-
- readingsEndUpdate( $hash, 1 );
-}
-
-###################################
sub ONKYO_AVR_Undefine($$) {
my ( $hash, $name ) = @_;
@@ -443,17 +186,1187 @@ sub ONKYO_AVR_Undefine($$) {
return undef;
}
-###################################
-sub ONKYO_AVR_Shutdown($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- Log3 $name, 5, "ONKYO_AVR $name: called function ONKYO_AVR_Shutdown()";
+sub ONKYO_AVR_Set($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+ my $zone = $hash->{ZONE};
+ my $state = ReadingsVal( $name, "power", "off" );
+ my $presence = ReadingsVal( $name, "presence", "absent" );
+ my $return;
+ my $reading;
+ my $inputs_txt = "";
+ my $channels_txt = "";
+ my @implicit_cmds;
+ my $implicit_txt = "";
- DevIo_CloseDev($hash);
- return undef;
+ Log3 $name, 5, "ONKYO_AVR $name: called function ONKYO_AVR_Set()";
+
+ return "Argument is missing" if ( int(@$a) < 1 );
+
+ # Input alias handling
+ if ( defined( $attr{$name}{inputs} ) && $attr{$name}{inputs} ne "" ) {
+ my @inputs = split( ':', $attr{$name}{inputs} );
+
+ if (@inputs) {
+ foreach (@inputs) {
+ if (m/[^,\s]+(,[^,\s]+)+/) {
+ my @input_names = split( ',', $_ );
+ $inputs_txt .= $input_names[1] . ",";
+ $input_names[1] =~ s/\s/_/g;
+ $hash->{helper}{receiver}{input_aliases}{ $input_names[0] }
+ = $input_names[1];
+ $hash->{helper}{receiver}{input_names}{ $input_names[1] } =
+ $input_names[0];
+ }
+ else {
+ $inputs_txt .= $_ . ",";
+ }
+ }
+ }
+
+ $inputs_txt =~ s/\s/_/g;
+ $inputs_txt = substr( $inputs_txt, 0, -1 );
+ }
+
+ # if we could read the actual available inputs from the receiver, use them
+ elsif (defined( $hash->{helper}{receiver} )
+ && ref( $hash->{helper}{receiver} ) eq "HASH"
+ && defined( $hash->{helper}{receiver}{device}{selectorlist}{count} )
+ && $hash->{helper}{receiver}{device}{selectorlist}{count} > 0 )
+ {
+
+ foreach my $input (
+ @{ $hash->{helper}{receiver}{device}{selectorlist}{selector} } )
+ {
+ if ( $input->{value} eq "1"
+ && $input->{zone} ne "00"
+ && $input->{id} ne "80" )
+ {
+ my $id = $input->{id};
+ my $name = trim( $input->{name} );
+ $inputs_txt .= $name . ",";
+ }
+ }
+
+ $inputs_txt =~ s/\s/_/g;
+ $inputs_txt = substr( $inputs_txt, 0, -1 );
+ }
+
+ # use general list of possible inputs
+ else {
+ # Find out valid inputs
+ my $inputs =
+ ONKYOdb::ONKYO_GetRemotecontrolValue( $zone,
+ ONKYOdb::ONKYO_GetRemotecontrolCommand( $zone, "input" ) );
+
+ foreach my $input ( sort keys %{$inputs} ) {
+ $inputs_txt .= $input . ","
+ if ( !( $input =~ /^(07|08|09|up|down|query)$/ ) );
+ }
+ $inputs_txt = substr( $inputs_txt, 0, -1 );
+ }
+
+ # list of network channels/services
+ my $channels_src = "internal";
+ if ( defined( $hash->{helper}{receiver} )
+ && ref( $hash->{helper}{receiver} ) eq "HASH"
+ && defined( $hash->{helper}{receiver}{device}{netservicelist}{count} )
+ && $hash->{helper}{receiver}{device}{netservicelist}{count} > 0 )
+ {
+
+ foreach my $id (
+ sort keys
+ %{ $hash->{helper}{receiver}{device}{netservicelist}{netservice} } )
+ {
+ if (
+ defined(
+ $hash->{helper}{receiver}{device}{netservicelist}
+ {netservice}{$id}{value}
+ )
+ && $hash->{helper}{receiver}{device}{netservicelist}
+ {netservice}{$id}{value} eq "1"
+ )
+ {
+ $channels_txt .=
+ trim( $hash->{helper}{receiver}{device}{netservicelist}
+ {netservice}{$id}{name} )
+ . ",";
+ }
+ }
+
+ $channels_txt =~ s/\s/_/g;
+ $channels_txt = substr( $channels_txt, 0, -1 );
+ $channels_src = "receiver";
+ }
+
+ # use general list of possible channels
+ else {
+ # Find out valid channels
+ my $channels =
+ ONKYOdb::ONKYO_GetRemotecontrolValue( "1",
+ ONKYOdb::ONKYO_GetRemotecontrolCommand( "1", "net-service" ) );
+
+ foreach my $channel ( sort keys %{$channels} ) {
+ $channels_txt .= $channel . ","
+ if ( !( $channel =~ /^(up|down|query)$/ ) );
+ }
+ $channels_txt = substr( $channels_txt, 0, -1 );
+ }
+
+ # for each reading, check if there is a known command for it
+ # and allow to set values if there are any available
+ if ( defined( $hash->{READINGS} ) ) {
+
+ foreach my $reading ( keys %{ $hash->{READINGS} } ) {
+ my $cmd_raw =
+ ONKYOdb::ONKYO_GetRemotecontrolCommand( $zone, $reading );
+ my @readingExceptions = (
+ "volume", "input", "mute", "sleep", "center-temporary-level",
+ "subwoofer-temporary-level", "balance", "preset",
+ );
+
+ if ( $cmd_raw && !( grep $_ eq $reading, @readingExceptions ) ) {
+ my $cmd_details =
+ ONKYOdb::ONKYO_GetRemotecontrolCommandDetails( $zone,
+ $cmd_raw );
+
+ my $value_list = "";
+ my $debuglist;
+ foreach my $value ( keys %{ $cmd_details->{values} } ) {
+ next
+ if ( $value eq "QSTN" );
+
+ if ( defined( $cmd_details->{values}{$value}{name} ) ) {
+ $value_list .= "," if ( $value_list ne "" );
+
+ $value_list .= $cmd_details->{values}{$value}{name}
+ if (
+ ref( $cmd_details->{values}{$value}{name} ) eq "" );
+
+ $value_list .= $cmd_details->{values}{$value}{name}[0]
+ if (
+ ref( $cmd_details->{values}{$value}{name} ) eq
+ "ARRAY" );
+ }
+ }
+
+ if ( $value_list ne "" ) {
+ push @implicit_cmds, $reading;
+ $implicit_txt .= " $reading:$value_list";
+ }
+ }
+
+ # tone-*
+ elsif ( $reading =~ /^tone.*-([a-zA-Z]+)$/ ) {
+ $implicit_txt .= " $reading:slider,-10,1,10";
+ }
+
+ # center-temporary-level
+ elsif ( $reading eq "center-temporary-level" ) {
+ $implicit_txt .= " $reading:slider,-12,1,12";
+ }
+
+ # subwoofer*-temporary-level
+ elsif ( $reading =~ /^subwoofer.*-temporary-level$/ ) {
+ $implicit_txt .= " $reading:slider,-15,1,12";
+ }
+ }
+ }
+
+ my $preset_txt = "";
+ if ( defined( $hash->{helper}{receiver}{preset} ) ) {
+
+ foreach my $id (
+ sort
+ keys %{ $hash->{helper}{receiver}{preset} }
+ )
+ {
+ my $presetName =
+ $hash->{helper}{receiver}{preset}{$id};
+ next if ( !$presetName || $presetName eq "" );
+
+ $preset_txt = "preset:" if ( $preset_txt eq "" );
+ $preset_txt .= ","
+ if ( $preset_txt eq "preset:"
+ && ReadingsVal( $name, "preset", "-" ) eq "" );
+
+ $presetName =~ s/\s/_/g;
+ $preset_txt .= $presetName . ",";
+ }
+ }
+ $preset_txt = substr( $preset_txt, 0, -1 ) if ( $preset_txt ne "" );
+
+ if ( $preset_txt eq "" ) {
+ $preset_txt = "preset:";
+ $preset_txt .= "," if ( ReadingsVal( $name, "preset", "-" ) eq "" );
+ $preset_txt .=
+"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40";
+ }
+
+ my $shuffle_txt = "shuffle:";
+ $shuffle_txt .= "," if ( ReadingsVal( $name, "shuffle", "-" ) eq "-" );
+ $shuffle_txt .= "off,on,on-album,on-folder";
+
+ my $repeat_txt = "repeat:";
+ $repeat_txt .= "," if ( ReadingsVal( $name, "repeat", "-" ) eq "-" );
+ $repeat_txt .= "off,all,all-folder,one";
+
+ my $usage =
+ "Unknown argument '"
+ . @$a[1]
+ . "', choose one of toggle:noArg on:noArg off:noArg volume:slider,0,1,100 volumeDown:noArg volumeUp:noArg mute:off,on muteT:noArg play:noArg pause:noArg stop:noArg previous:noArg next:noArg shuffleT:noArg repeatT:noArg remoteControl:play,pause,repeat,stop,top,down,up,right,delete,display,ff,left,mode,return,rew,select,setup,0,1,2,3,4,5,6,7,8,9,prev,next,shuffle,menu channelDown:noArg channelUp:noArg inputDown:noArg inputUp:noArg internet-radio-preset:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40 input:"
+ . $inputs_txt;
+ $usage .= " channel:$channels_txt";
+ $usage .= " presetDown:noArg presetUp:noArg $preset_txt";
+ $usage .= " $shuffle_txt";
+ $usage .= " $repeat_txt";
+ $usage .= $implicit_txt if ( $implicit_txt ne "" );
+ $usage .= " sleep:off,5,10,15,30,60,90";
+
+ if ( ReadingsVal( $name, "currentTrackPosition", "--:--" ) ne "--:--" ) {
+ $usage .= " currentTrackPosition";
+ }
+
+ my $cmd = '';
+
+ return "Device is offline and cannot be controlled at that stage."
+ if ( $presence eq "absent"
+ && lc( @$a[1] ) ne "on"
+ && lc( @$a[1] ) ne "?"
+ && lc( @$a[1] ) ne "help" );
+
+ readingsBeginUpdate($hash);
+
+ # create inputList reading for frontends
+ readingsBulkUpdate( $hash, "inputList", $inputs_txt )
+ if ( ReadingsVal( $name, "inputList", "-" ) ne $inputs_txt );
+
+ # create channelList reading for frontends
+ readingsBulkUpdate( $hash, "channelList", $channels_txt )
+ if (
+ (
+ $channels_src eq "internal"
+ && ReadingsVal( $name, "channelList", "-" ) eq "-"
+ )
+ || ( $channels_src eq "receiver"
+ && ReadingsVal( $name, "channelList", "-" ) ne $channels_txt )
+ );
+
+ # channel
+ if ( lc( @$a[1] ) eq "channel" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "Syntax: CHANNELNAME [USERNAME PASSWORD]";
+ }
+ else {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name channel " . @$a[2];
+ }
+ elsif ( $hash->{INPUT} ne "2B" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
+ $return .= fhem "sleep 1;set $name channel " . @$a[2];
+ }
+ elsif ( ReadingsVal( $name, "channel", "" ) ne @$a[2]
+ || ( defined( @$a[3] ) && defined( @$a[4] ) ) )
+ {
+
+ my $servicename = "";
+ my $channelname = @$a[2];
+
+ if (
+ defined( $hash->{helper}{receiver} )
+ && ref( $hash->{helper}{receiver} ) eq "HASH"
+ && defined(
+ $hash->{helper}{receiver}{device}{netservicelist}{count}
+ )
+ && $hash->{helper}{receiver}{device}{netservicelist}{count}
+ > 0
+ )
+ {
+
+ $channelname =~ s/_/ /g;
+
+ foreach my $id (
+ sort keys %{
+ $hash->{helper}{receiver}{device}{netservicelist}
+ {netservice}
+ }
+ )
+ {
+ if (
+ defined(
+ $hash->{helper}{receiver}{device}
+ {netservicelist}{netservice}{$id}{value}
+ )
+ && $hash->{helper}{receiver}{device}
+ {netservicelist}{netservice}{$id}{value} eq "1"
+ && $hash->{helper}{receiver}{device}
+ {netservicelist}{netservice}{$id}{name} eq
+ $channelname
+ )
+ {
+ $servicename .= uc($id);
+ last;
+ }
+ }
+ }
+ else {
+ my $channels = ONKYOdb::ONKYO_GetRemotecontrolValue(
+ "1",
+ ONKYOdb::ONKYO_GetRemotecontrolCommand(
+ "1", "net-service"
+ )
+ );
+
+ $servicename = $channels->{$channelname}
+ if ( defined( $channels->{$channelname} ) );
+ }
+
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ $servicename = uc($channelname)
+ if ( $servicename eq "" );
+
+ $servicename .= "0" if ( !defined( @$a[3] ) );
+ $servicename .= "1" . @$a[3] if ( defined( @$a[3] ) );
+ $servicename .= @$a[4] if ( defined( @$a[4] ) );
+
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "net-service", $servicename );
+ }
+ }
+ }
+
+ # channelDown
+ elsif ( lc( @$a[1] ) eq "channeldown" ) {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name channelDown";
+ }
+ elsif ( $hash->{INPUT} ne "2B" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
+ $return .= fhem "sleep 1;set $name channelDown";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "chdn" );
+ }
+ }
+
+ # channelUp
+ elsif ( lc( @$a[1] ) eq "channelup" ) {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name channelUp";
+ }
+ elsif ( $hash->{INPUT} ne "2B" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
+ $return .= fhem "sleep 1;set $name channelUp";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "chup" );
+ }
+ }
+
+ # currentTrackPosition
+ elsif ( lc( @$a[1] ) eq "currenttrackposition" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+
+ if ( @$a[2] !~ /^[0-9][0-9]:[0-5][0-9]$/ ) {
+ $return =
+ "Time needs to have format mm:ss and between 00:00 and 99:59";
+ }
+ else {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "net-usb-time-seek", @$a[2] );
+ }
+ }
+ }
+
+ # internet-radio-preset
+ elsif ( lc( @$a[1] ) eq "internet-radio-preset" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name " . @$a[1] . " " . @$a[2];
+ }
+ elsif ( $hash->{INPUT} ne "2B" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
+ $return .= fhem "sleep 5;set $name " . @$a[1] . " " . @$a[2];
+ }
+ elsif ( @$a[2] =~ /^\d*$/ ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ $return = ONKYO_AVR_SendCommand(
+ $hash,
+ lc( @$a[1] ),
+ ONKYO_AVR_dec2hex( @$a[2] )
+ );
+ }
+ else {
+ $return = "Invalid argument format";
+ }
+ }
+ }
+
+ # preset
+ elsif ( lc( @$a[1] ) eq "preset" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name preset " . @$a[2];
+ }
+ elsif ( $hash->{INPUT} ne "24" && $hash->{INPUT} ne "25" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "24" );
+ $return .= fhem "sleep 1;set $name preset " . @$a[2];
+ }
+ elsif ( lc( @$a[2] ) eq "up" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ $return = ONKYO_AVR_SendCommand( $hash, lc( @$a[1] ), "UP" );
+ }
+ elsif ( lc( @$a[2] ) eq "down" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ $return =
+ ONKYO_AVR_SendCommand( $hash, lc( @$a[1] ), "DOWN" );
+ }
+ elsif ( @$a[2] =~ /^\d*$/ ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ $return = ONKYO_AVR_SendCommand(
+ $hash,
+ lc( @$a[1] ),
+ ONKYO_AVR_dec2hex( @$a[2] )
+ );
+ }
+ elsif ( defined( $hash->{helper}{receiver}{preset} ) ) {
+
+ foreach
+ my $id ( sort keys %{ $hash->{helper}{receiver}{preset} } )
+ {
+ my $presetName =
+ $hash->{helper}{receiver}{preset}{$id};
+ next if ( !$presetName || $presetName eq "" );
+
+ $presetName =~ s/\s/_/g;
+
+ if ( $presetName eq @$a[2] ) {
+ Log3 $name, 3,
+ "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ $return =
+ ONKYO_AVR_SendCommand( $hash, lc( @$a[1] ), uc($id) );
+
+ last;
+ }
+ }
+ }
+ }
+ }
+
+ # presetDown
+ elsif ( lc( @$a[1] ) eq "presetdown" ) {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name presetDown";
+ }
+ elsif ( $hash->{INPUT} ne "24" && $hash->{INPUT} ne "25" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "24" );
+ $return .= fhem "sleep 1;set $name presetDown";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "preset", "down" );
+ }
+ }
+
+ # presetUp
+ elsif ( lc( @$a[1] ) eq "presetup" ) {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 5;set $name presetUp";
+ }
+ elsif ( $hash->{INPUT} ne "24" && $hash->{INPUT} ne "25" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "24" );
+ $return .= fhem "sleep 1;set $name presetUp";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "preset", "up" );
+ }
+ }
+
+ # tone-*
+ elsif ( lc( @$a[1] ) =~ /^(tone.*)-(bass|treble)$/ ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+ if ( $state eq "off" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ elsif ( lc( @$a[2] ) eq "up" ) {
+ my $setVal = "";
+ $setVal = "B" if ( $2 eq "bass" );
+ $setVal = "T" if ( $2 eq "treble" );
+ $return =
+ ONKYO_AVR_SendCommand( $hash, lc($1), $setVal . "UP" );
+ }
+ elsif ( lc( @$a[2] ) eq "down" ) {
+ my $setVal = "";
+ $setVal = "B" if ( $2 eq "bass" );
+ $setVal = "T" if ( $2 eq "treble" );
+ $return =
+ ONKYO_AVR_SendCommand( $hash, lc($1), $setVal . "DOWN" );
+ }
+ elsif ( @$a[2] =~ /^-*\d+$/ ) {
+ my $setVal = "";
+ $setVal = "B" if ( $2 eq "bass" );
+ $setVal = "T" if ( $2 eq "treble" );
+ $setVal .= "+" if ( @$a[2] > 0 );
+ $setVal .= "-" if ( @$a[2] < 0 );
+
+ my $setVal2 = @$a[2];
+ $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 < 0 );
+ $setVal2 = ONKYO_AVR_dec2hex($setVal2);
+ $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 ne "00" );
+
+ $return =
+ ONKYO_AVR_SendCommand( $hash, lc($1), $setVal . $setVal2 );
+ }
+ }
+ }
+
+ # center-temporary-level
+ # subwoofer-temporary-level
+ elsif (lc( @$a[1] ) eq "center-temporary-level"
+ || lc( @$a[1] ) eq "subwoofer-temporary-level" )
+ {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+ if ( $state eq "off" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ elsif ( lc( @$a[2] ) eq "up" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, lc($1), "UP" );
+ }
+ elsif ( lc( @$a[2] ) eq "down" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, lc($1), "DOWN" );
+ }
+ elsif ( @$a[2] =~ /^-*\d+$/ ) {
+ my $setVal = "";
+ $setVal = "+" if ( @$a[2] > 0 );
+ $setVal = "-" if ( @$a[2] < 0 );
+
+ my $setVal2 = @$a[2];
+ $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 < 0 );
+ $setVal2 = ONKYO_AVR_dec2hex($setVal2);
+ $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 ne "00" );
+
+ $return = ONKYO_AVR_SendCommand(
+ $hash,
+ lc( @$a[1] ),
+ $setVal . $setVal2
+ );
+ }
+ }
+ }
+
+ # toggle
+ elsif ( lc( @$a[1] ) eq "toggle" ) {
+ if ( $state eq "off" ) {
+ $return = fhem "set $name on";
+ }
+ else {
+ $return = fhem "set $name off";
+ }
+ }
+
+ # on
+ elsif ( lc( @$a[1] ) eq "on" ) {
+ if ( $presence eq "absent" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " (wakeup)";
+ my $wakeupCmd = AttrVal( $name, "wakeupCmd", "" );
+
+ if ( $wakeupCmd ne "" ) {
+ $wakeupCmd =~ s/\$DEVICE/$name/g;
+
+ if ( $wakeupCmd =~ s/^[ \t]*\{|\}[ \t]*$//g ) {
+ Log3 $name, 4,
+ "ONKYO_AVR executing wake-up command (Perl): $wakeupCmd";
+ $return = eval $wakeupCmd;
+ }
+ else {
+ Log3 $name, 4,
+ "ONKYO_AVR executing wake-up command (fhem): $wakeupCmd";
+ $return = fhem $wakeupCmd;
+ }
+ }
+ else {
+ $return =
+ "Device is offline and cannot be controlled at that stage.";
+ $return .=
+"\nYou may enable network-standby to allow a permanent connection to the device by the following command:\nget $name remoteControl network-standby on"
+ if ( ReadingsVal( $name, "network-standby", "off" ) ne "on" );
+ }
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+
+ # don't wait for receiver to confirm power on
+ #
+
+ readingsBeginUpdate($hash);
+
+ # power
+ readingsBulkUpdate( $hash, "power", "on" )
+ if ( ReadingsVal( $name, "power", "-" ) ne "on" );
+
+ # stateAV
+ my $stateAV = ONKYO_AVR_GetStateAV($hash);
+ readingsBulkUpdate( $hash, "stateAV", $stateAV )
+ if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
+
+ readingsEndUpdate( $hash, 1 );
+ }
+ }
+
+ # off
+ elsif ( lc( @$a[1] ) eq "off" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "off" );
+ }
+
+ # remoteControl
+ elsif ( lc( @$a[1] ) eq "remotecontrol" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given, choose one of minutes off";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( lc( @$a[2] ) eq "play"
+ || lc( @$a[2] ) eq "pause"
+ || lc( @$a[2] ) eq "repeat"
+ || lc( @$a[2] ) eq "stop"
+ || lc( @$a[2] ) eq "top"
+ || lc( @$a[2] ) eq "down"
+ || lc( @$a[2] ) eq "up"
+ || lc( @$a[2] ) eq "right"
+ || lc( @$a[2] ) eq "delete"
+ || lc( @$a[2] ) eq "display"
+ || lc( @$a[2] ) eq "ff"
+ || lc( @$a[2] ) eq "left"
+ || lc( @$a[2] ) eq "mode"
+ || lc( @$a[2] ) eq "return"
+ || lc( @$a[2] ) eq "rew"
+ || lc( @$a[2] ) eq "select"
+ || lc( @$a[2] ) eq "setup"
+ || lc( @$a[2] ) eq "0"
+ || lc( @$a[2] ) eq "1"
+ || lc( @$a[2] ) eq "2"
+ || lc( @$a[2] ) eq "3"
+ || lc( @$a[2] ) eq "4"
+ || lc( @$a[2] ) eq "5"
+ || lc( @$a[2] ) eq "6"
+ || lc( @$a[2] ) eq "7"
+ || lc( @$a[2] ) eq "8"
+ || lc( @$a[2] ) eq "9" )
+ {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "net-usb", lc( @$a[2] ) );
+ }
+ elsif ( lc( @$a[2] ) eq "prev" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trdown" );
+ }
+ elsif ( lc( @$a[2] ) eq "next" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trup" );
+ }
+ elsif ( lc( @$a[2] ) eq "shuffle" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "random" );
+ }
+ elsif ( lc( @$a[2] ) eq "menu" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "men" );
+ }
+ else {
+ $return = "Unsupported remoteControl command: " . @$a[2];
+ }
+
+ }
+ }
+
+ # play
+ elsif ( lc( @$a[1] ) eq "play" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "play" );
+ }
+ }
+
+ # pause
+ elsif ( lc( @$a[1] ) eq "pause" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "pause" );
+ }
+ }
+
+ # stop
+ elsif ( lc( @$a[1] ) eq "stop" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "stop" );
+ }
+ }
+
+ # shuffle
+ elsif ( lc( @$a[1] ) eq "shuffle" || lc( @$a[1] ) eq "shufflet" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "random" );
+ }
+ }
+
+ # repeat
+ elsif ( lc( @$a[1] ) eq "repeat" || lc( @$a[1] ) eq "repeatt" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "repeat" );
+ }
+ }
+
+ # previous
+ elsif ( lc( @$a[1] ) eq "previous" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trdown" );
+ }
+ }
+
+ # next
+ elsif ( lc( @$a[1] ) eq "next" ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+
+ if ( $state ne "on" ) {
+ $return =
+"Device power is turned off, this function is unavailable at that stage.";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trup" );
+ }
+ }
+
+ # sleep
+ elsif ( lc( @$a[1] ) eq "sleep" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given, choose one of minutes off";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( @$a[2] eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "sleep", "off" );
+ }
+ elsif ( @$a[2] =~ m/^\d+$/ && @$a[2] > 0 && @$a[2] <= 90 ) {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "sleep",
+ ONKYO_AVR_dec2hex( @$a[2] ) );
+ }
+ else {
+ $return =
+"Argument does not seem to be a valid integer between 0 and 90";
+ }
+ }
+ }
+
+ # mute
+ elsif ( lc( @$a[1] ) eq "mute" || lc( @$a[1] ) eq "mutet" ) {
+ if ( defined( @$a[2] ) ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ }
+
+ if ( $state eq "on" ) {
+ if ( !defined( @$a[2] ) || @$a[2] eq "toggle" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "mute", "toggle" );
+ }
+ elsif ( lc( @$a[2] ) eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "mute", "off" );
+ }
+ elsif ( lc( @$a[2] ) eq "on" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "mute", "on" );
+ }
+ else {
+ $return = "Argument does not seem to be one of on off toogle";
+ }
+ }
+ else {
+ $return = "Device needs to be ON to mute/unmute audio.";
+ }
+ }
+
+ # volume
+ elsif ( lc( @$a[1] ) eq "volume" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( $state eq "on" ) {
+ if ( @$a[2] =~ m/^\d+$/ && @$a[2] >= 0 && @$a[2] <= 100 ) {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "volume",
+ ONKYO_AVR_dec2hex( @$a[2] ) );
+ }
+ else {
+ $return =
+"Argument does not seem to be a valid integer between 0 and 100";
+ }
+ }
+ else {
+ $return = "Device needs to be ON to adjust volume.";
+ }
+ }
+ }
+
+ # volumeUp/volumeDown
+ elsif ( lc( @$a[1] ) =~ /^(volumeup|volumedown)$/ ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ my $volumeSteps = AttrVal( $name, "volumeSteps", "1" );
+ my $volume = ReadingsVal( $name, "volume", "0" );
+
+ if ( $state eq "on" ) {
+ if ( lc( @$a[1] ) eq "volumeup" ) {
+ if ( $volumeSteps > 1 ) {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "volume",
+ ONKYO_AVR_dec2hex( $volume + $volumeSteps ) );
+ }
+ else {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "volume", "level-up" );
+ }
+ }
+ else {
+ if ( $volumeSteps > 1 ) {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "volume",
+ ONKYO_AVR_dec2hex( $volume - $volumeSteps ) );
+ }
+ else {
+ $return =
+ ONKYO_AVR_SendCommand( $hash, "volume", "level-down" );
+ }
+ }
+ }
+ else {
+ $return = "Device needs to be ON to adjust volume.";
+ }
+ }
+
+ # input
+ elsif ( lc( @$a[1] ) eq "input" ) {
+ if ( !defined( @$a[2] ) ) {
+ $return = "No input given";
+ }
+ else {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 2;set $name input " . @$a[2];
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ $return = ONKYO_AVR_SendCommand( $hash, "input", @$a[2] );
+ }
+ }
+ }
+
+ # inputUp
+ elsif ( lc( @$a[1] ) eq "inputup" ) {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 2;set $name inputUp";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "up" );
+ }
+ }
+
+ # inputDown
+ elsif ( lc( @$a[1] ) eq "inputdown" ) {
+ if ( $state eq "off" ) {
+ $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
+ $return .= fhem "sleep 2;set $name inputDown";
+ }
+ else {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
+ $return = ONKYO_AVR_SendCommand( $hash, "input", "down" );
+ }
+ }
+
+ # implicit commands through available readings
+ elsif ( grep $_ eq lc( @$a[1] ), @implicit_cmds ) {
+ Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+
+ if ( !defined( @$a[2] ) ) {
+ $return = "No argument given";
+ }
+ else {
+ $return = ONKYO_AVR_SendCommand( $hash, @$a[1], @$a[2] );
+ }
+ }
+
+ # return usage hint
+ else {
+ $return = $usage;
+ }
+
+ readingsEndUpdate( $hash, 1 );
+
+ # return result
+ return $return;
+}
+
+sub ONKYO_AVR_Get($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+ my $zone = $hash->{ZONE};
+ my $state = ReadingsVal( $name, "power", "off" );
+ my $presence = ReadingsVal( $name, "presence", "absent" );
+ my $commands = ONKYOdb::ONKYO_GetRemotecontrolCommand($zone);
+ my $commands_details = ONKYOdb::ONKYO_GetRemotecontrolCommandDetails($zone);
+ my $return;
+
+ Log3 $name, 5, "ONKYO_AVR $name: called function ONKYO_AVR_Get()";
+
+ return "Argument is missing" if ( int(@$a) < 1 );
+
+ # readings
+ return $hash->{READINGS}{ @$a[1] }{VAL}
+ if ( defined( $hash->{READINGS}{ @$a[1] } ) );
+
+ return "Device is offline and cannot be controlled at that stage."
+ if ( $presence eq "absent" );
+
+ # createZone
+ if ( lc( @$a[1] ) eq "createzone" ) {
+
+ if ( !defined( @$a[2] ) ) {
+ $return = "Syntax: ZONE ID or NAME";
+ }
+ else {
+ $return =
+ fhem "define "
+ . $name . "_"
+ . @$a[2]
+ . " ONKYO_AVR_ZONE "
+ . @$a[2];
+ $return = $name . "_" . @$a[2] . " created"
+ if ( !$return || $return eq "" );
+ }
+ }
+
+ # statusRequest
+ elsif ( lc( @$a[1] ) eq "statusrequest" ) {
+ Log3 $name, 3, "ONKYO_AVR get $name " . @$a[1];
+
+ ONKYO_AVR_SendCommand( $hash, "power", "query" );
+ ONKYO_AVR_SendCommand( $hash, "input", "query" );
+ ONKYO_AVR_SendCommand( $hash, "mute", "query" );
+ ONKYO_AVR_SendCommand( $hash, "volume", "query" );
+ ONKYO_AVR_SendCommand( $hash, "sleep", "query" );
+ ONKYO_AVR_SendCommand( $hash, "audio-information", "query" );
+ ONKYO_AVR_SendCommand( $hash, "video-information", "query" );
+ ONKYO_AVR_SendCommand( $hash, "listening-mode", "query" );
+ ONKYO_AVR_SendCommand( $hash, "video-picture-mode", "query" );
+ ONKYO_AVR_SendCommand( $hash, "phase-matching-bass", "query" );
+ ONKYO_AVR_SendCommand( $hash, "center-temporary-level", "query" );
+ ONKYO_AVR_SendCommand( $hash, "subwoofer-temporary-level", "query" );
+ fhem
+"sleep 1 quiet;get $name remoteControl net-receiver-information query quiet";
+ }
+
+ # remoteControl
+ elsif ( lc( @$a[1] ) eq "remotecontrol" ) {
+
+ # Output help for commands
+ if ( !defined( @$a[2] ) || @$a[2] eq "help" || @$a[2] eq "?" ) {
+
+ my $valid_commands =
+ "Usage: \n\nValid commands in zone$zone:\n\n\n"
+ . "COMMAND\t\t\tDESCRIPTION\n\n";
+
+ # For each valid command
+ foreach my $command ( sort keys %{$commands} ) {
+ my $command_raw = $commands->{$command};
+
+ # add command including description if found
+ if ( defined( $commands_details->{$command_raw}{description} ) )
+ {
+ $valid_commands .=
+ $command
+ . "\t\t\t"
+ . $commands_details->{$command_raw}{description} . "\n";
+ }
+
+ # add command only
+ else {
+ $valid_commands .= $command . "\n";
+ }
+ }
+
+ $valid_commands .=
+"\nTry '<command> help' to find out well known values.\n\n\n";
+
+ $return = $valid_commands;
+ }
+ else {
+ # Reading values for command from HASH table
+ my $values =
+ ONKYOdb::ONKYO_GetRemotecontrolValue( $zone,
+ $commands->{ @$a[2] } );
+
+ @$a[3] = "query"
+ if ( !defined( @$a[3] ) && defined( $values->{query} ) );
+
+ # Output help for values
+ if ( !defined( @$a[3] ) || @$a[3] eq "help" || @$a[3] eq "?" ) {
+
+ # Get all details for command
+ my $command_details =
+ ONKYOdb::ONKYO_GetRemotecontrolCommandDetails( $zone,
+ $commands->{ @$a[2] } );
+
+ my $valid_values =
+ "Usage: "
+ . @$a[2]
+ . " \n\nWell known values:\n\n\n"
+ . "VALUE\t\t\tDESCRIPTION\n\n";
+
+ # For each valid value
+ foreach my $value ( sort keys %{$values} ) {
+
+ # add value including description if found
+ if ( defined( $command_details->{description} ) ) {
+ $valid_values .=
+ $value
+ . "\t\t\t"
+ . $command_details->{description} . "\n";
+ }
+
+ # add value only
+ else {
+ $valid_values .= $value . "\n";
+ }
+ }
+
+ $valid_values .= "\n\n\n";
+
+ $return = $valid_values;
+ }
+
+ # normal processing
+ else {
+ Log3 $name, 3,
+ "ONKYO_AVR get $name " . @$a[1] . " " . @$a[2] . " " . @$a[3]
+ if ( !@$a[4] || @$a[4] ne "quiet" );
+
+ ONKYO_AVR_SendCommand( $hash, @$a[2], @$a[3] );
+ $return = "Sent command: " . @$a[2] . " " . @$a[3]
+ if ( !@$a[4] || @$a[4] ne "quiet" );
+ }
+ }
+ }
+
+ else {
+ $return =
+ "Unknown argument " . @$a[1] . ", choose one of statusRequest:noArg";
+
+ # createZone
+ my $zones = "";
+ if ( defined( $hash->{helper}{receiver}{device}{zonelist}{zone} ) ) {
+ foreach my $zoneID (
+ keys %{ $hash->{helper}{receiver}{device}{zonelist}{zone} } )
+ {
+ next
+ if (
+ !defined(
+ $hash->{helper}{receiver}{device}{zonelist}{zone}
+ {$zoneID}{value}
+ )
+ || $hash->{helper}{receiver}{device}{zonelist}{zone}
+ {$zoneID}{value} ne "1"
+ || $zoneID eq "1"
+ );
+ $zones .= "," if ( $zones ne "" );
+ $zones .= $zoneID;
+ }
+ }
+ $return .= " createZone:$zones" if ( $zones ne "" );
+ $return .= " createZone:2,3,4" if ( $zones eq "" );
+
+ # remoteControl
+ $return .= " remoteControl:";
+ foreach my $command ( sort keys %{$commands} ) {
+ $return .= "," . $command;
+ }
+ }
+
+ return $return;
}
-###################################
sub ONKYO_AVR_Read($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -1744,7 +2657,33 @@ sub ONKYO_AVR_Read($) {
return;
}
-###################################
+sub ONKYO_AVR_Write($$) {
+ my ( $hash, $cmd ) = @_;
+ my $name = $hash->{NAME};
+ my $str = ONKYO_AVR_Pack( $cmd, $hash->{PROTOCOLVERSION} );
+
+ Log3 $name, 1,
+"ONKYO_AVR $name: $hash->{DeviceName} snd ERROR - could not transcode $cmd to HEX command"
+ and return
+ if ( !$str );
+
+ # Log3 $name, 5,
+ # "ONKYO_AVR $name: $hash->{DeviceName} snd " . ONKYO_AVR_hexdump($str);
+ Log3 $name, 5, "ONKYO_AVR $name: $hash->{DeviceName} snd $str";
+
+ DevIo_SimpleWrite( $hash, "$str", 0 );
+
+ # do connection check latest after TIMEOUT
+ my $next = gettimeofday() + $hash->{TIMEOUT};
+ if ( !defined( $hash->{helper}{nextConnectionCheck} )
+ || $hash->{helper}{nextConnectionCheck} > $next )
+ {
+ $hash->{helper}{nextConnectionCheck} = $next;
+ RemoveInternalTimer($hash);
+ InternalTimer( $next, "ONKYO_AVR_connectionCheck", $hash, 0 );
+ }
+}
+
sub ONKYO_AVR_Ready($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -1771,1196 +2710,227 @@ sub ONKYO_AVR_Ready($) {
return ( $InBytes && $InBytes > 0 );
}
-###################################
-sub ONKYO_AVR_Get($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
- my $zone = $hash->{ZONE};
- my $state = ReadingsVal( $name, "power", "off" );
- my $presence = ReadingsVal( $name, "presence", "absent" );
- my $commands = ONKYOdb::ONKYO_GetRemotecontrolCommand($zone);
- my $commands_details = ONKYOdb::ONKYO_GetRemotecontrolCommandDetails($zone);
- my $return;
+sub ONKYO_AVR_Notify($$) {
+ my ( $hash, $dev ) = @_;
+ my $name = $hash->{NAME};
+ my $devName = $dev->{NAME};
+ my $definedZones = scalar keys %{ $modules{ONKYO_AVR_ZONE}{defptr}{$name} };
+ my $presence = ReadingsVal( $name, "presence", "-" );
- Log3 $name, 5, "ONKYO_AVR $name: called function ONKYO_AVR_Get()";
+ return
+ if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
- return "Argument is missing" if ( int(@$a) < 1 );
+ # work on global events related to us
+ if ( $devName eq "global" ) {
+ foreach my $change ( @{ $dev->{CHANGED} } ) {
+ if ( $change !~ /^(\w+)\s(\w+)\s?(\w*)\s?(.*)$/
+ || $2 ne $name )
+ {
+ return;
+ }
- # readings
- return $hash->{READINGS}{ @$a[1] }{VAL}
- if ( defined( $hash->{READINGS}{ @$a[1] } ) );
+ # DEFINED
+ # MODIFIED
+ elsif ( $1 eq "DEFINED" || $1 eq "MODIFIED" ) {
+ Log3 $hash, 5,
+ "ONKYO_AVR "
+ . $name
+ . ": processing my global event $1: $3 -> $4";
- return "Device is offline and cannot be controlled at that stage."
- if ( $presence eq "absent" );
-
- # createZone
- if ( lc( @$a[1] ) eq "createzone" ) {
-
- if ( !defined( @$a[2] ) ) {
- $return = "Syntax: ZONE ID or NAME";
- }
- else {
- $return =
- fhem "define "
- . $name . "_"
- . @$a[2]
- . " ONKYO_AVR_ZONE "
- . @$a[2];
- $return = $name . "_" . @$a[2] . " created"
- if ( !$return || $return eq "" );
- }
- }
-
- # statusRequest
- elsif ( lc( @$a[1] ) eq "statusrequest" ) {
- Log3 $name, 3, "ONKYO_AVR get $name " . @$a[1];
-
- ONKYO_AVR_SendCommand( $hash, "power", "query" );
- ONKYO_AVR_SendCommand( $hash, "input", "query" );
- ONKYO_AVR_SendCommand( $hash, "mute", "query" );
- ONKYO_AVR_SendCommand( $hash, "volume", "query" );
- ONKYO_AVR_SendCommand( $hash, "sleep", "query" );
- ONKYO_AVR_SendCommand( $hash, "audio-information", "query" );
- ONKYO_AVR_SendCommand( $hash, "video-information", "query" );
- ONKYO_AVR_SendCommand( $hash, "listening-mode", "query" );
- ONKYO_AVR_SendCommand( $hash, "video-picture-mode", "query" );
- ONKYO_AVR_SendCommand( $hash, "phase-matching-bass", "query" );
- ONKYO_AVR_SendCommand( $hash, "center-temporary-level", "query" );
- ONKYO_AVR_SendCommand( $hash, "subwoofer-temporary-level", "query" );
- fhem
-"sleep 1 quiet;get $name remoteControl net-receiver-information query quiet";
- }
-
- # remoteControl
- elsif ( lc( @$a[1] ) eq "remotecontrol" ) {
-
- # Output help for commands
- if ( !defined( @$a[2] ) || @$a[2] eq "help" || @$a[2] eq "?" ) {
-
- my $valid_commands =
- "Usage: \n\nValid commands in zone$zone:\n\n\n"
- . "COMMAND\t\t\tDESCRIPTION\n\n";
-
- # For each valid command
- foreach my $command ( sort keys %{$commands} ) {
- my $command_raw = $commands->{$command};
-
- # add command including description if found
- if ( defined( $commands_details->{$command_raw}{description} ) )
- {
- $valid_commands .=
- $command
- . "\t\t\t"
- . $commands_details->{$command_raw}{description} . "\n";
+ if ( lc( ReadingsVal( $name, "state", "?" ) ) eq "opened" ) {
+ DoTrigger( $name, "CONNECTED" );
}
-
- # add command only
else {
- $valid_commands .= $command . "\n";
+ DoTrigger( $name, "DISCONNECTED" );
}
}
- $valid_commands .=
-"\nTry '<command> help' to find out well known values.\n\n\n";
-
- $return = $valid_commands;
- }
- else {
- # Reading values for command from HASH table
- my $values =
- ONKYOdb::ONKYO_GetRemotecontrolValue( $zone,
- $commands->{ @$a[2] } );
-
- @$a[3] = "query"
- if ( !defined( @$a[3] ) && defined( $values->{query} ) );
-
- # Output help for values
- if ( !defined( @$a[3] ) || @$a[3] eq "help" || @$a[3] eq "?" ) {
-
- # Get all details for command
- my $command_details =
- ONKYOdb::ONKYO_GetRemotecontrolCommandDetails( $zone,
- $commands->{ @$a[2] } );
-
- my $valid_values =
- "Usage: "
- . @$a[2]
- . " \n\nWell known values:\n\n\n"
- . "VALUE\t\t\tDESCRIPTION\n\n";
-
- # For each valid value
- foreach my $value ( sort keys %{$values} ) {
-
- # add value including description if found
- if ( defined( $command_details->{description} ) ) {
- $valid_values .=
- $value
- . "\t\t\t"
- . $command_details->{description} . "\n";
- }
-
- # add value only
- else {
- $valid_values .= $value . "\n";
- }
- }
-
- $valid_values .= "\n\n\n";
-
- $return = $valid_values;
- }
-
- # normal processing
+ # unknown event
else {
- Log3 $name, 3,
- "ONKYO_AVR get $name " . @$a[1] . " " . @$a[2] . " " . @$a[3]
- if ( !@$a[4] || @$a[4] ne "quiet" );
-
- ONKYO_AVR_SendCommand( $hash, @$a[2], @$a[3] );
- $return = "Sent command: " . @$a[2] . " " . @$a[3]
- if ( !@$a[4] || @$a[4] ne "quiet" );
- }
- }
- }
-
- else {
- $return =
- "Unknown argument " . @$a[1] . ", choose one of statusRequest:noArg";
-
- # createZone
- my $zones = "";
- if ( defined( $hash->{helper}{receiver}{device}{zonelist}{zone} ) ) {
- foreach my $zoneID (
- keys %{ $hash->{helper}{receiver}{device}{zonelist}{zone} } )
- {
- next
- if (
- !defined(
- $hash->{helper}{receiver}{device}{zonelist}{zone}
- {$zoneID}{value}
- )
- || $hash->{helper}{receiver}{device}{zonelist}{zone}
- {$zoneID}{value} ne "1"
- || $zoneID eq "1"
- );
- $zones .= "," if ( $zones ne "" );
- $zones .= $zoneID;
- }
- }
- $return .= " createZone:$zones" if ( $zones ne "" );
- $return .= " createZone:2,3,4" if ( $zones eq "" );
-
- # remoteControl
- $return .= " remoteControl:";
- foreach my $command ( sort keys %{$commands} ) {
- $return .= "," . $command;
- }
- }
-
- return $return if ($return);
-}
-
-###################################
-sub ONKYO_AVR_Set($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
- my $zone = $hash->{ZONE};
- my $state = ReadingsVal( $name, "power", "off" );
- my $presence = ReadingsVal( $name, "presence", "absent" );
- my $return;
- my $reading;
- my $inputs_txt = "";
- my $channels_txt = "";
- my @implicit_cmds;
- my $implicit_txt = "";
-
- Log3 $name, 5, "ONKYO_AVR $name: called function ONKYO_AVR_Set()";
-
- return "Argument is missing" if ( int(@$a) < 1 );
-
- # Input alias handling
- if ( defined( $attr{$name}{inputs} ) && $attr{$name}{inputs} ne "" ) {
- my @inputs = split( ':', $attr{$name}{inputs} );
-
- if (@inputs) {
- foreach (@inputs) {
- if (m/[^,\s]+(,[^,\s]+)+/) {
- my @input_names = split( ',', $_ );
- $inputs_txt .= $input_names[1] . ",";
- $input_names[1] =~ s/\s/_/g;
- $hash->{helper}{receiver}{input_aliases}{ $input_names[0] }
- = $input_names[1];
- $hash->{helper}{receiver}{input_names}{ $input_names[1] } =
- $input_names[0];
- }
- else {
- $inputs_txt .= $_ . ",";
- }
+ Log3 $hash, 5,
+ "ONKYO_AVR "
+ . $name
+ . ": WONT BE processing my global event $1: $3 -> $4";
}
}
- $inputs_txt =~ s/\s/_/g;
- $inputs_txt = substr( $inputs_txt, 0, -1 );
+ return;
}
- # if we could read the actual available inputs from the receiver, use them
- elsif (defined( $hash->{helper}{receiver} )
- && ref( $hash->{helper}{receiver} ) eq "HASH"
- && defined( $hash->{helper}{receiver}{device}{selectorlist}{count} )
- && $hash->{helper}{receiver}{device}{selectorlist}{count} > 0 )
- {
-
- foreach my $input (
- @{ $hash->{helper}{receiver}{device}{selectorlist}{selector} } )
- {
- if ( $input->{value} eq "1"
- && $input->{zone} ne "00"
- && $input->{id} ne "80" )
- {
- my $id = $input->{id};
- my $name = trim( $input->{name} );
- $inputs_txt .= $name . ",";
- }
- }
-
- $inputs_txt =~ s/\s/_/g;
- $inputs_txt = substr( $inputs_txt, 0, -1 );
+ # do nothing for any other device
+ elsif ( $devName ne $name ) {
+ return;
}
- # use general list of possible inputs
- else {
- # Find out valid inputs
- my $inputs =
- ONKYOdb::ONKYO_GetRemotecontrolValue( $zone,
- ONKYOdb::ONKYO_GetRemotecontrolCommand( $zone, "input" ) );
-
- foreach my $input ( sort keys %{$inputs} ) {
- $inputs_txt .= $input . ","
- if ( !( $input =~ /^(07|08|09|up|down|query)$/ ) );
- }
- $inputs_txt = substr( $inputs_txt, 0, -1 );
- }
-
- # list of network channels/services
- my $channels_src = "internal";
- if ( defined( $hash->{helper}{receiver} )
- && ref( $hash->{helper}{receiver} ) eq "HASH"
- && defined( $hash->{helper}{receiver}{device}{netservicelist}{count} )
- && $hash->{helper}{receiver}{device}{netservicelist}{count} > 0 )
- {
-
- foreach my $id (
- sort keys
- %{ $hash->{helper}{receiver}{device}{netservicelist}{netservice} } )
- {
- if (
- defined(
- $hash->{helper}{receiver}{device}{netservicelist}
- {netservice}{$id}{value}
- )
- && $hash->{helper}{receiver}{device}{netservicelist}
- {netservice}{$id}{value} eq "1"
- )
- {
- $channels_txt .=
- trim( $hash->{helper}{receiver}{device}{netservicelist}
- {netservice}{$id}{name} )
- . ",";
- }
- }
-
- $channels_txt =~ s/\s/_/g;
- $channels_txt = substr( $channels_txt, 0, -1 );
- $channels_src = "receiver";
- }
-
- # use general list of possible channels
- else {
- # Find out valid channels
- my $channels =
- ONKYOdb::ONKYO_GetRemotecontrolValue( "1",
- ONKYOdb::ONKYO_GetRemotecontrolCommand( "1", "net-service" ) );
-
- foreach my $channel ( sort keys %{$channels} ) {
- $channels_txt .= $channel . ","
- if ( !( $channel =~ /^(up|down|query)$/ ) );
- }
- $channels_txt = substr( $channels_txt, 0, -1 );
- }
-
- # for each reading, check if there is a known command for it
- # and allow to set values if there are any available
- if ( defined( $hash->{READINGS} ) ) {
-
- foreach my $reading ( keys %{ $hash->{READINGS} } ) {
- my $cmd_raw =
- ONKYOdb::ONKYO_GetRemotecontrolCommand( $zone, $reading );
- my @readingExceptions = (
- "volume", "input", "mute", "sleep", "center-temporary-level",
- "subwoofer-temporary-level", "balance", "preset",
- );
-
- if ( $cmd_raw && !( grep $_ eq $reading, @readingExceptions ) ) {
- my $cmd_details =
- ONKYOdb::ONKYO_GetRemotecontrolCommandDetails( $zone,
- $cmd_raw );
-
- my $value_list = "";
- my $debuglist;
- foreach my $value ( keys %{ $cmd_details->{values} } ) {
- next
- if ( $value eq "QSTN" );
-
- if ( defined( $cmd_details->{values}{$value}{name} ) ) {
- $value_list .= "," if ( $value_list ne "" );
-
- $value_list .= $cmd_details->{values}{$value}{name}
- if (
- ref( $cmd_details->{values}{$value}{name} ) eq "" );
-
- $value_list .= $cmd_details->{values}{$value}{name}[0]
- if (
- ref( $cmd_details->{values}{$value}{name} ) eq
- "ARRAY" );
- }
- }
-
- if ( $value_list ne "" ) {
- push @implicit_cmds, $reading;
- $implicit_txt .= " $reading:$value_list";
- }
- }
-
- # tone-*
- elsif ( $reading =~ /^tone.*-([a-zA-Z]+)$/ ) {
- $implicit_txt .= " $reading:slider,-10,1,10";
- }
-
- # center-temporary-level
- elsif ( $reading eq "center-temporary-level" ) {
- $implicit_txt .= " $reading:slider,-12,1,12";
- }
-
- # subwoofer*-temporary-level
- elsif ( $reading =~ /^subwoofer.*-temporary-level$/ ) {
- $implicit_txt .= " $reading:slider,-15,1,12";
- }
- }
- }
-
- my $preset_txt = "";
- if ( defined( $hash->{helper}{receiver}{preset} ) ) {
-
- foreach my $id (
- sort
- keys %{ $hash->{helper}{receiver}{preset} }
- )
- {
- my $presetName =
- $hash->{helper}{receiver}{preset}{$id};
- next if ( !$presetName || $presetName eq "" );
-
- $preset_txt = "preset:" if ( $preset_txt eq "" );
- $preset_txt .= ","
- if ( $preset_txt eq "preset:"
- && ReadingsVal( $name, "preset", "-" ) eq "" );
-
- $presetName =~ s/\s/_/g;
- $preset_txt .= $presetName . ",";
- }
- }
- $preset_txt = substr( $preset_txt, 0, -1 ) if ( $preset_txt ne "" );
-
- if ( $preset_txt eq "" ) {
- $preset_txt = "preset:";
- $preset_txt .= "," if ( ReadingsVal( $name, "preset", "-" ) eq "" );
- $preset_txt .=
-"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40";
- }
-
- my $shuffle_txt = "shuffle:";
- $shuffle_txt .= "," if ( ReadingsVal( $name, "shuffle", "-" ) eq "-" );
- $shuffle_txt .= "off,on,on-album,on-folder";
-
- my $repeat_txt = "repeat:";
- $repeat_txt .= "," if ( ReadingsVal( $name, "repeat", "-" ) eq "-" );
- $repeat_txt .= "off,all,all-folder,one";
-
- my $usage =
- "Unknown argument '"
- . @$a[1]
- . "', choose one of toggle:noArg on:noArg off:noArg volume:slider,0,1,100 volumeDown:noArg volumeUp:noArg mute:off,on muteT:noArg play:noArg pause:noArg stop:noArg previous:noArg next:noArg shuffleT:noArg repeatT:noArg remoteControl:play,pause,repeat,stop,top,down,up,right,delete,display,ff,left,mode,return,rew,select,setup,0,1,2,3,4,5,6,7,8,9,prev,next,shuffle,menu channelDown:noArg channelUp:noArg inputDown:noArg inputUp:noArg internet-radio-preset:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40 input:"
- . $inputs_txt;
- $usage .= " channel:$channels_txt";
- $usage .= " presetDown:noArg presetUp:noArg $preset_txt";
- $usage .= " $shuffle_txt";
- $usage .= " $repeat_txt";
- $usage .= $implicit_txt if ( $implicit_txt ne "" );
- $usage .= " sleep:off,5,10,15,30,60,90";
-
- if ( ReadingsVal( $name, "currentTrackPosition", "--:--" ) ne "--:--" ) {
- $usage .= " currentTrackPosition";
- }
-
- my $cmd = '';
-
- return "Device is offline and cannot be controlled at that stage."
- if ( $presence eq "absent"
- && lc( @$a[1] ) ne "on"
- && lc( @$a[1] ) ne "?"
- && lc( @$a[1] ) ne "help" );
-
readingsBeginUpdate($hash);
- # create inputList reading for frontends
- readingsBulkUpdate( $hash, "inputList", $inputs_txt )
- if ( ReadingsVal( $name, "inputList", "-" ) ne $inputs_txt );
+ foreach my $change ( @{ $dev->{CHANGED} } ) {
- # create channelList reading for frontends
- readingsBulkUpdate( $hash, "channelList", $channels_txt )
- if (
- (
- $channels_src eq "internal"
- && ReadingsVal( $name, "channelList", "-" ) eq "-"
- )
- || ( $channels_src eq "receiver"
- && ReadingsVal( $name, "channelList", "-" ) ne $channels_txt )
- );
+ # DISCONNECTED
+ if ( $change eq "DISCONNECTED" ) {
+ Log3 $hash, 5, "ONKYO_AVR " . $name . ": processing change $change";
- # channel
- if ( lc( @$a[1] ) eq "channel" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "Syntax: CHANNELNAME [USERNAME PASSWORD]";
- }
- else {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name channel " . @$a[2];
- }
- elsif ( $hash->{INPUT} ne "2B" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
- $return .= fhem "sleep 1;set $name channel " . @$a[2];
- }
- elsif ( ReadingsVal( $name, "channel", "" ) ne @$a[2]
- || ( defined( @$a[3] ) && defined( @$a[4] ) ) )
- {
+ # disable connectionCheck and wait
+ # until DevIo reopened the connection
+ RemoveInternalTimer($hash);
- my $servicename = "";
- my $channelname = @$a[2];
+ readingsBulkUpdate( $hash, "presence", "absent" )
+ if ( $presence ne "absent" );
- if (
- defined( $hash->{helper}{receiver} )
- && ref( $hash->{helper}{receiver} ) eq "HASH"
- && defined(
- $hash->{helper}{receiver}{device}{netservicelist}{count}
- )
- && $hash->{helper}{receiver}{device}{netservicelist}{count}
- > 0
- )
- {
-
- $channelname =~ s/_/ /g;
-
- foreach my $id (
- sort keys %{
- $hash->{helper}{receiver}{device}{netservicelist}
- {netservice}
- }
- )
- {
- if (
- defined(
- $hash->{helper}{receiver}{device}
- {netservicelist}{netservice}{$id}{value}
- )
- && $hash->{helper}{receiver}{device}
- {netservicelist}{netservice}{$id}{value} eq "1"
- && $hash->{helper}{receiver}{device}
- {netservicelist}{netservice}{$id}{name} eq
- $channelname
- )
- {
- $servicename .= uc($id);
- last;
- }
- }
- }
- else {
- my $channels = ONKYOdb::ONKYO_GetRemotecontrolValue(
- "1",
- ONKYOdb::ONKYO_GetRemotecontrolCommand(
- "1", "net-service"
- )
- );
-
- $servicename = $channels->{$channelname}
- if ( defined( $channels->{$channelname} ) );
- }
-
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- $servicename = uc($channelname)
- if ( $servicename eq "" );
-
- $servicename .= "0" if ( !defined( @$a[3] ) );
- $servicename .= "1" . @$a[3] if ( defined( @$a[3] ) );
- $servicename .= @$a[4] if ( defined( @$a[4] ) );
-
- $return =
- ONKYO_AVR_SendCommand( $hash, "net-service", $servicename );
- }
- }
- }
-
- # channelDown
- elsif ( lc( @$a[1] ) eq "channeldown" ) {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name channelDown";
- }
- elsif ( $hash->{INPUT} ne "2B" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
- $return .= fhem "sleep 1;set $name channelDown";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "chdn" );
- }
- }
-
- # channelUp
- elsif ( lc( @$a[1] ) eq "channelup" ) {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name channelUp";
- }
- elsif ( $hash->{INPUT} ne "2B" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
- $return .= fhem "sleep 1;set $name channelUp";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "chup" );
- }
- }
-
- # currentTrackPosition
- elsif ( lc( @$a[1] ) eq "currenttrackposition" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
-
- if ( @$a[2] !~ /^[0-9][0-9]:[0-5][0-9]$/ ) {
- $return =
- "Time needs to have format mm:ss and between 00:00 and 99:59";
- }
- else {
- $return =
- ONKYO_AVR_SendCommand( $hash, "net-usb-time-seek", @$a[2] );
- }
- }
- }
-
- # internet-radio-preset
- elsif ( lc( @$a[1] ) eq "internet-radio-preset" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name " . @$a[1] . " " . @$a[2];
- }
- elsif ( $hash->{INPUT} ne "2B" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "2B" );
- $return .= fhem "sleep 5;set $name " . @$a[1] . " " . @$a[2];
- }
- elsif ( @$a[2] =~ /^\d*$/ ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
- $return = ONKYO_AVR_SendCommand(
- $hash,
- lc( @$a[1] ),
- ONKYO_AVR_dec2hex( @$a[2] )
- );
- }
- else {
- $return = "Invalid argument format";
- }
- }
- }
-
- # preset
- elsif ( lc( @$a[1] ) eq "preset" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name preset " . @$a[2];
- }
- elsif ( $hash->{INPUT} ne "24" && $hash->{INPUT} ne "25" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "24" );
- $return .= fhem "sleep 1;set $name preset " . @$a[2];
- }
- elsif ( lc( @$a[2] ) eq "up" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
- $return = ONKYO_AVR_SendCommand( $hash, lc( @$a[1] ), "UP" );
- }
- elsif ( lc( @$a[2] ) eq "down" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
- $return =
- ONKYO_AVR_SendCommand( $hash, lc( @$a[1] ), "DOWN" );
- }
- elsif ( @$a[2] =~ /^\d*$/ ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
- $return = ONKYO_AVR_SendCommand(
- $hash,
- lc( @$a[1] ),
- ONKYO_AVR_dec2hex( @$a[2] )
- );
- }
- elsif ( defined( $hash->{helper}{receiver}{preset} ) ) {
-
- foreach
- my $id ( sort keys %{ $hash->{helper}{receiver}{preset} } )
- {
- my $presetName =
- $hash->{helper}{receiver}{preset}{$id};
- next if ( !$presetName || $presetName eq "" );
-
- $presetName =~ s/\s/_/g;
-
- if ( $presetName eq @$a[2] ) {
- Log3 $name, 3,
- "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- $return =
- ONKYO_AVR_SendCommand( $hash, lc( @$a[1] ), uc($id) );
-
- last;
- }
- }
- }
- }
- }
-
- # presetDown
- elsif ( lc( @$a[1] ) eq "presetdown" ) {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name presetDown";
- }
- elsif ( $hash->{INPUT} ne "24" && $hash->{INPUT} ne "25" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "24" );
- $return .= fhem "sleep 1;set $name presetDown";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "preset", "down" );
- }
- }
-
- # presetUp
- elsif ( lc( @$a[1] ) eq "presetup" ) {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 5;set $name presetUp";
- }
- elsif ( $hash->{INPUT} ne "24" && $hash->{INPUT} ne "25" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "input", "24" );
- $return .= fhem "sleep 1;set $name presetUp";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "preset", "up" );
- }
- }
-
- # tone-*
- elsif ( lc( @$a[1] ) =~ /^(tone.*)-(bass|treble)$/ ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
- if ( $state eq "off" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- elsif ( lc( @$a[2] ) eq "up" ) {
- my $setVal = "";
- $setVal = "B" if ( $2 eq "bass" );
- $setVal = "T" if ( $2 eq "treble" );
- $return =
- ONKYO_AVR_SendCommand( $hash, lc($1), $setVal . "UP" );
- }
- elsif ( lc( @$a[2] ) eq "down" ) {
- my $setVal = "";
- $setVal = "B" if ( $2 eq "bass" );
- $setVal = "T" if ( $2 eq "treble" );
- $return =
- ONKYO_AVR_SendCommand( $hash, lc($1), $setVal . "DOWN" );
- }
- elsif ( @$a[2] =~ /^-*\d+$/ ) {
- my $setVal = "";
- $setVal = "B" if ( $2 eq "bass" );
- $setVal = "T" if ( $2 eq "treble" );
- $setVal .= "+" if ( @$a[2] > 0 );
- $setVal .= "-" if ( @$a[2] < 0 );
-
- my $setVal2 = @$a[2];
- $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 < 0 );
- $setVal2 = ONKYO_AVR_dec2hex($setVal2);
- $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 ne "00" );
-
- $return =
- ONKYO_AVR_SendCommand( $hash, lc($1), $setVal . $setVal2 );
- }
- }
- }
-
- # center-temporary-level
- # subwoofer-temporary-level
- elsif (lc( @$a[1] ) eq "center-temporary-level"
- || lc( @$a[1] ) eq "subwoofer-temporary-level" )
- {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
- if ( $state eq "off" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- elsif ( lc( @$a[2] ) eq "up" ) {
- $return = ONKYO_AVR_SendCommand( $hash, lc($1), "UP" );
- }
- elsif ( lc( @$a[2] ) eq "down" ) {
- $return = ONKYO_AVR_SendCommand( $hash, lc($1), "DOWN" );
- }
- elsif ( @$a[2] =~ /^-*\d+$/ ) {
- my $setVal = "";
- $setVal = "+" if ( @$a[2] > 0 );
- $setVal = "-" if ( @$a[2] < 0 );
-
- my $setVal2 = @$a[2];
- $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 < 0 );
- $setVal2 = ONKYO_AVR_dec2hex($setVal2);
- $setVal2 = substr( $setVal2, 1 ) if ( $setVal2 ne "00" );
-
- $return = ONKYO_AVR_SendCommand(
- $hash,
- lc( @$a[1] ),
- $setVal . $setVal2
- );
- }
- }
- }
-
- # toggle
- elsif ( lc( @$a[1] ) eq "toggle" ) {
- if ( $state eq "off" ) {
- $return = fhem "set $name on";
- }
- else {
- $return = fhem "set $name off";
- }
- }
-
- # on
- elsif ( lc( @$a[1] ) eq "on" ) {
- if ( $presence eq "absent" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " (wakeup)";
- my $wakeupCmd = AttrVal( $name, "wakeupCmd", "" );
-
- if ( $wakeupCmd ne "" ) {
- $wakeupCmd =~ s/\$DEVICE/$name/g;
-
- if ( $wakeupCmd =~ s/^[ \t]*\{|\}[ \t]*$//g ) {
- Log3 $name, 4,
- "ONKYO_AVR executing wake-up command (Perl): $wakeupCmd";
- $return = eval $wakeupCmd;
- }
- else {
- Log3 $name, 4,
- "ONKYO_AVR executing wake-up command (fhem): $wakeupCmd";
- $return = fhem $wakeupCmd;
- }
- }
- else {
- $return =
- "Device is offline and cannot be controlled at that stage.";
- $return .=
-"\nYou may enable network-standby to allow a permanent connection to the device by the following command:\nget $name remoteControl network-standby on"
- if ( ReadingsVal( $name, "network-standby", "off" ) ne "on" );
- }
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
-
- # don't wait for receiver to confirm power on
- #
-
- readingsBeginUpdate($hash);
-
- # power
- readingsBulkUpdate( $hash, "power", "on" )
- if ( ReadingsVal( $name, "power", "-" ) ne "on" );
+ readingsBulkUpdate( $hash, "power", "off" )
+ if ( ReadingsVal( $name, "power", "on" ) ne "off" );
# stateAV
my $stateAV = ONKYO_AVR_GetStateAV($hash);
readingsBulkUpdate( $hash, "stateAV", $stateAV )
if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
- readingsEndUpdate( $hash, 1 );
+ # send to slaves
+ if ( $definedZones > 1 ) {
+ Log3 $name, 5,
+ "ONKYO_AVR $name: Dispatching state change to slaves";
+ Dispatch(
+ $hash,
+ {
+ "presence" => "absent",
+ "power" => "off",
+ },
+ undef
+ );
+ }
}
- }
- # off
- elsif ( lc( @$a[1] ) eq "off" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "power", "off" );
- }
+ # CONNECTED
+ elsif ( $change eq "CONNECTED" ) {
+ Log3 $hash, 5, "ONKYO_AVR " . $name . ": processing change $change";
- # remoteControl
- elsif ( lc( @$a[1] ) eq "remotecontrol" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given, choose one of minutes off";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
+ readingsBulkUpdate( $hash, "presence", "present" )
+ if ( $presence ne "present" );
- if ( lc( @$a[2] ) eq "play"
- || lc( @$a[2] ) eq "pause"
- || lc( @$a[2] ) eq "repeat"
- || lc( @$a[2] ) eq "stop"
- || lc( @$a[2] ) eq "top"
- || lc( @$a[2] ) eq "down"
- || lc( @$a[2] ) eq "up"
- || lc( @$a[2] ) eq "right"
- || lc( @$a[2] ) eq "delete"
- || lc( @$a[2] ) eq "display"
- || lc( @$a[2] ) eq "ff"
- || lc( @$a[2] ) eq "left"
- || lc( @$a[2] ) eq "mode"
- || lc( @$a[2] ) eq "return"
- || lc( @$a[2] ) eq "rew"
- || lc( @$a[2] ) eq "select"
- || lc( @$a[2] ) eq "setup"
- || lc( @$a[2] ) eq "0"
- || lc( @$a[2] ) eq "1"
- || lc( @$a[2] ) eq "2"
- || lc( @$a[2] ) eq "3"
- || lc( @$a[2] ) eq "4"
- || lc( @$a[2] ) eq "5"
- || lc( @$a[2] ) eq "6"
- || lc( @$a[2] ) eq "7"
- || lc( @$a[2] ) eq "8"
- || lc( @$a[2] ) eq "9" )
- {
- $return =
- ONKYO_AVR_SendCommand( $hash, "net-usb", lc( @$a[2] ) );
- }
- elsif ( lc( @$a[2] ) eq "prev" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trdown" );
- }
- elsif ( lc( @$a[2] ) eq "next" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trup" );
- }
- elsif ( lc( @$a[2] ) eq "shuffle" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "random" );
- }
- elsif ( lc( @$a[2] ) eq "menu" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "men" );
- }
- else {
- $return = "Unsupported remoteControl command: " . @$a[2];
+ # stateAV
+ my $stateAV = ONKYO_AVR_GetStateAV($hash);
+ readingsBulkUpdate( $hash, "stateAV", $stateAV )
+ if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
+
+ ONKYO_AVR_SendCommand( $hash, "power", "query" );
+ ONKYO_AVR_SendCommand( $hash, "network-standby", "query" );
+ ONKYO_AVR_SendCommand( $hash, "input", "query" );
+ ONKYO_AVR_SendCommand( $hash, "mute", "query" );
+ ONKYO_AVR_SendCommand( $hash, "volume", "query" );
+ ONKYO_AVR_SendCommand( $hash, "sleep", "query" );
+ ONKYO_AVR_SendCommand( $hash, "audio-information", "query" );
+ ONKYO_AVR_SendCommand( $hash, "video-information", "query" );
+ ONKYO_AVR_SendCommand( $hash, "listening-mode", "query" );
+ ONKYO_AVR_SendCommand( $hash, "video-picture-mode", "query" );
+ ONKYO_AVR_SendCommand( $hash, "phase-matching-bass", "query" );
+ ONKYO_AVR_SendCommand( $hash, "center-temporary-level", "query" );
+ ONKYO_AVR_SendCommand( $hash, "subwoofer-temporary-level",
+ "query" );
+ fhem
+"sleep 1 quiet;get $name remoteControl net-receiver-information query quiet";
+
+ # send to slaves
+ if ( $definedZones > 1 ) {
+ Log3 $name, 5,
+ "ONKYO_AVR $name: Dispatching state change to slaves";
+ Dispatch(
+ $hash,
+ {
+ "presence" => "present",
+ },
+ undef
+ );
}
}
}
- # play
- elsif ( lc( @$a[1] ) eq "play" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "play" );
- }
- }
-
- # pause
- elsif ( lc( @$a[1] ) eq "pause" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "pause" );
- }
- }
-
- # stop
- elsif ( lc( @$a[1] ) eq "stop" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "stop" );
- }
- }
-
- # shuffle
- elsif ( lc( @$a[1] ) eq "shuffle" || lc( @$a[1] ) eq "shufflet" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "random" );
- }
- }
-
- # repeat
- elsif ( lc( @$a[1] ) eq "repeat" || lc( @$a[1] ) eq "repeatt" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "repeat" );
- }
- }
-
- # previous
- elsif ( lc( @$a[1] ) eq "previous" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trdown" );
- }
- }
-
- # next
- elsif ( lc( @$a[1] ) eq "next" ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
-
- if ( $state ne "on" ) {
- $return =
-"Device power is turned off, this function is unavailable at that stage.";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, "net-usb", "trup" );
- }
- }
-
- # sleep
- elsif ( lc( @$a[1] ) eq "sleep" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given, choose one of minutes off";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- if ( @$a[2] eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "sleep", "off" );
- }
- elsif ( @$a[2] =~ m/^\d+$/ && @$a[2] > 0 && @$a[2] <= 90 ) {
- $return =
- ONKYO_AVR_SendCommand( $hash, "sleep",
- ONKYO_AVR_dec2hex( @$a[2] ) );
- }
- else {
- $return =
-"Argument does not seem to be a valid integer between 0 and 90";
- }
- }
- }
-
- # mute
- elsif ( lc( @$a[1] ) eq "mute" || lc( @$a[1] ) eq "mutet" ) {
- if ( defined( @$a[2] ) ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- }
-
- if ( $state eq "on" ) {
- if ( !defined( @$a[2] ) || @$a[2] eq "toggle" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "mute", "toggle" );
- }
- elsif ( lc( @$a[2] ) eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "mute", "off" );
- }
- elsif ( lc( @$a[2] ) eq "on" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "mute", "on" );
- }
- else {
- $return = "Argument does not seem to be one of on off toogle";
- }
- }
- else {
- $return = "Device needs to be ON to mute/unmute audio.";
- }
- }
-
- # volume
- elsif ( lc( @$a[1] ) eq "volume" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- if ( $state eq "on" ) {
- if ( @$a[2] =~ m/^\d+$/ && @$a[2] >= 0 && @$a[2] <= 100 ) {
- $return =
- ONKYO_AVR_SendCommand( $hash, "volume",
- ONKYO_AVR_dec2hex( @$a[2] ) );
- }
- else {
- $return =
-"Argument does not seem to be a valid integer between 0 and 100";
- }
- }
- else {
- $return = "Device needs to be ON to adjust volume.";
- }
- }
- }
-
- # volumeUp/volumeDown
- elsif ( lc( @$a[1] ) =~ /^(volumeup|volumedown)$/ ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- my $volumeSteps = AttrVal( $name, "volumeSteps", "1" );
- my $volume = ReadingsVal( $name, "volume", "0" );
-
- if ( $state eq "on" ) {
- if ( lc( @$a[1] ) eq "volumeup" ) {
- if ( $volumeSteps > 1 ) {
- $return =
- ONKYO_AVR_SendCommand( $hash, "volume",
- ONKYO_AVR_dec2hex( $volume + $volumeSteps ) );
- }
- else {
- $return =
- ONKYO_AVR_SendCommand( $hash, "volume", "level-up" );
- }
- }
- else {
- if ( $volumeSteps > 1 ) {
- $return =
- ONKYO_AVR_SendCommand( $hash, "volume",
- ONKYO_AVR_dec2hex( $volume - $volumeSteps ) );
- }
- else {
- $return =
- ONKYO_AVR_SendCommand( $hash, "volume", "level-down" );
- }
- }
- }
- else {
- $return = "Device needs to be ON to adjust volume.";
- }
- }
-
- # input
- elsif ( lc( @$a[1] ) eq "input" ) {
- if ( !defined( @$a[2] ) ) {
- $return = "No input given";
- }
- else {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 2;set $name input " . @$a[2];
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
- $return = ONKYO_AVR_SendCommand( $hash, "input", @$a[2] );
- }
- }
- }
-
- # inputUp
- elsif ( lc( @$a[1] ) eq "inputup" ) {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 2;set $name inputUp";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "input", "up" );
- }
- }
-
- # inputDown
- elsif ( lc( @$a[1] ) eq "inputdown" ) {
- if ( $state eq "off" ) {
- $return = ONKYO_AVR_SendCommand( $hash, "power", "on" );
- $return .= fhem "sleep 2;set $name inputDown";
- }
- else {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1];
- $return = ONKYO_AVR_SendCommand( $hash, "input", "down" );
- }
- }
-
- # implicit commands through available readings
- elsif ( grep $_ eq lc( @$a[1] ), @implicit_cmds ) {
- Log3 $name, 3, "ONKYO_AVR set $name " . @$a[1] . " " . @$a[2];
-
- if ( !defined( @$a[2] ) ) {
- $return = "No argument given";
- }
- else {
- $return = ONKYO_AVR_SendCommand( $hash, @$a[1], @$a[2] );
- }
- }
-
- # return usage hint
- else {
- $return = $usage;
- }
-
readingsEndUpdate( $hash, 1 );
-
- # return result
- return $return;
}
-############################################################################################################
-#
-# Begin of helper functions
-#
-############################################################################################################
+sub ONKYO_AVR_Shutdown($) {
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+ Log3 $name, 5, "ONKYO_AVR $name: called function ONKYO_AVR_Shutdown()";
+
+ DevIo_CloseDev($hash);
+ return undef;
+}
+
+# module Fn ####################################################################
+sub ONKYO_AVR_DevInit($) {
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+
+ if ( lc( ReadingsVal( $name, "state", "?" ) ) eq "opened" ) {
+ DoTrigger( $name, "CONNECTED" );
+ }
+ else {
+ DoTrigger( $name, "DISCONNECTED" );
+ }
+}
+
+sub ONKYO_AVR_addExtension($$$) {
+ my ( $name, $func, $link ) = @_;
+
+ my $url = "?/$link";
+
+ return 0
+ if ( defined( $data{FWEXT}{$url} )
+ && $data{FWEXT}{$url}{deviceName} ne $name );
+
+ Log3 $name, 2,
+ "ONKYO_AVR $name: Registering ONKYO_AVR for webhook URI $url ...";
+ $data{FWEXT}{$url}{deviceName} = $name;
+ $data{FWEXT}{$url}{FUNC} = $func;
+ $data{FWEXT}{$url}{LINK} = $link;
+
+ return 1;
+}
+
+sub ONKYO_AVR_removeExtension($) {
+ my ($link) = @_;
+
+ my $url = "?/$link";
+ my $name = $data{FWEXT}{$url}{deviceName};
+ Log3 $name, 2,
+ "ONKYO_AVR $name: Unregistering ONKYO_AVR for webhook URI $url...";
+ delete $data{FWEXT}{$url};
+}
+
+sub ONKYO_AVR_CGI() {
+ my ($request) = @_;
+
+ # data received
+ if ( $request =~ m,^\?\/ONKYO_AVR\/cover\/(.+)\.(.+)$, ) {
+
+ Log3 undef, 5, "ONKYO_AVR: sending cover $1.$2";
+
+ if ( $1 eq "empty" && $2 eq "jpg" ) {
+ FW_serveSpecial( 'sonos_empty', 'jpg',
+ AttrVal( "global", "modpath", "." ) . '/FHEM/lib/UPnP', 1 );
+ }
+ else {
+ FW_serveSpecial(
+ $1,
+ $2,
+ AttrVal( "global", "modpath", "." )
+ . '/www/images/default/ONKYO_AVR',
+ 1
+ );
+ }
+
+ return ( undef, undef );
+ }
+
+ # no data received
+ else {
+ Log3 undef, 5, "ONKYO_AVR: received malformed request\n$request";
+ }
+
+ return ( "text/plain; charset=utf-8", "Call failure: " . $request );
+}
-###################################
sub ONKYO_AVR_SendCommand($$$) {
my ( $hash, $cmd, $value ) = @_;
my $name = $hash->{NAME};
@@ -3029,35 +2999,6 @@ sub ONKYO_AVR_SendCommand($$$) {
return;
}
-###################################
-sub ONKYO_AVR_Write($$) {
- my ( $hash, $cmd ) = @_;
- my $name = $hash->{NAME};
- my $str = ONKYO_AVR_Pack( $cmd, $hash->{PROTOCOLVERSION} );
-
- Log3 $name, 1,
-"ONKYO_AVR $name: $hash->{DeviceName} snd ERROR - could not transcode $cmd to HEX command"
- and return
- if ( !$str );
-
- # Log3 $name, 5,
- # "ONKYO_AVR $name: $hash->{DeviceName} snd " . ONKYO_AVR_hexdump($str);
- Log3 $name, 5, "ONKYO_AVR $name: $hash->{DeviceName} snd $str";
-
- DevIo_SimpleWrite( $hash, "$str", 0 );
-
- # do connection check latest after TIMEOUT
- my $next = gettimeofday() + $hash->{TIMEOUT};
- if ( !defined( $hash->{helper}{nextConnectionCheck} )
- || $hash->{helper}{nextConnectionCheck} > $next )
- {
- $hash->{helper}{nextConnectionCheck} = $next;
- RemoveInternalTimer($hash);
- InternalTimer( $next, "ONKYO_AVR_connectionCheck", $hash, 0 );
- }
-}
-
-###################################
sub ONKYO_AVR_connectionCheck ($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -3089,7 +3030,6 @@ sub ONKYO_AVR_connectionCheck ($) {
delete $attr{$name}{verbose} if ( $verbose eq "" );
}
-###################################
sub ONKYO_AVR_WriteFile($$) {
my ( $fileName, $data ) = @_;
@@ -3099,7 +3039,6 @@ sub ONKYO_AVR_WriteFile($$) {
close IMGFILE;
}
-###################################
sub ONKYO_AVR_Pack($;$) {
my ( $d, $protocol ) = @_;
@@ -3149,7 +3088,6 @@ sub ONKYO_AVR_Pack($;$) {
pack( "a* N N N a*", 'ISCP', 0x10, ( length $d ), 0x01000000, $d );
}
-###################################
sub ONKYO_AVR_hexdump {
my $s = shift;
my $r = unpack 'H*', $s;
@@ -3157,19 +3095,16 @@ sub ONKYO_AVR_hexdump {
$r . ' ' . $s;
}
-###################################
sub ONKYO_AVR_hex2dec($) {
my ($hex) = @_;
return unpack( 's', pack 's', hex($hex) );
}
-###################################
sub ONKYO_AVR_hex2image($) {
my ($hex) = @_;
return pack( "H*", $hex );
}
-###################################
sub ONKYO_AVR_dec2hex($) {
my ($dec) = @_;
my $hex = uc( sprintf( "%x", $dec ) );
@@ -3178,7 +3113,6 @@ sub ONKYO_AVR_dec2hex($) {
return $hex;
}
-###################################
sub ONKYO_AVR_GetStateAV($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -3202,8 +3136,6 @@ sub ONKYO_AVR_GetStateAV($) {
}
}
-#####################################
-# Callback from 95_remotecontrol for command makenotify.
sub ONKYO_AVR_RCmakenotify($$) {
my ( $name, $ndev ) = @_;
my $nname = "notify_$name";
@@ -3213,9 +3145,6 @@ sub ONKYO_AVR_RCmakenotify($$) {
return "Notify created by ENIGMA2: $nname";
}
-#####################################
-# RC layouts
-
sub ONKYO_AVR_RClayout_SVG() {
my @row;
diff --git a/fhem/FHEM/70_PHTV.pm b/fhem/FHEM/70_PHTV.pm
index aa64522b0..b5fd4ccb7 100644
--- a/fhem/FHEM/70_PHTV.pm
+++ b/fhem/FHEM/70_PHTV.pm
@@ -1,68 +1,29 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 70_PHTV.pm
-# An FHEM Perl module for controlling Philips Televisons
-# via network connection.
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
package main;
-use 5.012;
use strict;
use warnings;
use Data::Dumper;
use Time::HiRes qw(gettimeofday);
use HttpUtils;
use Color;
-use SetExtensions;
use Encode;
-sub PHTV_Set($@);
-sub PHTV_Get($@);
-sub PHTV_GetStatus($;$);
-sub PHTV_Define($$);
-sub PHTV_Notify($$);
-sub PHTV_Undefine($$);
-
-#########################
-# Forward declaration for remotecontrol module
-#sub PHTV_RClayout_TV();
-#sub PHTV_RCmakenotify($$);
-
-###################################
+# initialize ##################################################################
sub PHTV_Initialize($) {
my ($hash) = @_;
Log3 $hash, 5, "PHTV_Initialize: Entering";
- $hash->{GetFn} = "PHTV_Get";
- $hash->{SetFn} = "PHTV_Set";
- $hash->{NotifyFn} = "PHTV_Notify";
$hash->{DefFn} = "PHTV_Define";
$hash->{UndefFn} = "PHTV_Undefine";
+ $hash->{SetFn} = "PHTV_Set";
+ $hash->{GetFn} = "PHTV_Get";
+ $hash->{NotifyFn} = "PHTV_Notify";
$hash->{AttrList} =
-"disable:0,1 timeout sequentialQuery:0,1 drippyFactor:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 inputs ambiHueLeft ambiHueRight ambiHueTop ambiHueBottom ambiHueLatency:150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000 jsversion:1,5,6 macaddr:textField model wakeupCmd:textField channelsMax:slider,30,1,200 httpLoglevel:1,2,3,4,5 sslVersion device_id auth_key "
+"disable:0,1 disabledForIntervals do_not_notify:1,0 timeout sequentialQuery:0,1 drippyFactor:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 inputs ambiHueLeft ambiHueRight ambiHueTop ambiHueBottom ambiHueLatency:150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000 jsversion:1,5,6 macaddr:textField model wakeupCmd:textField channelsMax:slider,30,1,200 httpLoglevel:1,2,3,4,5 sslVersion device_id auth_key "
. $readingFnAttributes;
$data{RC_layout}{PHTV_SVG} = "PHTV_RClayout_SVG";
@@ -88,170 +49,73 @@ sub PHTV_Initialize($) {
};
FHEM_colorpickerInit();
-
- return;
}
-#####################################
-sub PHTV_GetStatus($;$) {
- my ( $hash, $update ) = @_;
- my $name = $hash->{NAME};
- my $interval = $hash->{INTERVAL};
- my $presence = ReadingsVal( $name, "presence", "absent" );
- my $sequential = AttrVal( $name, "sequentialQuery", 0 );
- my $querySent = 0;
-
- Log3 $name, 5, "PHTV $name: called function PHTV_GetStatus()";
-
- $interval = $interval * 1.6
- if ( ReadingsVal( $name, "ambiHue", "off" ) eq "on" );
-
- RemoveInternalTimer($hash);
- InternalTimer( gettimeofday() + $interval, "PHTV_GetStatus", $hash, 0 );
-
- return
- if ( IsDisabled($name) );
-
- # try to fetch only some information to check device availability
- if ( !$update ) {
- PHTV_SendCommand( $hash, "audio/volume" ) if ( $presence eq "present" );
- PHTV_SendCommand( $hash, "system" ) if ( $presence eq "absent" );
-
- # in case we should query the device gently, mark we already sent a query
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter} = 1 if $sequential;
- }
-
- # fetch other info if device is on
- if ( !$querySent
- && ( ReadingsVal( $name, "state", "off" ) eq "on" || $update ) )
- {
-
- # Read device info every 15 minutes only
- if (
- !$querySent
- && (
- !defined( $hash->{helper}{lastFullUpdate} )
- || ( !$update
- && $hash->{helper}{lastFullUpdate} + 900 le time() )
- )
- )
- {
- PHTV_SendCommand( $hash, "system" );
- PHTV_SendCommand( $hash, "ambilight/topology" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
-
- # Update state
- $hash->{helper}{lastFullUpdate} = time();
- }
-
- # read audio volume
- if ( !$querySent && $update ) {
- PHTV_SendCommand( $hash, "audio/volume" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
- }
-
- # read ambilight details
- if ( !$querySent ) {
-
- # read ambilight mode
- PHTV_SendCommand( $hash, "ambilight/mode" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
-
- # read ambilight RGB value
- PHTV_SendCommand( $hash, "ambilight/cached" )
- if ( ReadingsVal( $name, "ambiMode", "internal" ) ne "internal" );
- }
-
- # read all sources if not existing
- if (
- !$querySent
- && ( !defined( $hash->{helper}{device}{sourceName} )
- || !defined( $hash->{helper}{device}{sourceID} ) )
- )
- {
- PHTV_SendCommand( $hash, "sources" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
- }
-
- # otherwise read current source
- elsif ( !$querySent ) {
- PHTV_SendCommand( $hash, "sources/current" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
- }
-
- # read all channels if not existing
- if (
- !$querySent
- && ( !defined( $hash->{helper}{device}{channelName} )
- || !defined( $hash->{helper}{device}{channelID} ) )
- )
- {
- PHTV_SendCommand( $hash, "channels" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
- }
-
- # otherwise read current channel
- elsif ( !$querySent ) {
- PHTV_SendCommand( $hash, "channels/current" );
- $querySent = 1 if $sequential;
- $hash->{helper}{sequentialQueryCounter}++ if $sequential;
- }
-
- }
-
- # Input alias handling
- #
- if ( AttrVal( $name, "inputs", "" ) ne "" ) {
- my @inputs = split( ':', AttrVal( $name, "inputs", ":" ) );
-
- if (@inputs) {
- foreach (@inputs) {
- if (m/[^,\s]+(,[^,\s]+)+/) {
- my @input_names = split( ',', $_ );
- $input_names[1] =~ s/\s/_/g;
- $hash->{helper}{device}{inputAliases}{ $input_names[0] } =
- $input_names[1];
- $hash->{helper}{device}{inputNames}{ $input_names[1] } =
- $input_names[0];
- }
- }
- }
- }
-
- return;
-}
-
-###################################
-sub PHTV_Get($@) {
- my ( $hash, @a ) = @_;
+# regular Fn ##################################################################
+sub PHTV_Define($$) {
+ my ( $hash, $def ) = @_;
+ my @a = split( "[ \t][ \t]*", $def );
my $name = $hash->{NAME};
- my $state = ReadingsVal( $name, "state", "Initialized" );
- my $what;
- Log3 $name, 5, "PHTV $name: called function PHTV_Get()";
+ Log3 $name, 5, "PHTV $name: called function PHTV_Define()";
- return "argument is missing" if ( int(@a) < 2 );
- return if ( $state =~ /^(pairing.*|initialized)$/i );
+ eval {
+ require JSON;
+ import JSON qw( decode_json encode_json );
+ };
+ return "Please install Perl JSON to use module PHTV"
+ if ($@);
- $what = $a[1];
-
- if ( $what =~ /^(power|input|volume|mute|rgb)$/ ) {
- return ReadingsVal( $name, $what, "no such reading: $what" );
+ if ( int(@a) < 3 ) {
+ my $msg =
+ "Wrong syntax: define PHTV []";
+ Log3 $name, 4, $msg;
+ return $msg;
}
- else {
- return
-"Unknown argument $what, choose one of power:noArg input:noArg volume:noArg mute:noArg rgb:noArg ";
+
+ $hash->{TYPE} = "PHTV";
+
+ my $address = $a[2];
+ $hash->{helper}{ADDRESS} = $address;
+
+ # use interval of 45sec if not defined
+ my $interval = $a[3] || 45;
+ $hash->{INTERVAL} = $interval;
+
+ readingsSingleUpdate( $hash, "ambiHue", "off", 0 )
+ if ( ReadingsVal( $name, "ambiHue", "" ) ne "off" );
+
+ $hash->{model} = ReadingsVal( $name, "model", undef )
+ if ( ReadingsVal( $name, "model", undef ) );
+
+ $hash->{swversion} = ReadingsVal( $name, "softwareversion", undef )
+ if ( ReadingsVal( $name, "softwareversion", undef ) );
+
+ # set default settings on first define
+ if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
+ fhem 'attr ' . $name . ' webCmd volume:input:rgb';
+ fhem 'attr ' . $name
+ . ' devStateIcon on:rc_GREEN:off off:rc_YELLOW:on absent:rc_STOP:on';
+ fhem 'attr ' . $name . ' icon it_television';
+
+ PHTV_GetStatus($hash);
}
+
+ return;
+}
+
+sub PHTV_Undefine($$) {
+ my ( $hash, $arg ) = @_;
+ my $name = $hash->{NAME};
+
+ Log3 $name, 5, "PHTV $name: called function PHTV_Undefine()";
+
+ # Stop the internal GetStatus-Loop and exit
+ RemoveInternalTimer($hash);
+
+ return;
}
-###################################
sub PHTV_Set($@) {
my ( $hash, @a ) = @_;
my $name = $hash->{NAME};
@@ -1396,57 +1260,26 @@ sub PHTV_Set($@) {
return;
}
-###################################
-sub PHTV_Define($$) {
- my ( $hash, $def ) = @_;
- my @a = split( "[ \t][ \t]*", $def );
+sub PHTV_Get($@) {
+ my ( $hash, @a ) = @_;
my $name = $hash->{NAME};
+ my $state = ReadingsVal( $name, "state", "Initialized" );
+ my $what;
- Log3 $name, 5, "PHTV $name: called function PHTV_Define()";
+ Log3 $name, 5, "PHTV $name: called function PHTV_Get()";
- eval {
- require JSON;
- import JSON qw( decode_json encode_json );
- };
- return "Please install Perl JSON to use module PHTV"
- if ($@);
+ return "argument is missing" if ( int(@a) < 2 );
+ return if ( $state =~ /^(pairing.*|initialized)$/i );
- if ( int(@a) < 3 ) {
- my $msg =
- "Wrong syntax: define PHTV []";
- Log3 $name, 4, $msg;
- return $msg;
+ $what = $a[1];
+
+ if ( $what =~ /^(power|input|volume|mute|rgb)$/ ) {
+ return ReadingsVal( $name, $what, "no such reading: $what" );
}
-
- $hash->{TYPE} = "PHTV";
-
- my $address = $a[2];
- $hash->{helper}{ADDRESS} = $address;
-
- # use interval of 45sec if not defined
- my $interval = $a[3] || 45;
- $hash->{INTERVAL} = $interval;
-
- readingsSingleUpdate( $hash, "ambiHue", "off", 0 )
- if ( ReadingsVal( $name, "ambiHue", "" ) ne "off" );
-
- $hash->{model} = ReadingsVal( $name, "model", undef )
- if ( ReadingsVal( $name, "model", undef ) );
-
- $hash->{swversion} = ReadingsVal( $name, "softwareversion", undef )
- if ( ReadingsVal( $name, "softwareversion", undef ) );
-
- # set default settings on first define
- if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
- fhem 'attr ' . $name . ' webCmd volume:input:rgb';
- fhem 'attr ' . $name
- . ' devStateIcon on:rc_GREEN:off off:rc_YELLOW:on absent:rc_STOP:on';
- fhem 'attr ' . $name . ' icon it_television';
-
- PHTV_GetStatus($hash);
+ else {
+ return
+"Unknown argument $what, choose one of power:noArg input:noArg volume:noArg mute:noArg rgb:noArg ";
}
-
- return;
}
sub PHTV_Notify($$) {
@@ -1488,13 +1321,142 @@ sub PHTV_Notify($$) {
return undef;
}
-############################################################################################################
-#
-# Begin of helper functions
-#
-############################################################################################################
+# module Fn ####################################################################
+sub PHTV_GetStatus($;$) {
+ my ( $hash, $update ) = @_;
+ my $name = $hash->{NAME};
+ my $interval = $hash->{INTERVAL};
+ my $presence = ReadingsVal( $name, "presence", "absent" );
+ my $sequential = AttrVal( $name, "sequentialQuery", 0 );
+ my $querySent = 0;
+
+ Log3 $name, 5, "PHTV $name: called function PHTV_GetStatus()";
+
+ $interval = $interval * 1.6
+ if ( ReadingsVal( $name, "ambiHue", "off" ) eq "on" );
+
+ RemoveInternalTimer($hash);
+ InternalTimer( gettimeofday() + $interval, "PHTV_GetStatus", $hash, 0 );
+
+ return
+ if ( IsDisabled($name) );
+
+ # try to fetch only some information to check device availability
+ if ( !$update ) {
+ PHTV_SendCommand( $hash, "audio/volume" ) if ( $presence eq "present" );
+ PHTV_SendCommand( $hash, "system" ) if ( $presence eq "absent" );
+
+ # in case we should query the device gently, mark we already sent a query
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter} = 1 if $sequential;
+ }
+
+ # fetch other info if device is on
+ if ( !$querySent
+ && ( ReadingsVal( $name, "state", "off" ) eq "on" || $update ) )
+ {
+
+ # Read device info every 15 minutes only
+ if (
+ !$querySent
+ && (
+ !defined( $hash->{helper}{lastFullUpdate} )
+ || ( !$update
+ && $hash->{helper}{lastFullUpdate} + 900 le time() )
+ )
+ )
+ {
+ PHTV_SendCommand( $hash, "system" );
+ PHTV_SendCommand( $hash, "ambilight/topology" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+
+ # Update state
+ $hash->{helper}{lastFullUpdate} = time();
+ }
+
+ # read audio volume
+ if ( !$querySent && $update ) {
+ PHTV_SendCommand( $hash, "audio/volume" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+ }
+
+ # read ambilight details
+ if ( !$querySent ) {
+
+ # read ambilight mode
+ PHTV_SendCommand( $hash, "ambilight/mode" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+
+ # read ambilight RGB value
+ PHTV_SendCommand( $hash, "ambilight/cached" )
+ if ( ReadingsVal( $name, "ambiMode", "internal" ) ne "internal" );
+ }
+
+ # read all sources if not existing
+ if (
+ !$querySent
+ && ( !defined( $hash->{helper}{device}{sourceName} )
+ || !defined( $hash->{helper}{device}{sourceID} ) )
+ )
+ {
+ PHTV_SendCommand( $hash, "sources" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+ }
+
+ # otherwise read current source
+ elsif ( !$querySent ) {
+ PHTV_SendCommand( $hash, "sources/current" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+ }
+
+ # read all channels if not existing
+ if (
+ !$querySent
+ && ( !defined( $hash->{helper}{device}{channelName} )
+ || !defined( $hash->{helper}{device}{channelID} ) )
+ )
+ {
+ PHTV_SendCommand( $hash, "channels" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+ }
+
+ # otherwise read current channel
+ elsif ( !$querySent ) {
+ PHTV_SendCommand( $hash, "channels/current" );
+ $querySent = 1 if $sequential;
+ $hash->{helper}{sequentialQueryCounter}++ if $sequential;
+ }
+
+ }
+
+ # Input alias handling
+ #
+ if ( AttrVal( $name, "inputs", "" ) ne "" ) {
+ my @inputs = split( ':', AttrVal( $name, "inputs", ":" ) );
+
+ if (@inputs) {
+ foreach (@inputs) {
+ if (m/[^,\s]+(,[^,\s]+)+/) {
+ my @input_names = split( ',', $_ );
+ $input_names[1] =~ s/\s/_/g;
+ $hash->{helper}{device}{inputAliases}{ $input_names[0] } =
+ $input_names[1];
+ $hash->{helper}{device}{inputNames}{ $input_names[1] } =
+ $input_names[0];
+ }
+ }
+ }
+ }
+
+ return;
+}
-###################################
sub PHTV_SendCommandDelayed($) {
my ($par) = @_;
@@ -1507,7 +1469,6 @@ sub PHTV_SendCommandDelayed($) {
$par->{type} );
}
-###################################
sub PHTV_SendCommand($$;$$$) {
my ( $hash, $service, $cmd, $type, $delay ) = @_;
my $name = $hash->{NAME};
@@ -1613,7 +1574,7 @@ sub PHTV_SendCommand($$;$$$) {
'Accept-Charset' => 'UTF-8',
},
sslargs => {
- SSL_verify_mode => 0,
+ SSL_verify_mode => 'SSL_VERIFY_NONE',
},
}
);
@@ -1621,7 +1582,6 @@ sub PHTV_SendCommand($$;$$$) {
return;
}
-###################################
sub PHTV_ReceiveCommand($$$) {
my ( $param, $err, $data ) = @_;
my $hash = $param->{hash};
@@ -3079,20 +3039,6 @@ m/^\s*(([{\[][\s\S]+[}\]])|(\s*\s*\s*Ok\s*<\/title>\s*<\/head
return;
}
-###################################
-sub PHTV_Undefine($$) {
- my ( $hash, $arg ) = @_;
- my $name = $hash->{NAME};
-
- Log3 $name, 5, "PHTV $name: called function PHTV_Undefine()";
-
- # Stop the internal GetStatus-Loop and exit
- RemoveInternalTimer($hash);
-
- return;
-}
-
-###################################
sub PHTV_GetStateAV($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -3114,7 +3060,6 @@ sub PHTV_GetStateAV($) {
}
}
-###################################
sub PHTV_wake ($) {
my ($hash) = @_;
my $name = $hash->{NAME};
@@ -3153,8 +3098,6 @@ sub PHTV_wake ($) {
return 1;
}
-#####################################
-# Callback from 95_remotecontrol for command makenotify.
sub PHTV_RCmakenotify($$) {
my ( $nam, $ndev ) = @_;
my $nname = "notify_$nam";
@@ -3164,10 +3107,6 @@ sub PHTV_RCmakenotify($$) {
return "Notify created by PHTV: $nname";
}
-#####################################
-# RC layouts
-
-# Philips TV with SVG
sub PHTV_RClayout_SVG() {
my @row;
@@ -3202,7 +3141,6 @@ sub PHTV_RClayout_SVG() {
return @row;
}
-# Philips TV with PNG
sub PHTV_RClayout() {
my @row;
@@ -3233,7 +3171,6 @@ sub PHTV_RClayout() {
return @row;
}
-###################################
sub PHTV_GetRemotecontrolCommand($) {
my ($command) = @_;
my $commands = {
@@ -3305,26 +3242,22 @@ sub PHTV_GetRemotecontrolCommand($) {
}
}
-###################################
sub PHTV_isinteger {
defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}
-###################################
sub PHTV_bri2pct($) {
my ($bri) = @_;
return 0 if ( $bri <= 0 );
return int( $bri / 255 * 100 + 0.5 );
}
-###################################
sub PHTV_pct2bri($) {
my ($pct) = @_;
return 0 if ( $pct <= 0 );
return int( $pct / 100 * 255 + 0.5 );
}
-###################################
sub PHTV_hex2rgb($) {
my ($hex) = @_;
if ( uc($hex) =~ /^(..)(..)(..)$/ ) {
@@ -3339,7 +3272,6 @@ sub PHTV_hex2rgb($) {
}
}
-###################################
sub PHTV_rgb2hex($$$) {
my ( $r, $g, $b ) = @_;
my $return = sprintf( "%2.2X%2.2X%2.2X", $r, $g, $b );
@@ -3347,7 +3279,6 @@ sub PHTV_rgb2hex($$$) {
return uc($return);
}
-###################################
sub PHTV_hex2hsb($;$) {
my ( $hex, $type ) = @_;
$type = lc($type) if ( defined( ($type) && $type ne "" ) );
@@ -3364,14 +3295,12 @@ sub PHTV_hex2hsb($;$) {
}
}
-###################################
sub PHTV_hsb2hex($$$) {
my ( $h, $s, $b ) = @_;
my $rgb = PHTV_hsb2rgb( $h, $s, $b );
return PHTV_rgb2hex( $rgb->{r}, $rgb->{g}, $rgb->{b} );
}
-###################################
sub PHTV_rgb2hsb ($$$) {
my ( $r, $g, $b ) = @_;
@@ -3393,7 +3322,6 @@ sub PHTV_rgb2hsb ($$$) {
};
}
-###################################
sub PHTV_hsb2rgb ($$$) {
my ( $h, $s, $bri ) = @_;
@@ -3415,7 +3343,6 @@ sub PHTV_hsb2rgb ($$$) {
};
}
-###################################
sub PHTV_rgb2hsv($$$) {
my ( $r, $g, $b ) = @_;
my ( $M, $m, $c, $h, $s, $v );
@@ -3457,7 +3384,6 @@ sub PHTV_rgb2hsv($$$) {
};
}
-###################################
sub PHTV_hsv2rgb($$$) {
my ( $h, $s, $v ) = @_;
my $r = 0.0;
@@ -3518,7 +3444,6 @@ sub PHTV_hsv2rgb($$$) {
};
}
-###################################
sub PHTV_max {
my ( $max, @vars ) = @_;
for (@vars) {
@@ -3528,7 +3453,6 @@ sub PHTV_max {
return $max;
}
-###################################
sub PHTV_min {
my ( $min, @vars ) = @_;
for (@vars) {
@@ -3537,7 +3461,6 @@ sub PHTV_min {
return $min;
}
-###################################
sub PHTV_createDeviceId() {
my $deviceid;
my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9 );
@@ -3545,7 +3468,6 @@ sub PHTV_createDeviceId() {
return $deviceid;
}
-###################################
sub PHTV_createAuthSignature($$$) {
my ( $timestamp, $pin, $secretkey ) = @_;
my $base64 = 0;
diff --git a/fhem/FHEM/70_Pushover.pm b/fhem/FHEM/70_Pushover.pm
index 3cf9a36d0..c96e9b857 100644
--- a/fhem/FHEM/70_Pushover.pm
+++ b/fhem/FHEM/70_Pushover.pm
@@ -1,24 +1,22 @@
-# $Id$
###############################################################################
-#
-# Also see API documentation:
+# $Id$
# https://pushover.net/api
-
+#
package main;
use HttpUtils;
use utf8;
use Data::Dumper;
use HttpUtils;
-use SetExtensions;
use Encode;
-#------------------------------------------------------------------------------
+# initialize ##################################################################
sub Pushover_Initialize($$) {
my ($hash) = @_;
$hash->{DefFn} = "Pushover_Define";
$hash->{UndefFn} = "Pushover_Undefine";
$hash->{SetFn} = "Pushover_Set";
+
$hash->{AttrList} =
"disable:0,1 disabledForIntervals do_not_notify:0,1 timestamp:0,1 title sound:pushover,bike,bugle,cashregister,classical,cosmic,falling,gamelan,incoming,intermission,magic,mechanical,pianobar,siren,spacealarm,tugboat,alien,climb,persistent,echo,updown,none device priority:0,1,2,-1,-2 callbackUrl retry expire "
. $readingFnAttributes;
@@ -27,39 +25,7 @@ sub Pushover_Initialize($$) {
$hash->{'.msgParams'} = { parseParams => 1, };
}
-#------------------------------------------------------------------------------
-sub Pushover_addExtension($$$) {
- my ( $name, $func, $link ) = @_;
-
- my $url = "/$link";
-
- return 0
- if ( defined( $data{FWEXT}{$url} )
- && $data{FWEXT}{$url}{deviceName} ne $name );
-
- Log3 $name, 2,
- "Pushover $name: Registering Pushover for webhook URI $url ...";
- $data{FWEXT}{$url}{deviceName} = $name;
- $data{FWEXT}{$url}{FUNC} = $func;
- $data{FWEXT}{$url}{LINK} = $link;
- $name->{HASH}{FHEMWEB_URI} = $url;
-
- return 1;
-}
-
-#------------------------------------------------------------------------------
-sub Pushover_removeExtension($) {
- my ($link) = @_;
-
- my $url = "/$link";
- my $name = $data{FWEXT}{$url}{deviceName};
- Log3 $name, 2,
- "Pushover $name: Unregistering Pushover for webhook URI $url...";
- delete $data{FWEXT}{$url};
- delete $name->{HASH}{FHEMWEB_URI};
-}
-
-#------------------------------------------------------------------------------
+# regular Fn ##################################################################
sub Pushover_Define($$) {
my ( $hash, $def ) = @_;
@@ -67,8 +33,8 @@ sub Pushover_Define($$) {
my $name = shift @a;
my $type = shift @a;
- return
-"Invalid number of arguments: define Pushover []"
+ return "Invalid number of arguments: "
+ . "define Pushover []"
if ( int(@a) < 2 );
my ( $token, $user, $infix ) = @a;
@@ -107,9 +73,10 @@ sub Pushover_Define($$) {
else {
return "App or user/group token missing.";
}
+
+ return undef;
}
-#------------------------------------------------------------------------------
sub Pushover_Undefine($$) {
my ( $hash, $name ) = @_;
@@ -122,7 +89,6 @@ sub Pushover_Undefine($$) {
return undef;
}
-#------------------------------------------------------------------------------
sub Pushover_Set($@) {
my ( $hash, $name, $cmd, @args ) = @_;
my ( $a, $h ) = parseParams( join " ", @args );
@@ -169,9 +135,199 @@ sub Pushover_Set($@) {
return Pushover_SetMessage( $hash, @args )
if ( $cmd eq 'msg' );
+
+ return undef;
+}
+
+# module Fn ####################################################################
+sub Pushover_addExtension($$$) {
+ my ( $name, $func, $link ) = @_;
+
+ my $url = "/$link";
+
+ return 0
+ if ( defined( $data{FWEXT}{$url} )
+ && $data{FWEXT}{$url}{deviceName} ne $name );
+
+ Log3 $name, 2,
+ "Pushover $name: Registering Pushover for webhook URI $url ...";
+ $data{FWEXT}{$url}{deviceName} = $name;
+ $data{FWEXT}{$url}{FUNC} = $func;
+ $data{FWEXT}{$url}{LINK} = $link;
+ $name->{HASH}{FHEMWEB_URI} = $url;
+
+ return 1;
+}
+
+sub Pushover_removeExtension($) {
+ my ($link) = @_;
+
+ my $url = "/$link";
+ my $name = $data{FWEXT}{$url}{deviceName};
+ Log3 $name, 2,
+ "Pushover $name: Unregistering Pushover for webhook URI $url...";
+ delete $data{FWEXT}{$url};
+ delete $name->{HASH}{FHEMWEB_URI};
+}
+
+sub Pushover_CGI() {
+ my ($request) = @_;
+
+ my $hash;
+ my $name = "";
+ my $link = "";
+ my $URI = "";
+
+ # data received
+ if ( $request =~ m,^(/[^/]+?)(?:\&|\?)(.*)?$, ) {
+ $link = $1;
+ $URI = $2;
+
+ # get device name
+ $name = $data{FWEXT}{$link}{deviceName} if ( $data{FWEXT}{$link} );
+ $hash = $defs{$name};
+
+ # return error if no such device
+ return ( "text/plain; charset=utf-8",
+ "NOK No Pushover device for callback $link" )
+ unless ($name);
+
+ Log3 $name, 4, "Pushover $name callback: link='$link' URI='$URI'";
+
+ my $webArgs;
+ my $receipt = "";
+ my %revReadings;
+
+ # extract values from URI
+ foreach my $pv ( split( "&", $URI ) ) {
+ next if ( $pv eq "" );
+ $pv =~ s/\+/ /g;
+ $pv =~ s/%([\dA-F][\dA-F])/chr(hex($1))/ige;
+ my ( $p, $v ) = split( "=", $pv, 2 );
+
+ $webArgs->{$p} = $v;
+ }
+
+ if ( defined( $webArgs->{receipt} ) ) {
+ $receipt = $webArgs->{receipt};
+ }
+ elsif ( defined( $webArgs->{FhemCallbackId} ) ) {
+ $receipt = $webArgs->{FhemCallbackId};
+ }
+ else {
+ return ( "text/plain; charset=utf-8",
+ "NOK missing argument receipt or FhemCallbackId" );
+ }
+
+ # search for existing receipt
+ keys %{ $hash->{READINGS} };
+ while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) {
+ $revReadings{ $value->{VAL} } = $1
+ if ( defined( $value->{VAL} ) && $key =~ /^cb_(\d+)$/ );
+ }
+
+ if ( defined( $revReadings{$receipt} ) ) {
+ my $rAct = "cbAct_" . $revReadings{$receipt};
+ my $rAck = "cbAck_" . $revReadings{$receipt};
+ my $rAckAt = "cbAckAt_" . $revReadings{$receipt};
+ my $rAckBy = "cbAckBy_" . $revReadings{$receipt};
+ my $rCancelId = "cbCancelId_" . $revReadings{$receipt};
+ my $rDev = "cbDev_" . $revReadings{$receipt};
+
+ return ( "text/plain; charset=utf-8",
+ "NOK " . $receipt . ": invalid argument 'acknowledged'" )
+ if ( !defined( $webArgs->{acknowledged} )
+ || $webArgs->{acknowledged} ne "1" );
+
+ return ( "text/plain; charset=utf-8",
+ "NOK " . $receipt . ": invalid argument 'acknowledged_by'" )
+ if ( !defined( $webArgs->{acknowledged_by} )
+ || $webArgs->{acknowledged_by} ne $hash->{USER_KEY} );
+
+ if ( ReadingsVal( $name, $rAck, "1" ) eq "0"
+ && $revReadings{$receipt} > int( time() ) )
+ {
+ delete $hash->{READINGS}{$rCancelId}
+ if ( defined( $hash->{READINGS}{$rCancelId} ) );
+
+ readingsBeginUpdate($hash);
+
+ readingsBulkUpdate( $hash, $rAck, "1" );
+ readingsBulkUpdate( $hash, $rAckBy,
+ $webArgs->{acknowledged_by} );
+
+ if ( defined( $webArgs->{acknowledged_at} )
+ && $webArgs->{acknowledged_at} ne "" )
+ {
+ readingsBulkUpdate( $hash, $rAckAt,
+ $webArgs->{acknowledged_at} );
+ }
+ else {
+ readingsBulkUpdate( $hash, $rAckAt, int( time() ) );
+ }
+
+ my $redirect = "";
+
+ # run FHEM command if desired
+ if ( ReadingsVal( $name, $rAct, "pushover://" ) !~
+ /^[\w-]+:\/\/.*$/ )
+ {
+ $redirect = "pushover://";
+
+ fhem ReadingsVal( $name, $rAct, "" );
+ readingsBulkUpdate( $hash, $rAct,
+ "executed: " . ReadingsVal( $name, $rAct, "" ) );
+ }
+
+ # redirect to presented URL
+ if ( ReadingsVal( $name, $rAct, "none" ) =~ /^[\w-]+:\/\/.*$/ )
+ {
+ $redirect = ReadingsVal( $name, $rAct, "" );
+ }
+
+ readingsEndUpdate( $hash, 1 );
+
+ return (
+ "text/html; charset=utf-8",
+ "Click here to get redirected to your destination"
+ . ""
+ ) if ( $redirect ne "" );
+
+ }
+ else {
+ Log3 $name, 4,
+ "Pushover $name callback: " . $receipt . " has expired";
+ return (
+ "text/plain; charset=utf-8",
+ "NOK " . $receipt . " has expired"
+ );
+ }
+
+ }
+ else {
+ Log3 $name, 4,
+ "Pushover $name callback: unable to find existing receipt "
+ . $receipt;
+ return ( "text/plain; charset=utf-8",
+ "NOK unable to find existing receipt " . $receipt );
+ }
+
+ }
+
+ # no data received
+ else {
+ Log3 $name, 5,
+ "Pushover $name callback: received malformed request\n$request";
+ return ( "text/plain; charset=utf-8", "NOK malformed request" );
+ }
+
+ return ( "text/plain; charset=utf-8", "OK" );
}
-#------------------------------------------------------------------------------
sub Pushover_SendCommand($$;$\%) {
my ( $hash, $service, $cmd, $type ) = @_;
my $name = $hash->{NAME};
@@ -267,6 +423,10 @@ sub Pushover_SendCommand($$;$\%) {
Accept => 'application/json;charset=UTF-8',
'Accept-Charset' => 'UTF-8',
},
+
+ # sslargs => {
+ # SSL_verify_mode => 'SSL_verify_PEER',
+ # },
}
);
@@ -316,7 +476,6 @@ sub Pushover_SendCommand($$;$\%) {
return;
}
-#------------------------------------------------------------------------------
sub Pushover_ReceiveCommand($$$) {
my ( $param, $err, $data ) = @_;
my $hash = $param->{hash};
@@ -711,7 +870,6 @@ sub Pushover_ReceiveCommand($$$) {
return;
}
-#------------------------------------------------------------------------------
sub Pushover_ValidateUser ($;$) {
my ( $hash, $update ) = @_;
my $name = $hash->{NAME};
@@ -739,7 +897,6 @@ sub Pushover_ValidateUser ($;$) {
}
}
-#------------------------------------------------------------------------------
sub Pushover_SetMessage {
my $hash = shift;
my $name = $hash->{NAME};
@@ -843,7 +1000,6 @@ sub Pushover_SetMessage {
return Pushover_SetMessage2( $hash, "msg", undef, \%values );
}
-#------------------------------------------------------------------------------
sub Pushover_SetMessage2 ($$$$) {
my ( $hash, $cmd, $a, $h ) = @_;
my $name = $hash->{NAME};
@@ -1236,165 +1392,6 @@ sub Pushover_CancelMessage ($$$$) {
return $return;
}
-#------------------------------------------------------------------------------
-sub Pushover_CGI() {
- my ($request) = @_;
-
- my $hash;
- my $name = "";
- my $link = "";
- my $URI = "";
-
- # data received
- if ( $request =~ m,^(/[^/]+?)(?:\&|\?)(.*)?$, ) {
- $link = $1;
- $URI = $2;
-
- # get device name
- $name = $data{FWEXT}{$link}{deviceName} if ( $data{FWEXT}{$link} );
- $hash = $defs{$name};
-
- # return error if no such device
- return ( "text/plain; charset=utf-8",
- "NOK No Pushover device for callback $link" )
- unless ($name);
-
- Log3 $name, 4, "Pushover $name callback: link='$link' URI='$URI'";
-
- my $webArgs;
- my $receipt = "";
- my %revReadings;
-
- # extract values from URI
- foreach my $pv ( split( "&", $URI ) ) {
- next if ( $pv eq "" );
- $pv =~ s/\+/ /g;
- $pv =~ s/%([\dA-F][\dA-F])/chr(hex($1))/ige;
- my ( $p, $v ) = split( "=", $pv, 2 );
-
- $webArgs->{$p} = $v;
- }
-
- if ( defined( $webArgs->{receipt} ) ) {
- $receipt = $webArgs->{receipt};
- }
- elsif ( defined( $webArgs->{FhemCallbackId} ) ) {
- $receipt = $webArgs->{FhemCallbackId};
- }
- else {
- return ( "text/plain; charset=utf-8",
- "NOK missing argument receipt or FhemCallbackId" );
- }
-
- # search for existing receipt
- keys %{ $hash->{READINGS} };
- while ( my ( $key, $value ) = each %{ $hash->{READINGS} } ) {
- $revReadings{ $value->{VAL} } = $1
- if ( defined( $value->{VAL} ) && $key =~ /^cb_(\d+)$/ );
- }
-
- if ( defined( $revReadings{$receipt} ) ) {
- my $rAct = "cbAct_" . $revReadings{$receipt};
- my $rAck = "cbAck_" . $revReadings{$receipt};
- my $rAckAt = "cbAckAt_" . $revReadings{$receipt};
- my $rAckBy = "cbAckBy_" . $revReadings{$receipt};
- my $rCancelId = "cbCancelId_" . $revReadings{$receipt};
- my $rDev = "cbDev_" . $revReadings{$receipt};
-
- return ( "text/plain; charset=utf-8",
- "NOK " . $receipt . ": invalid argument 'acknowledged'" )
- if ( !defined( $webArgs->{acknowledged} )
- || $webArgs->{acknowledged} ne "1" );
-
- return ( "text/plain; charset=utf-8",
- "NOK " . $receipt . ": invalid argument 'acknowledged_by'" )
- if ( !defined( $webArgs->{acknowledged_by} )
- || $webArgs->{acknowledged_by} ne $hash->{USER_KEY} );
-
- if ( ReadingsVal( $name, $rAck, "1" ) eq "0"
- && $revReadings{$receipt} > int( time() ) )
- {
- delete $hash->{READINGS}{$rCancelId}
- if ( defined( $hash->{READINGS}{$rCancelId} ) );
-
- readingsBeginUpdate($hash);
-
- readingsBulkUpdate( $hash, $rAck, "1" );
- readingsBulkUpdate( $hash, $rAckBy,
- $webArgs->{acknowledged_by} );
-
- if ( defined( $webArgs->{acknowledged_at} )
- && $webArgs->{acknowledged_at} ne "" )
- {
- readingsBulkUpdate( $hash, $rAckAt,
- $webArgs->{acknowledged_at} );
- }
- else {
- readingsBulkUpdate( $hash, $rAckAt, int( time() ) );
- }
-
- my $redirect = "";
-
- # run FHEM command if desired
- if ( ReadingsVal( $name, $rAct, "pushover://" ) !~
- /^[\w-]+:\/\/.*$/ )
- {
- $redirect = "pushover://";
-
- fhem ReadingsVal( $name, $rAct, "" );
- readingsBulkUpdate( $hash, $rAct,
- "executed: " . ReadingsVal( $name, $rAct, "" ) );
- }
-
- # redirect to presented URL
- if ( ReadingsVal( $name, $rAct, "none" ) =~ /^[\w-]+:\/\/.*$/ )
- {
- $redirect = ReadingsVal( $name, $rAct, "" );
- }
-
- readingsEndUpdate( $hash, 1 );
-
- return (
- "text/html; charset=utf-8",
- "Click here to get redirected to your destination"
- . ""
- ) if ( $redirect ne "" );
-
- }
- else {
- Log3 $name, 4,
- "Pushover $name callback: " . $receipt . " has expired";
- return (
- "text/plain; charset=utf-8",
- "NOK " . $receipt . " has expired"
- );
- }
-
- }
- else {
- Log3 $name, 4,
- "Pushover $name callback: unable to find existing receipt "
- . $receipt;
- return ( "text/plain; charset=utf-8",
- "NOK unable to find existing receipt " . $receipt );
- }
-
- }
-
- # no data received
- else {
- Log3 $name, 5,
- "Pushover $name callback: received malformed request\n$request";
- return ( "text/plain; charset=utf-8", "NOK malformed request" );
- }
-
- return ( "text/plain; charset=utf-8", "OK" );
-}
-
1;
###############################################################################
diff --git a/fhem/FHEM/71_ONKYO_AVR_ZONE.pm b/fhem/FHEM/71_ONKYO_AVR_ZONE.pm
index afa3012f1..588d2c6e7 100644
--- a/fhem/FHEM/71_ONKYO_AVR_ZONE.pm
+++ b/fhem/FHEM/71_ONKYO_AVR_ZONE.pm
@@ -1,50 +1,13 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 70_ONKYO_AVR_ZONE.pm
-# An FHEM Perl module for controlling ONKYO A/V receivers
-# via network connection.
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
package main;
+
use strict;
use warnings;
-use Time::HiRes qw(usleep);
-use Symbol qw;
use Data::Dumper;
+use Symbol qw;
-$Data::Dumper::Sortkeys = 1;
-
-sub ONKYO_AVR_ZONE_Set($$$);
-sub ONKYO_AVR_ZONE_Get($$$);
-sub ONKYO_AVR_ZONE_Define($$$);
-sub ONKYO_AVR_ZONE_Undefine($$);
-
-#########################
-# Forward declaration for remotecontrol module
-sub ONKYO_AVR_ZONE_RClayout_TV();
-sub ONKYO_AVR_ZONE_RCmakenotify($$);
-
-###################################
+# initialize ##################################################################
sub ONKYO_AVR_ZONE_Initialize($) {
my ($hash) = @_;
@@ -52,22 +15,17 @@ sub ONKYO_AVR_ZONE_Initialize($) {
require "$attr{global}{modpath}/FHEM/ONKYOdb.pm";
- $hash->{Match} = ".+";
-
$hash->{DefFn} = "ONKYO_AVR_ZONE_Define";
$hash->{UndefFn} = "ONKYO_AVR_ZONE_Undefine";
-
- # $hash->{DeleteFn} = "ONKYO_AVR_ZONE_Delete";
- $hash->{SetFn} = "ONKYO_AVR_ZONE_Set";
- $hash->{GetFn} = "ONKYO_AVR_ZONE_Get";
-
- # $hash->{AttrFn} = "ONKYO_AVR_ZONE_Attr";
- # $hash->{NotifyFn} = "ONKYO_AVR_ZONE_Notify";
+ $hash->{SetFn} = "ONKYO_AVR_ZONE_Set";
+ $hash->{GetFn} = "ONKYO_AVR_ZONE_Get";
$hash->{ParseFn} = "ONKYO_AVR_ZONE_Parse";
+ $hash->{Match} = ".+";
+
$hash->{AttrList} =
- "IODev do_not_notify:1,0 "
- . "volumeSteps:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 inputs disable:0,1 model wakeupCmd:textField "
+ "IODev disable:0,1 disabledForIntervals do_not_notify:1,0 "
+ . "volumeSteps:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 inputs model wakeupCmd:textField "
. $readingFnAttributes;
# $data{RC_layout}{ONKYO_AVR_ZONE_SVG} = "ONKYO_AVR_ZONE_RClayout_SVG";
@@ -90,7 +48,7 @@ sub ONKYO_AVR_ZONE_Initialize($) {
$hash->{parseParams} = 1;
}
-###################################
+# regular Fn ##################################################################
sub ONKYO_AVR_ZONE_Define($$$) {
my ( $hash, $a, $h ) = @_;
my $name = $hash->{NAME};
@@ -125,8 +83,8 @@ sub ONKYO_AVR_ZONE_Define($$$) {
. $modules{ONKYO_AVR_ZONE}{defptr}{$IOname}{$zone}{NAME};
}
elsif ( !defined($IOhash) ) {
- return
-"No matching I/O device found, please define a ONKYO_AVR device first";
+ return "No matching I/O device found, "
+ . "please define a ONKYO_AVR device first";
}
elsif ( !defined( $IOhash->{TYPE} ) || !defined( $IOhash->{NAME} ) ) {
return "IODev does not seem to be existing";
@@ -182,10 +140,9 @@ sub ONKYO_AVR_ZONE_Define($$$) {
ONKYO_AVR_ZONE_SendCommand( $hash, "mute", "query" );
ONKYO_AVR_ZONE_SendCommand( $hash, "volume", "query" );
- return;
+ return undef;
}
-###################################
sub ONKYO_AVR_ZONE_Undefine($$) {
my ( $hash, $name ) = @_;
my $zone = $hash->{ZONE};
@@ -207,300 +164,6 @@ sub ONKYO_AVR_ZONE_Undefine($$) {
return undef;
}
-#############################
-sub ONKYO_AVR_ZONE_Parse($$) {
- my ( $IOhash, $msg ) = @_;
- my @matches;
- my $IOname = $IOhash->{NAME};
- my $zone = $msg->{zone} || "";
-
- delete $msg->{zone} if ( defined( $msg->{zone} ) );
-
- Log3 $IOname, 5,
- "ONKYO_AVR $IOname: called function ONKYO_AVR_ZONE_Parse()";
-
- foreach my $d ( keys %defs ) {
- my $hash = $defs{$d};
- my $name = $hash->{NAME};
- my $state = ReadingsVal( $name, "power", "off" );
-
- if ( $hash->{TYPE} eq "ONKYO_AVR_ZONE"
- && $hash->{IODev} eq $IOhash
- && ( $zone eq "" || $hash->{ZONE} eq $zone ) )
- {
- push @matches, $d;
-
- # Update readings
- readingsBeginUpdate($hash);
-
- foreach my $cmd ( keys %{$msg} ) {
- my $value = $msg->{$cmd};
-
- $hash->{INPUT} = $value and next if ( $cmd eq "INPUT_RAW" );
- $hash->{CHANNEL} = $value and next if ( $cmd eq "CHANNEL_RAW" );
-
- Log3 $name, 4, "ONKYO_AVR_ZONE $name: rcv $cmd = $value";
-
- # presence
- if ( $cmd eq "presence" && $value eq "present" ) {
- ONKYO_AVR_ZONE_SendCommand( $hash, "power", "query" );
- ONKYO_AVR_ZONE_SendCommand( $hash, "input", "query" );
- ONKYO_AVR_ZONE_SendCommand( $hash, "mute", "query" );
- ONKYO_AVR_ZONE_SendCommand( $hash, "volume", "query" );
- }
-
- # input
- elsif ( $cmd eq "input" ) {
-
- # Input alias handling
- if (
- defined(
- $hash->{helper}{receiver}{input_aliases}{$value}
- )
- )
- {
- Log3 $name, 4,
- "ONKYO_AVR_AVR $name: Input aliasing '$value' to '"
- . $hash->{helper}{receiver}{input_aliases}{$value}
- . "'";
- $value =
- $hash->{helper}{receiver}{input_aliases}{$value};
- }
-
- }
-
- # power
- elsif ( $cmd eq "power" ) {
- readingsBulkUpdate( $hash, "presence", "present" )
- if ( ReadingsVal( $name, "presence", "-" ) ne "present" );
- }
-
- # balance
- elsif ( $cmd eq "balance" ) {
- my $prefix = "";
- $prefix = "-" if ( $value =~ /^\-.*/ );
- $value = substr( $value, 1 ) if ( $value =~ /^[\+|\-].*/ );
-
- $value = $prefix . ONKYO_AVR_hex2dec($value);
- }
-
- # preset
- elsif ( $cmd eq "preset" ) {
-
- if ( defined( $IOhash->{helper}{receiver}{preset} ) ) {
-
- foreach my $id (
- sort keys %{ $IOhash->{helper}{receiver}{preset} } )
- {
- my $presetName =
- $IOhash->{helper}{receiver}{preset}{$id};
- next if ( !$presetName || $presetName eq "" );
-
- $presetName =~ s/\s/_/g;
-
- if ( $id eq ONKYO_AVR_dec2hex($value) ) {
- $value = $presetName;
- last;
- }
- }
- }
-
- $value = "" if ( $value eq "0" );
- }
-
- # tone
- if ( $cmd =~ /^tone/ ) {
- if ( $value =~ /^B(..)T(..)$/ ) {
- my $bass = $1;
- my $treble = $2;
- my $bassName = $cmd . "-bass";
- my $trebleName = $cmd . "-treble";
- my $prefixBass = "";
- my $prefixTreble = "";
-
- # tone-bass
- $prefixBass = "-" if ( $bass =~ /^\-.*/ );
- $bass = substr( $bass, 1 ) if ( $bass =~ /^[\+|\-].*/ );
- $bass = $prefixBass . ONKYO_AVR_hex2dec($bass);
- readingsBulkUpdate( $hash, $bassName, $bass )
- if ( ReadingsVal( $name, $bassName, "-" ) ne $bass );
-
- # tone-treble
- $prefixTreble = "-" if ( $treble =~ /^\-.*/ );
- $treble = substr( $treble, 1 )
- if ( $treble =~ /^[\+|\-].*/ );
- $treble = $prefixTreble . ONKYO_AVR_hex2dec($treble);
- readingsBulkUpdate( $hash, $trebleName, $treble )
- if (
- ReadingsVal( $name, $trebleName, "-" ) ne $treble );
- }
- }
-
- # all other commands
- else {
- readingsBulkUpdate( $hash, $cmd, $value )
- if ( ReadingsVal( $name, $cmd, "-" ) ne $value
- || $cmd =~ /^currentAlbumArt.*/ );
- }
- }
-
- # stateAV
- my $stateAV = ONKYO_AVR_ZONE_GetStateAV($hash);
- readingsBulkUpdate( $hash, "stateAV", $stateAV )
- if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
-
- readingsEndUpdate( $hash, 1 );
- last;
- }
- }
- return @matches if (@matches);
- return "UNDEFINED ONKYO_AVR_ZONE";
-}
-
-###################################
-sub ONKYO_AVR_ZONE_Get($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
- my $zone = $hash->{ZONE};
- my $IOhash = $hash->{IODev};
- my $IOname = $IOhash->{NAME};
- my $state = ReadingsVal( $name, "power", "off" );
- my $presence = ReadingsVal( $name, "presence", "absent" );
- my $commands = ONKYOdb::ONKYO_GetRemotecontrolCommand($zone);
- my $commands_details = ONKYOdb::ONKYO_GetRemotecontrolCommandDetails($zone);
- my $return;
-
- Log3 $name, 5, "ONKYO_AVR_ZONE $name: called function ONKYO_AVR_ZONE_Get()";
-
- return "Argument is missing" if ( int(@$a) < 1 );
-
- # readings
- return $hash->{READINGS}{ @$a[1] }{VAL}
- if ( defined( $hash->{READINGS}{ @$a[1] } ) );
-
- return "Device is offline and cannot be controlled at that stage."
- if ( $presence eq "absent" );
-
- # statusRequest
- if ( lc( @$a[1] ) eq "statusrequest" ) {
- Log3 $name, 3, "ONKYO_AVR_ZONE get $name " . @$a[1];
-
- ONKYO_AVR_ZONE_SendCommand( $hash, "power", "query" );
- ONKYO_AVR_ZONE_SendCommand( $hash, "input", "query" );
- ONKYO_AVR_ZONE_SendCommand( $hash, "mute", "query" );
- ONKYO_AVR_ZONE_SendCommand( $hash, "volume", "query" );
- }
-
- # remoteControl
- elsif ( lc( @$a[1] ) eq "remotecontrol" ) {
-
- # Output help for commands
- if ( !defined( @$a[2] ) || @$a[2] eq "help" || @$a[2] eq "?" ) {
-
- my $valid_commands =
- "Usage: \n\nValid commands in zone$zone:\n\n\n"
- . "COMMAND\t\t\tDESCRIPTION\n\n";
-
- # For each valid command
- foreach my $command ( sort keys %{$commands} ) {
- my $command_raw = $commands->{$command};
-
- # add command including description if found
- if ( defined( $commands_details->{$command_raw}{description} ) )
- {
- $valid_commands .=
- $command
- . "\t\t\t"
- . $commands_details->{$command_raw}{description} . "\n";
- }
-
- # add command only
- else {
- $valid_commands .= $command . "\n";
- }
- }
-
- $valid_commands .=
-"\nTry '<command> help' to find out well known values.\n\n\n";
-
- $return = $valid_commands;
- }
- else {
- # Reading values for command from HASH table
- my $values =
- ONKYOdb::ONKYO_GetRemotecontrolValue( $zone,
- $commands->{ @$a[2] } );
-
- @$a[3] = "query"
- if ( !defined( @$a[3] ) && defined( $values->{query} ) );
-
- # Output help for values
- if ( !defined( @$a[3] ) || @$a[3] eq "help" || @$a[3] eq "?" ) {
-
- # Get all details for command
- my $command_details =
- ONKYOdb::ONKYO_GetRemotecontrolCommandDetails( $zone,
- $commands->{ @$a[2] } );
-
- my $valid_values =
- "Usage: "
- . @$a[2]
- . " \n\nWell known values:\n\n\n"
- . "VALUE\t\t\tDESCRIPTION\n\n";
-
- # For each valid value
- foreach my $value ( sort keys %{$values} ) {
-
- # add value including description if found
- if ( defined( $command_details->{description} ) ) {
- $valid_values .=
- $value
- . "\t\t\t"
- . $command_details->{description} . "\n";
- }
-
- # add value only
- else {
- $valid_values .= $value . "\n";
- }
- }
-
- $valid_values .= "\n\n\n";
-
- $return = $valid_values;
- }
-
- # normal processing
- else {
- Log3 $name, 3,
- "ONKYO_AVR_ZONE get $name "
- . @$a[1] . " "
- . @$a[2] . " "
- . @$a[3]
- if ( !@$a[4] || @$a[4] ne "quiet" );
-
- ONKYO_AVR_ZONE_SendCommand( $hash, @$a[2], @$a[3] );
- $return = "Sent command: " . @$a[2] . " " . @$a[3]
- if ( !@$a[4] || @$a[4] ne "quiet" );
- }
- }
- }
-
- else {
- $return =
- "Unknown argument " . @$a[1] . ", choose one of statusRequest:noArg";
-
- # remoteControl
- $return .= " remoteControl:";
- foreach my $command ( sort keys %{$commands} ) {
- $return .= "," . $command;
- }
- }
-
- return $return if ($return);
-}
-
-###################################
sub ONKYO_AVR_ZONE_Set($$$) {
my ( $hash, $a, $h ) = @_;
my $IOhash = $hash->{IODev};
@@ -1443,13 +1106,298 @@ sub ONKYO_AVR_ZONE_Set($$$) {
return $return;
}
-############################################################################################################
-#
-# Begin of helper functions
-#
-############################################################################################################
+sub ONKYO_AVR_ZONE_Get($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+ my $zone = $hash->{ZONE};
+ my $IOhash = $hash->{IODev};
+ my $IOname = $IOhash->{NAME};
+ my $state = ReadingsVal( $name, "power", "off" );
+ my $presence = ReadingsVal( $name, "presence", "absent" );
+ my $commands = ONKYOdb::ONKYO_GetRemotecontrolCommand($zone);
+ my $commands_details = ONKYOdb::ONKYO_GetRemotecontrolCommandDetails($zone);
+ my $return;
-###################################
+ Log3 $name, 5, "ONKYO_AVR_ZONE $name: called function ONKYO_AVR_ZONE_Get()";
+
+ return "Argument is missing" if ( int(@$a) < 1 );
+
+ # readings
+ return $hash->{READINGS}{ @$a[1] }{VAL}
+ if ( defined( $hash->{READINGS}{ @$a[1] } ) );
+
+ return "Device is offline and cannot be controlled at that stage."
+ if ( $presence eq "absent" );
+
+ # statusRequest
+ if ( lc( @$a[1] ) eq "statusrequest" ) {
+ Log3 $name, 3, "ONKYO_AVR_ZONE get $name " . @$a[1];
+
+ ONKYO_AVR_ZONE_SendCommand( $hash, "power", "query" );
+ ONKYO_AVR_ZONE_SendCommand( $hash, "input", "query" );
+ ONKYO_AVR_ZONE_SendCommand( $hash, "mute", "query" );
+ ONKYO_AVR_ZONE_SendCommand( $hash, "volume", "query" );
+ }
+
+ # remoteControl
+ elsif ( lc( @$a[1] ) eq "remotecontrol" ) {
+
+ # Output help for commands
+ if ( !defined( @$a[2] ) || @$a[2] eq "help" || @$a[2] eq "?" ) {
+
+ my $valid_commands =
+ "Usage: \n\nValid commands in zone$zone:\n\n\n"
+ . "COMMAND\t\t\tDESCRIPTION\n\n";
+
+ # For each valid command
+ foreach my $command ( sort keys %{$commands} ) {
+ my $command_raw = $commands->{$command};
+
+ # add command including description if found
+ if ( defined( $commands_details->{$command_raw}{description} ) )
+ {
+ $valid_commands .=
+ $command
+ . "\t\t\t"
+ . $commands_details->{$command_raw}{description} . "\n";
+ }
+
+ # add command only
+ else {
+ $valid_commands .= $command . "\n";
+ }
+ }
+
+ $valid_commands .=
+"\nTry '<command> help' to find out well known values.\n\n\n";
+
+ $return = $valid_commands;
+ }
+ else {
+ # Reading values for command from HASH table
+ my $values =
+ ONKYOdb::ONKYO_GetRemotecontrolValue( $zone,
+ $commands->{ @$a[2] } );
+
+ @$a[3] = "query"
+ if ( !defined( @$a[3] ) && defined( $values->{query} ) );
+
+ # Output help for values
+ if ( !defined( @$a[3] ) || @$a[3] eq "help" || @$a[3] eq "?" ) {
+
+ # Get all details for command
+ my $command_details =
+ ONKYOdb::ONKYO_GetRemotecontrolCommandDetails( $zone,
+ $commands->{ @$a[2] } );
+
+ my $valid_values =
+ "Usage: "
+ . @$a[2]
+ . " \n\nWell known values:\n\n\n"
+ . "VALUE\t\t\tDESCRIPTION\n\n";
+
+ # For each valid value
+ foreach my $value ( sort keys %{$values} ) {
+
+ # add value including description if found
+ if ( defined( $command_details->{description} ) ) {
+ $valid_values .=
+ $value
+ . "\t\t\t"
+ . $command_details->{description} . "\n";
+ }
+
+ # add value only
+ else {
+ $valid_values .= $value . "\n";
+ }
+ }
+
+ $valid_values .= "\n\n\n";
+
+ $return = $valid_values;
+ }
+
+ # normal processing
+ else {
+ Log3 $name, 3,
+ "ONKYO_AVR_ZONE get $name "
+ . @$a[1] . " "
+ . @$a[2] . " "
+ . @$a[3]
+ if ( !@$a[4] || @$a[4] ne "quiet" );
+
+ ONKYO_AVR_ZONE_SendCommand( $hash, @$a[2], @$a[3] );
+ $return = "Sent command: " . @$a[2] . " " . @$a[3]
+ if ( !@$a[4] || @$a[4] ne "quiet" );
+ }
+ }
+ }
+
+ else {
+ $return =
+ "Unknown argument " . @$a[1] . ", choose one of statusRequest:noArg";
+
+ # remoteControl
+ $return .= " remoteControl:";
+ foreach my $command ( sort keys %{$commands} ) {
+ $return .= "," . $command;
+ }
+ }
+
+ return $return;
+}
+
+sub ONKYO_AVR_ZONE_Parse($$) {
+ my ( $IOhash, $msg ) = @_;
+ my @matches;
+ my $IOname = $IOhash->{NAME};
+ my $zone = $msg->{zone} || "";
+
+ delete $msg->{zone} if ( defined( $msg->{zone} ) );
+
+ Log3 $IOname, 5,
+ "ONKYO_AVR $IOname: called function ONKYO_AVR_ZONE_Parse()";
+
+ foreach my $d ( keys %defs ) {
+ my $hash = $defs{$d};
+ my $name = $hash->{NAME};
+ my $state = ReadingsVal( $name, "power", "off" );
+
+ if ( $hash->{TYPE} eq "ONKYO_AVR_ZONE"
+ && $hash->{IODev} eq $IOhash
+ && ( $zone eq "" || $hash->{ZONE} eq $zone ) )
+ {
+ push @matches, $d;
+
+ # Update readings
+ readingsBeginUpdate($hash);
+
+ foreach my $cmd ( keys %{$msg} ) {
+ my $value = $msg->{$cmd};
+
+ $hash->{INPUT} = $value and next if ( $cmd eq "INPUT_RAW" );
+ $hash->{CHANNEL} = $value and next if ( $cmd eq "CHANNEL_RAW" );
+
+ Log3 $name, 4, "ONKYO_AVR_ZONE $name: rcv $cmd = $value";
+
+ # presence
+ if ( $cmd eq "presence" && $value eq "present" ) {
+ ONKYO_AVR_ZONE_SendCommand( $hash, "power", "query" );
+ ONKYO_AVR_ZONE_SendCommand( $hash, "input", "query" );
+ ONKYO_AVR_ZONE_SendCommand( $hash, "mute", "query" );
+ ONKYO_AVR_ZONE_SendCommand( $hash, "volume", "query" );
+ }
+
+ # input
+ elsif ( $cmd eq "input" ) {
+
+ # Input alias handling
+ if (
+ defined(
+ $hash->{helper}{receiver}{input_aliases}{$value}
+ )
+ )
+ {
+ Log3 $name, 4,
+ "ONKYO_AVR_AVR $name: Input aliasing '$value' to '"
+ . $hash->{helper}{receiver}{input_aliases}{$value}
+ . "'";
+ $value =
+ $hash->{helper}{receiver}{input_aliases}{$value};
+ }
+
+ }
+
+ # power
+ elsif ( $cmd eq "power" ) {
+ readingsBulkUpdate( $hash, "presence", "present" )
+ if ( ReadingsVal( $name, "presence", "-" ) ne "present" );
+ }
+
+ # balance
+ elsif ( $cmd eq "balance" ) {
+ my $prefix = "";
+ $prefix = "-" if ( $value =~ /^\-.*/ );
+ $value = substr( $value, 1 ) if ( $value =~ /^[\+|\-].*/ );
+
+ $value = $prefix . ONKYO_AVR_hex2dec($value);
+ }
+
+ # preset
+ elsif ( $cmd eq "preset" ) {
+
+ if ( defined( $IOhash->{helper}{receiver}{preset} ) ) {
+
+ foreach my $id (
+ sort keys %{ $IOhash->{helper}{receiver}{preset} } )
+ {
+ my $presetName =
+ $IOhash->{helper}{receiver}{preset}{$id};
+ next if ( !$presetName || $presetName eq "" );
+
+ $presetName =~ s/\s/_/g;
+
+ if ( $id eq ONKYO_AVR_dec2hex($value) ) {
+ $value = $presetName;
+ last;
+ }
+ }
+ }
+
+ $value = "" if ( $value eq "0" );
+ }
+
+ # tone
+ if ( $cmd =~ /^tone/ ) {
+ if ( $value =~ /^B(..)T(..)$/ ) {
+ my $bass = $1;
+ my $treble = $2;
+ my $bassName = $cmd . "-bass";
+ my $trebleName = $cmd . "-treble";
+ my $prefixBass = "";
+ my $prefixTreble = "";
+
+ # tone-bass
+ $prefixBass = "-" if ( $bass =~ /^\-.*/ );
+ $bass = substr( $bass, 1 ) if ( $bass =~ /^[\+|\-].*/ );
+ $bass = $prefixBass . ONKYO_AVR_hex2dec($bass);
+ readingsBulkUpdate( $hash, $bassName, $bass )
+ if ( ReadingsVal( $name, $bassName, "-" ) ne $bass );
+
+ # tone-treble
+ $prefixTreble = "-" if ( $treble =~ /^\-.*/ );
+ $treble = substr( $treble, 1 )
+ if ( $treble =~ /^[\+|\-].*/ );
+ $treble = $prefixTreble . ONKYO_AVR_hex2dec($treble);
+ readingsBulkUpdate( $hash, $trebleName, $treble )
+ if (
+ ReadingsVal( $name, $trebleName, "-" ) ne $treble );
+ }
+ }
+
+ # all other commands
+ else {
+ readingsBulkUpdate( $hash, $cmd, $value )
+ if ( ReadingsVal( $name, $cmd, "-" ) ne $value
+ || $cmd =~ /^currentAlbumArt.*/ );
+ }
+ }
+
+ # stateAV
+ my $stateAV = ONKYO_AVR_ZONE_GetStateAV($hash);
+ readingsBulkUpdate( $hash, "stateAV", $stateAV )
+ if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV );
+
+ readingsEndUpdate( $hash, 1 );
+ last;
+ }
+ }
+ return @matches if (@matches);
+ return "UNDEFINED ONKYO_AVR_ZONE";
+}
+
+# module Fn ####################################################################
sub ONKYO_AVR_ZONE_SendCommand($$$) {
my ( $hash, $cmd, $value ) = @_;
my $IOhash = $hash->{IODev};
@@ -1523,7 +1471,6 @@ sub ONKYO_AVR_ZONE_SendCommand($$$) {
return;
}
-###################################
sub ONKYO_AVR_ZONE_GetStateAV($) {
my ($hash) = @_;
my $name = $hash->{NAME};
diff --git a/fhem/FHEM/74_THINKINGCLEANER.pm b/fhem/FHEM/74_THINKINGCLEANER.pm
index a67c16cf4..0fe8707f5 100644
--- a/fhem/FHEM/74_THINKINGCLEANER.pm
+++ b/fhem/FHEM/74_THINKINGCLEANER.pm
@@ -1,30 +1,5 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 74_THINKINGCLEANER.pm
-# An FHEM Perl module for controlling ThinkingCleaner connected
-# Roomba vacuum cleaning robot.
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
package main;
use strict;
@@ -34,15 +9,7 @@ use HttpUtils;
use Encode;
use Data::Dumper;
-no warnings "all";
-
-sub THINKINGCLEANER_Set($@);
-sub THINKINGCLEANER_GetStatus($;$);
-sub THINKINGCLEANER_Attr($@);
-sub THINKINGCLEANER_Define($$);
-sub THINKINGCLEANER_Undefine($$);
-
-###################################
+# initialize ##################################################################
sub THINKINGCLEANER_Initialize($) {
my ($hash) = @_;
@@ -51,14 +18,14 @@ sub THINKINGCLEANER_Initialize($) {
my $webhookFWinstance =
join( ",", devspec2array('TYPE=FHEMWEB:FILTER=TEMPORARY!=1') );
- $hash->{SetFn} = "THINKINGCLEANER_Set";
$hash->{DefFn} = "THINKINGCLEANER_Define";
- $hash->{AttrFn} = "THINKINGCLEANER_Attr";
$hash->{UndefFn} = "THINKINGCLEANER_Undefine";
+ $hash->{SetFn} = "THINKINGCLEANER_Set";
+ $hash->{AttrFn} = "THINKINGCLEANER_Attr";
$hash->{parseParams} = 1;
$hash->{AttrList} =
-"disable:0,1 timeout:1,2,3,4,5 pollInterval:30,45,60,75,90 pollMultiplierWebhook pollMultiplierCleaning model webhookHttpHostname webhookPort webhookFWinstance:$webhookFWinstance restart:noArg "
+"disable:0,1 disabledForIntervals timeout:1,2,3,4,5 pollInterval:30,45,60,75,90 pollMultiplierWebhook pollMultiplierCleaning model webhookHttpHostname webhookPort webhookFWinstance:$webhookFWinstance restart:noArg "
. $readingFnAttributes;
# 98_powerMap.pm support
@@ -89,50 +56,82 @@ sub THINKINGCLEANER_Initialize($) {
},
},
};
-
- return;
}
-#####################################
-sub THINKINGCLEANER_GetStatus($;$) {
- my ( $hash, $delay ) = @_;
- my $name = $hash->{NAME};
- $hash->{INTERVAL_MULTIPLIER} = (
- ReadingsVal( $name, "state", "off" ) ne "off"
- && ReadingsVal( $name, "state", "absent" ) ne "absent"
- && ReadingsVal( $name, "state", "standby" ) ne "standby"
- ? AttrVal( $name, "pollMultiplierCleaning", "0.5" )
- : (
- $hash->{WEBHOOK_REGISTER} eq "success"
- ? AttrVal( $name, "pollMultiplierWebhook", "2" )
- : "1"
- )
- );
-
- $hash->{INTERVAL} =
- AttrVal( $name, "pollInterval", "45" ) * $hash->{INTERVAL_MULTIPLIER};
- my $interval = (
- $delay
- ? $delay
- : $hash->{INTERVAL}
- );
+# regular Fn ##################################################################
+sub THINKINGCLEANER_Define($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+ my $infix = "THINKINGCLEANER";
Log3 $name, 5,
- "THINKINGCLEANER $name: called function THINKINGCLEANER_GetStatus()";
+ "THINKINGCLEANER $name: called function THINKINGCLEANER_Define()";
- RemoveInternalTimer($hash);
- InternalTimer( gettimeofday() + $interval,
- "THINKINGCLEANER_GetStatus", $hash, 0 );
+ eval {
+ require JSON;
+ import JSON qw( decode_json );
+ };
+ return "Please install Perl JSON to use module THINKINGCLEANER"
+ if ($@);
- return
- if ( $delay || AttrVal( $name, "disable", 0 ) == 1 );
+ if ( int(@$a) < 2 ) {
+ my $msg =
+ "Wrong syntax: define THINKINGCLEANER ";
+ Log3 $name, 4, $msg;
+ return $msg;
+ }
- THINKINGCLEANER_SendCommand( $hash, "full_status.json" );
+ $hash->{TYPE} = "THINKINGCLEANER";
- return;
+ my $address = @$a[2];
+ $hash->{DeviceName} = $address;
+
+ # set reverse pointer
+ $modules{THINKINGCLEANER}{defptr}{$name} = \$hash;
+
+ # set default settings on first define
+ if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
+ $attr{$name}{cmdIcon} =
+'on-max:text_max on-spot:refresh on-delayed:time_timer dock:measure_battery_50 locate:rc_SEARCH';
+ $attr{$name}{devStateIcon} =
+'on-delayed:rc_STOP@green:off on-max:rc_BLUE@green:off on-spot:rc_GREEN@red:off on.*:rc_GREEN@green:off dock:rc_GREEN@orange:off off:rc_STOP:on standby|remote:rc_YELLOW:on locate:rc_YELLOW .*:rc_RED';
+ $attr{$name}{icon} = 'scene_cleaning';
+ $attr{$name}{webCmd} = 'on-max:on-spot:on-delayed:dock:locate';
+ }
+
+ if ( THINKINGCLEANER_addExtension( $name, "THINKINGCLEANER_CGI", $infix ) )
+ {
+ $hash->{fhem}{infix} = $infix;
+ }
+
+ $hash->{WEBHOOK_REGISTER} = "unregistered";
+
+ # start the status update timer
+ THINKINGCLEANER_GetStatus( $hash, 2 );
+
+ return undef;
+}
+
+sub THINKINGCLEANER_Undefine($$$) {
+ my ( $hash, $a, $h ) = @_;
+ my $name = $hash->{NAME};
+
+ if ( defined( $hash->{fhem}{infix} ) ) {
+ THINKINGCLEANER_removeExtension( $hash->{fhem}{infix} );
+ }
+
+ Log3 $name, 5,
+ "THINKINGCLEANER $name: called function THINKINGCLEANER_Undefine()";
+
+ # Stop the internal GetStatus-Loop and exit
+ RemoveInternalTimer($hash);
+
+ # release reverse pointer
+ delete $modules{THINKINGCLEANER}{defptr}{$name};
+
+ return undef;
}
-###################################
sub THINKINGCLEANER_Set($$$) {
my ( $hash, $a, $h ) = @_;
my $name = $hash->{NAME};
@@ -842,64 +841,9 @@ sub THINKINGCLEANER_Set($$$) {
return $usage;
}
- return;
+ return undef;
}
-###################################
-sub THINKINGCLEANER_Define($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
- my $infix = "THINKINGCLEANER";
-
- Log3 $name, 5,
- "THINKINGCLEANER $name: called function THINKINGCLEANER_Define()";
-
- eval {
- require JSON;
- import JSON qw( decode_json );
- };
- return "Please install Perl JSON to use module THINKINGCLEANER"
- if ($@);
-
- if ( int(@$a) < 2 ) {
- my $msg =
- "Wrong syntax: define THINKINGCLEANER ";
- Log3 $name, 4, $msg;
- return $msg;
- }
-
- $hash->{TYPE} = "THINKINGCLEANER";
-
- my $address = @$a[2];
- $hash->{DeviceName} = $address;
-
- # set reverse pointer
- $modules{THINKINGCLEANER}{defptr}{$name} = \$hash;
-
- # set default settings on first define
- if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
- $attr{$name}{cmdIcon} =
-'on-max:text_max on-spot:refresh on-delayed:time_timer dock:measure_battery_50 locate:rc_SEARCH';
- $attr{$name}{devStateIcon} =
-'on-delayed:rc_STOP@green:off on-max:rc_BLUE@green:off on-spot:rc_GREEN@red:off on.*:rc_GREEN@green:off dock:rc_GREEN@orange:off off:rc_STOP:on standby|remote:rc_YELLOW:on locate:rc_YELLOW .*:rc_RED';
- $attr{$name}{icon} = 'scene_cleaning';
- $attr{$name}{webCmd} = 'on-max:on-spot:on-delayed:dock:locate';
- }
-
- if ( THINKINGCLEANER_addExtension( $name, "THINKINGCLEANER_CGI", $infix ) )
- {
- $hash->{fhem}{infix} = $infix;
- }
-
- $hash->{WEBHOOK_REGISTER} = "unregistered";
-
- # start the status update timer
- THINKINGCLEANER_GetStatus( $hash, 2 );
-
- return;
-}
-
-###################################
sub THINKINGCLEANER_Attr(@) {
my ( $cmd, $name, $attrName, $attrVal ) = @_;
my $hash = $defs{$name};
@@ -1004,7 +948,7 @@ sub THINKINGCLEANER_Attr(@) {
return undef;
}
-###################################
+# module Fn ####################################################################
sub THINKINGCLEANER_addExtension($$$) {
my ( $name, $func, $link ) = @_;
@@ -1023,7 +967,6 @@ sub THINKINGCLEANER_addExtension($$$) {
return 1;
}
-###################################
sub THINKINGCLEANER_removeExtension($) {
my ($link) = @_;
@@ -1034,13 +977,88 @@ sub THINKINGCLEANER_removeExtension($) {
delete $data{FWEXT}{$url};
}
-############################################################################################################
-#
-# Begin of helper functions
-#
-############################################################################################################
+sub THINKINGCLEANER_CGI() {
+ my ($request) = @_;
+
+ # data received
+ if ( defined( $FW_httpheader{UUID} ) ) {
+ if ( defined( $modules{THINKINGCLEANER}{defptr} ) ) {
+ while ( my ( $key, $value ) =
+ each %{ $modules{THINKINGCLEANER}{defptr} } )
+ {
+
+ my $uuid = ReadingsVal( $key, "uuid", undef );
+ next if ( !$uuid || $uuid ne $FW_httpheader{UUID} );
+
+ $defs{$key}{WEBHOOK_COUNTER}++;
+ $defs{$key}{WEBHOOK_LAST} = TimeNow();
+
+ Log3 $key, 4,
+"THINKINGCLEANER $key: Received webhook for matching UUID at device $key";
+
+ my $delay = undef;
+
+# we need some delay as to the Robo seems to send webhooks but it's status does
+# not really reflect the change we'd expect to get here already so give 'em some
+# more time to think about it...
+ $delay = "2"
+ if ( defined( $defs{$key}{LAST_COMMAND} )
+ && time() - time_str2num( $defs{$key}{LAST_COMMAND} ) < 3 );
+
+ THINKINGCLEANER_GetStatus( $defs{$key}, $delay );
+ last;
+ }
+ }
+
+ return ( undef, undef );
+ }
+
+ # no data received
+ else {
+ Log3 undef, 5, "THINKINGCLEANER: received malformed request\n$request";
+ }
+
+ return ( "text/plain; charset=utf-8", "Call failure: " . $request );
+}
+
+sub THINKINGCLEANER_GetStatus($;$) {
+ my ( $hash, $delay ) = @_;
+ my $name = $hash->{NAME};
+ $hash->{INTERVAL_MULTIPLIER} = (
+ ReadingsVal( $name, "state", "off" ) ne "off"
+ && ReadingsVal( $name, "state", "absent" ) ne "absent"
+ && ReadingsVal( $name, "state", "standby" ) ne "standby"
+ ? AttrVal( $name, "pollMultiplierCleaning", "0.5" )
+ : (
+ $hash->{WEBHOOK_REGISTER} eq "success"
+ ? AttrVal( $name, "pollMultiplierWebhook", "2" )
+ : "1"
+ )
+ );
+
+ $hash->{INTERVAL} =
+ AttrVal( $name, "pollInterval", "45" ) * $hash->{INTERVAL_MULTIPLIER};
+ my $interval = (
+ $delay
+ ? $delay
+ : $hash->{INTERVAL}
+ );
+
+ Log3 $name, 5,
+ "THINKINGCLEANER $name: called function THINKINGCLEANER_GetStatus()";
+
+ RemoveInternalTimer($hash);
+ InternalTimer( gettimeofday() + $interval,
+ "THINKINGCLEANER_GetStatus", $hash, 0 );
+
+ return
+ if ( $delay || AttrVal( $name, "disable", 0 ) == 1 );
+
+ THINKINGCLEANER_SendCommand( $hash, "full_status.json" );
+
+ return;
+}
-###################################
sub THINKINGCLEANER_SendCommand($$;$$) {
my ( $hash, $service, $cmd, $type ) = @_;
my $name = $hash->{NAME};
@@ -1166,7 +1184,6 @@ sub THINKINGCLEANER_SendCommand($$;$$) {
return;
}
-###################################
sub THINKINGCLEANER_ReceiveCommand($$$) {
my ( $param, $err, $data ) = @_;
my $hash = $param->{hash};
@@ -1728,73 +1745,6 @@ sub THINKINGCLEANER_ReceiveCommand($$$) {
return;
}
-###################################
-sub THINKINGCLEANER_CGI() {
- my ($request) = @_;
-
- # data received
- if ( defined( $FW_httpheader{UUID} ) ) {
- if ( defined( $modules{THINKINGCLEANER}{defptr} ) ) {
- while ( my ( $key, $value ) =
- each %{ $modules{THINKINGCLEANER}{defptr} } )
- {
-
- my $uuid = ReadingsVal( $key, "uuid", undef );
- next if ( !$uuid || $uuid ne $FW_httpheader{UUID} );
-
- $defs{$key}{WEBHOOK_COUNTER}++;
- $defs{$key}{WEBHOOK_LAST} = TimeNow();
-
- Log3 $key, 4,
-"THINKINGCLEANER $key: Received webhook for matching UUID at device $key";
-
- my $delay = undef;
-
-# we need some delay as to the Robo seems to send webhooks but it's status does
-# not really reflect the change we'd expect to get here already so give 'em some
-# more time to think about it...
- $delay = "2"
- if ( defined( $defs{$key}{LAST_COMMAND} )
- && time() - time_str2num( $defs{$key}{LAST_COMMAND} ) < 3 );
-
- THINKINGCLEANER_GetStatus( $defs{$key}, $delay );
- last;
- }
- }
-
- return ( undef, undef );
- }
-
- # no data received
- else {
- Log3 undef, 5, "THINKINGCLEANER: received malformed request\n$request";
- }
-
- return ( "text/plain; charset=utf-8", "Call failure: " . $request );
-}
-
-###################################
-sub THINKINGCLEANER_Undefine($$$) {
- my ( $hash, $a, $h ) = @_;
- my $name = $hash->{NAME};
-
- if ( defined( $hash->{fhem}{infix} ) ) {
- THINKINGCLEANER_removeExtension( $hash->{fhem}{infix} );
- }
-
- Log3 $name, 5,
- "THINKINGCLEANER $name: called function THINKINGCLEANER_Undefine()";
-
- # Stop the internal GetStatus-Loop and exit
- RemoveInternalTimer($hash);
-
- # release reverse pointer
- delete $modules{THINKINGCLEANER}{defptr}{$name};
-
- return;
-}
-
-###################################
sub THINKINGCLEANER_time2sec($) {
my ($timeString) = @_;
my @time = split /:/, $timeString;
@@ -1802,7 +1752,6 @@ sub THINKINGCLEANER_time2sec($) {
return $time[0] * 3600 + $time[1] * 60;
}
-###################################
sub THINKINGCLEANER_sec2time($) {
my ($sec) = @_;
@@ -1818,6 +1767,7 @@ sub THINKINGCLEANER_sec2time($) {
return "$hours:$minutes:$seconds";
}
+
1;
=pod
diff --git a/fhem/FHEM/75_msgConfig.pm b/fhem/FHEM/75_msgConfig.pm
index 2ed6a2681..668159aff 100755
--- a/fhem/FHEM/75_msgConfig.pm
+++ b/fhem/FHEM/75_msgConfig.pm
@@ -1,41 +1,11 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# 97_msgConfig.pm
-# Global configuration settings for FHEM msg command.
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
package main;
-
use strict;
use warnings;
use Data::Dumper;
-sub msgConfig_Set($@);
-sub msgConfig_Get($@);
-sub msgConfig_Define($$);
-sub msgConfig_Undefine($$);
-
-###################################
+# initialize ##################################################################
sub msgConfig_Initialize($) {
my ($hash) = @_;
@@ -173,7 +143,7 @@ sub msgConfig_Initialize($) {
}
}
-###################################
+# regular Fn ##################################################################
sub msgConfig_Define($$) {
my ( $hash, $def ) = @_;
@@ -212,7 +182,6 @@ sub msgConfig_Define($$) {
return undef;
}
-###################################
sub msgConfig_Undefine($$) {
my ( $hash, $name ) = @_;
@@ -223,7 +192,6 @@ sub msgConfig_Undefine($$) {
return undef;
}
-###################################
sub msgConfig_Set($@) {
my ( $hash, @a ) = @_;
my $name = $hash->{NAME};
@@ -275,7 +243,7 @@ sub msgConfig_Set($@) {
$attr{$device}{userattr} .= " msgLocationName"
if ( defined( $attr{$device}{userattr} )
&& $attr{$device}{userattr} !~
-/^msgLocationName$|^msgLocationName\s|\smsgLocationName\s|\smsgLocationName$/
+m/^msgLocationName$|^msgLocationName\s|\smsgLocationName\s|\smsgLocationName$/
);
$attr{$device}{userattr} = "msgLocationName"
if ( !defined( $attr{$device}{userattr} ) );
@@ -399,9 +367,10 @@ sub msgConfig_Set($@) {
return
"Unknown argument $what, choose one of cleanReadings addLocation createSwitcherDev:de,en createResidentsDev:de,en";
}
+
+ return undef;
}
-###################################
sub msgConfig_Get($@) {
my ( $hash, @a ) = @_;
my $name = $hash->{NAME};
@@ -578,9 +547,11 @@ sub msgConfig_Get($@) {
return
"Unknown argument $what, choose one of routeCmd:,audio,light,mail,push,screen,queue";
}
+
+ return undef;
}
-########################################
+# module Fn ####################################################################
sub MSG_FindAttrVal($$$$) {
my ( $d, $n, $msgType, $default ) = @_;
$msgType = "" unless ($msgType);
@@ -636,7 +607,6 @@ sub MSG_FindAttrVal($$$$) {
);
}
-########################################
sub msgConfig_FindReadingsVal($$$$) {
my ( $d, $n, $msgType, $default ) = @_;
$msgType = ucfirst($msgType) if ($msgType);
@@ -664,7 +634,6 @@ sub msgConfig_FindReadingsVal($$$$) {
);
}
-########################################
sub msgConfig_QueueAdd(@) {
my (
$msgA, $params, $datetime, $msgID,
@@ -703,7 +672,6 @@ sub msgConfig_QueueAdd(@) {
return 1;
}
-########################################
sub msgConfig_QueueReleaseMsgId($$) {
my ( $recipient, $msgID ) = @_;
diff --git a/fhem/FHEM/98_powerMap.pm b/fhem/FHEM/98_powerMap.pm
index 19fedd273..0872d28ae 100644
--- a/fhem/FHEM/98_powerMap.pm
+++ b/fhem/FHEM/98_powerMap.pm
@@ -1,59 +1,18 @@
-################################################################################
+###############################################################################
# $Id$
-##############################################################################
#
-# 98_powerMap.pm
-# Original version by igami
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-################################################################################
# TODO
# - document how to include powerMap for other module maintainers
# (see 50_HP1000)
#
-
package main;
use strict;
use warnings;
+use Data::Dumper;
+
use Unit;
-# forward declarations #########################################################
-sub powerMap_Initialize($);
-
-sub powerMap_Define($$);
-sub powerMap_Undefine($$);
-sub powerMap_Set($@);
-sub powerMap_Get($@);
-sub powerMap_Attr(@);
-sub powerMap_Notify($$);
-
-sub powerMap_AttrVal($$$$);
-sub powerMap_load($$;$$);
-sub powerMap_unload($$);
-sub powerMap_findPowerMaps($;$);
-sub powerMap_verifyEventChain($$$);
-sub powerMap_power($$$;$);
-sub powerMap_energy($$;$);
-sub powerMap_update($;$);
-
-# module hashes ################################################################
+# module hashes ###############################################################
my %powerMap_tmpl = (
# Format example for devices w/ model support:
@@ -540,7 +499,7 @@ my %powerMap_tmpl = (
},
);
-# initialize ###################################################################
+# initialize ##################################################################
sub powerMap_Initialize($) {
my ($hash) = @_;
my $TYPE = "powerMap";
@@ -553,7 +512,7 @@ sub powerMap_Initialize($) {
$hash->{NotifyFn} = $TYPE . "_Notify";
$hash->{AttrList} =
- "disable:1,0 "
+ "disable:1,0 disabledForIntervals do_not_notify:1,0 "
. $TYPE
. "_gridV:230,110 "
. $TYPE
@@ -568,7 +527,7 @@ sub powerMap_Initialize($) {
addToAttrList( $TYPE . ":textField-long" );
}
-# regular Fn ###################################################################
+# regular Fn ##################################################################
sub powerMap_Define($$) {
my ( $hash, $def ) = @_;
my ( $name, $type, $rest ) = split( /[\s]+/, $def, 3 );
@@ -747,7 +706,7 @@ sub powerMap_Notify($$) {
next unless ( defined($event) );
# initialize or terminate powerMap for each device
- if ( $event =~ /^(INITIALIZED|SHUTDOWN)$/ ) {
+ if ( $event =~ /^(INITIALIZED|REREADCFG|SHUTDOWN)$/ ) {
foreach ( keys %{ powerMap_findPowerMaps( $name, ":PM_$1" ) } )
{
next
@@ -1337,6 +1296,8 @@ sub powerMap_verifyEventChain($$$) {
return 1;
}
+sub powerMap_power($$$;$);
+
sub powerMap_power($$$;$) {
my ( $name, $dev, $event, $loop ) = @_;
my $hash = $defs{$name};
@@ -1579,7 +1540,7 @@ sub powerMap_update($;$) {
1;
-# commandref ###################################################################
+# commandref ##################################################################
=pod
=item helper
diff --git a/fhem/FHEM/ONKYOdb.pm b/fhem/FHEM/ONKYOdb.pm
index 18d246004..b5edf1172 100644
--- a/fhem/FHEM/ONKYOdb.pm
+++ b/fhem/FHEM/ONKYOdb.pm
@@ -1,34 +1,9 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# ONKYOdb.pm
-# ONKYO command database for ONKYO AVR module to split DB from code
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
-sub ONKYOdb_Initialize() {
-}
+package main;
+sub ONKYOdb_Initialize() { }
package ONKYOdb;
-
use strict;
use warnings;
diff --git a/fhem/FHEM/RESIDENTStk.pm b/fhem/FHEM/RESIDENTStk.pm
index aea2b8e94..7dcff942d 100644
--- a/fhem/FHEM/RESIDENTStk.pm
+++ b/fhem/FHEM/RESIDENTStk.pm
@@ -541,10 +541,10 @@ return;;\
Log3 $NAME, 3,
"RESIDENTStk $NAME: "
. "new notify macro device $macroRNameGotosleep created";
- fhem
-"define $macroRNameGotosleep notify $macroRNameGotosleep $templateGotosleep";
- fhem
-"attr $macroRNameGotosleep comment Auto-created by RESIDENTS Toolkit: FHEM commands to run when all residents are gettin' ready for bed";
+ fhem "define $macroRNameGotosleep "
+ . "notify $macroRNameGotosleep $templateGotosleep";
+ fhem "attr $macroRNameGotosleep "
+ . "comment Auto-created by RESIDENTS Toolkit: FHEM commands to run when all residents are gettin' ready for bed";
fhem "attr $macroRNameGotosleep room $room"
if ($room);
}
@@ -2061,15 +2061,19 @@ sub RESIDENTStk_RG_Attr(@) {
if ( $lang eq "DE" ) {
$attr{$name}{devStateIcon} =
-'.*zuhause:user_available:absent .*anwesend:user_available:absent .*abwesend:user_away:home .*verreist:user_ext_away:home .*bettfertig:scene_toilet:asleep .*schlaeft:scene_sleeping:awoken .*schläft:scene_sleeping:awoken .*aufgestanden:scene_sleeping_alternat:home .*:user_unknown:home';
+ '.*zuhause:user_available:absent '
+ . '.*anwesend:user_available:absent .*abwesend:user_away:home .*verreist:user_ext_away:home .*bettfertig:scene_toilet:asleep .*schlaeft:scene_sleeping:awoken .*schläft:scene_sleeping:awoken .*aufgestanden:scene_sleeping_alternat:home .*:user_unknown:home';
$attr{$name}{eventMap} =
-"home:zuhause absent:abwesend gone:verreist gotosleep:bettfertig asleep:schläft awoken:aufgestanden";
+ "home:zuhause absent:abwesend gone:verreist "
+ . "gotosleep:bettfertig asleep:schläft awoken:aufgestanden";
$attr{$name}{widgetOverride} =
-"state:zuhause,bettfertig,schläft,aufgestanden,abwesend,verreist";
+ "state:zuhause,bettfertig,schläft,"
+ . "aufgestanden,abwesend,verreist";
}
elsif ( $lang eq "EN" ) {
$attr{$name}{devStateIcon} =
-'.*home:user_available:absent .*absent:user_away:home .*gone:user_ext_away:home .*gotosleep:scene_toilet:asleep .*asleep:scene_sleeping:awoken .*awoken:scene_sleeping_alternat:home .*:user_unknown:home';
+ '.*home:user_available:absent .*absent:user_away:home '
+ . '.*gone:user_ext_away:home .*gotosleep:scene_toilet:asleep .*asleep:scene_sleeping:awoken .*awoken:scene_sleeping_alternat:home .*:user_unknown:home';
delete $attr{$name}{eventMap}
if ( defined( $attr{$name}{eventMap} ) );
delete $attr{$name}{widgetOverride}
diff --git a/fhem/FHEM/msgSchema.pm b/fhem/FHEM/msgSchema.pm
index fd7bb196e..49df7fff8 100755
--- a/fhem/FHEM/msgSchema.pm
+++ b/fhem/FHEM/msgSchema.pm
@@ -1,38 +1,9 @@
+###############################################################################
# $Id$
-##############################################################################
-#
-# msgSchema.pm
-# Schema database for FHEM modules and their messaging options.
-# These commands are being used as default setting for FHEM command 'msg'
-# unless there is an explicit msgCmd* attribute.
-#
-# FHEM module authors may request to extend this file
-#
-# Copyright by Julian Pawlowski
-# e-mail: julian.pawlowski at gmail.com
-#
-# This file is part of fhem.
-#
-# Fhem is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Fhem is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with fhem. If not, see .
-#
-##############################################################################
-
-sub msgSchema_Initialize() {
-}
+package main;
+sub msgSchema_Initialize() { }
package msgSchema;
-
use strict;
use warnings;