From a9823f72a91861197b870c0fd93e3dfb49dcd460 Mon Sep 17 00:00:00 2001 From: markooldenburg <> Date: Thu, 29 Oct 2015 09:04:55 +0000 Subject: [PATCH] 74_AMAD: New Mirror Version 0.8.0, AMADCommBridge (AMADCommunication Device), toggle between to BT Devices, clear Notificationbar (Automagic,All), play Notify Soundfile (WallClock), check for a activ task on the tablet/phone git-svn-id: https://svn.fhem.de/fhem/trunk@9713 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 6 + fhem/FHEM/74_AMAD.pm | 823 +++++++++++++++++++++++++++++-------------- 2 files changed, 566 insertions(+), 263 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 812454826..d3c86a0d6 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,11 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - updated: 74_AMAD: New Mirror Version + - feature: 74_AMAD: AMADCommBridge (AMADCommunication Device) + toggle between to BT Devices, clear Notificationbar + (Automagic,All), play Notify Soundfile (WallClock), + check for a activ task on the tablet/phone + - bugfix: 74_AMAD: improved error handling - bugfix: 70_PIONEERAVR: fixed the decoding for the reading "display". - feature: 93_DbLog: Added support for longpoll SVG. - feature: contrib/98_openweathermap.pm - add support for stationByZip. diff --git a/fhem/FHEM/74_AMAD.pm b/fhem/FHEM/74_AMAD.pm index 99aa3052c..9125dc12b 100644 --- a/fhem/FHEM/74_AMAD.pm +++ b/fhem/FHEM/74_AMAD.pm @@ -33,8 +33,9 @@ use warnings; use Time::HiRes qw(gettimeofday); use HttpUtils; +use TcpServerUtils; -my $version = "0.6.3"; +my $version = "0.8.0"; @@ -46,65 +47,95 @@ sub AMAD_Initialize($) { $hash->{DefFn} = "AMAD_Define"; $hash->{UndefFn} = "AMAD_Undef"; $hash->{AttrFn} = "AMAD_Attr"; - $hash->{ReadFn} = "AMAD_Read"; + $hash->{ReadFn} = "AMAD_CommBridge_Read"; + $hash->{AttrList} = "setOpenApp ". + "checkActiveTask ". "setFullscreen:0,1 ". "setScreenOrientation:0,1 ". "setScreenBrightness:0,1 ". - "fhemServerIP ". + "setBluetoothDevice ". "root:0,1 ". "interval ". "port ". "disable:1 "; $hash->{AttrList} .= $readingFnAttributes; - - foreach my $d(sort keys %defs) { - next if($defs{$d}{TYPE} ne "AMAD"); - $defs{$d}->{VERSION} = $version; + foreach my $d(sort keys %{$modules{AMAD}{defptr}}) { + my $hash = $modules{AMAD}{defptr}{$d}; + $hash->{VERSION} = $version; } } sub AMAD_Define($$) { -my ( $hash, $def ) = @_; + my ( $hash, $def ) = @_; + my @a = split( "[ \t][ \t]*", $def ); - return "too few parameters: define AMAD " if ( @a != 3 ); - + return "too few parameters: define AMAD " if( @a != 3 && $a[0] ne "AMADCommBridge" ); my $name = $a[0]; my $host = $a[2]; my $port = 8090; my $interval = 180; - $hash->{HOST} = $host; + $hash->{HOST} = $host if( $host ); $hash->{PORT} = $port; - $hash->{INTERVAL} = $interval; + $hash->{INTERVAL} = $interval if( $hash->{HOST} ); $hash->{VERSION} = $version; - $hash->{helper}{infoErrorCounter} = 0; - $hash->{helper}{setCmdErrorCounter} = 0; - - Log3 $name, 3, "AMAD ($name) - defined with host $hash->{HOST} on port $hash->{PORT} and interval $hash->{INTERVAL} (sec)"; - - AMAD_GetUpdateLocal( $hash ); - - InternalTimer( gettimeofday()+$hash->{INTERVAL}, "AMAD_GetUpdateTimer", $hash, 0 ); + $hash->{helper}{infoErrorCounter} = 0 if( $hash->{HOST} ); + $hash->{helper}{setCmdErrorCounter} = 0 if( $hash->{HOST} ); - # $hash->{STATE} = "initialized"; # direktes setzen von STATE ist absolete - readingsSingleUpdate ( $hash, "state", "initialized", 1 ); - readingsSingleUpdate ( $hash, "deviceState", "online", 1 ); + if( ! $hash->{HOST} ) { + return "there is already a AMAD Bridge" if( $modules{AMAD}{defptr}{BRIDGE} ); - return undef; + $hash->{BRIDGE} = 1; + $modules{AMAD}{defptr}{BRIDGE} = $hash; + $attr{$name}{room} = "AMAD"; + Log3 $name, 3, "AMAD ($name) - defined Bridge with Socketport $hash->{PORT}"; + AMAD_CommBridge_Open( $hash ); + + } else { + if( ! $modules{AMAD}{defptr}{BRIDGE} && $init_done ) { + CommandDefine( undef, "AMADCommBridge AMAD" ); + } + + Log3 $name, 3, "AMAD ($name) - defined with host $hash->{HOST} on port $hash->{PORT} and interval $hash->{INTERVAL} (sec)"; + + $attr{$name}{room} = "AMAD"; + readingsSingleUpdate ( $hash, "state", "initialized", 1 ) if( $hash->{HOST} ); + readingsSingleUpdate ( $hash, "deviceState", "online", 1 ) if( $hash->{HOST} ); + + InternalTimer( gettimeofday()+$hash->{INTERVAL}, "AMAD_GetUpdateTimer", $hash, 0 ) if( $hash->{HOST} ); + + $modules{AMAD}{defptr}{$hash->{HOST}} = $hash; + + return undef; + } } sub AMAD_Undef($$) { -my ( $hash, $arg ) = @_; + my ( $hash, $arg ) = @_; + + if( $hash->{BRIDGE} ) { + delete $modules{AMAD}{defptr}{BRIDGE}; + my $ret = TcpServer_Close( $hash ); + return $ret; - RemoveInternalTimer( $hash ); - - return undef; + } else { + delete $modules{AMAD}{defptr}{$hash->{HOST}}; + RemoveInternalTimer( $hash ); + + foreach my $d(sort keys %{$modules{AMAD}{defptr}}) { + my $hash = $modules{AMAD}{defptr}{$d}; + my $host = $hash->{HOST}; + + return if( $host ); + CommandDelete( undef, "AMADCommBridge" ); + } + } } sub AMAD_Attr(@) { @@ -117,11 +148,9 @@ my ( $cmd, $name, $attrName, $attrVal ) = @_; if( $attrVal eq "0" ) { RemoveInternalTimer( $hash ); InternalTimer( gettimeofday()+2, "AMAD_GetUpdateTimer", $hash, 0 ) if( ReadingsVal( $hash->{NAME}, "state", 0 ) eq "disabled" ); - # $hash->{STATE}='active'; # direktes STATE setzen ist absolete readingsSingleUpdate ( $hash, "state", "active", 1 ); Log3 $name, 3, "AMAD ($name) - enabled"; } else { - # $hash->{STATE} = 'disabled'; readingsSingleUpdate ( $hash, "state", "disabled", 1 ); RemoveInternalTimer( $hash ); Log3 $name, 3, "AMAD ($name) - disabled"; @@ -130,7 +159,6 @@ my ( $cmd, $name, $attrName, $attrVal ) = @_; elsif( $cmd eq "del" ) { RemoveInternalTimer( $hash ); InternalTimer( gettimeofday()+2, "AMAD_GetUpdateTimer", $hash, 0 ) if( ReadingsVal( $hash->{NAME}, "state", 0 ) eq "disabled" ); - # $hash->{STATE}='active'; readingsSingleUpdate ( $hash, "state", "active", 1 ); Log3 $name, 3, "AMAD ($name) - enabled"; @@ -205,7 +233,7 @@ sub AMAD_GetUpdateTimer($) { my ( $hash ) = @_; my $name = $hash->{NAME}; - AMAD_RetrieveAutomagicInfo( $hash ) if( ReadingsVal( $name, "deviceState", "online" ) eq "online" && AttrVal( $name, "disable", 0 ) ne "1" ); ### deviceState muß von Hand online/offline gesetzt werden z.B. ueber RESIDENZ Modul + AMAD_RetrieveAutomagicInfo( $hash ) if( ReadingsVal( $name, "deviceState", "online" ) eq "online" && AttrVal( $name, "disable", 0 ) ne "1" ); ### deviceState muss von Hand online/offline gesetzt werden z.B. ueber RESIDENZ Modul InternalTimer( gettimeofday()+$hash->{INTERVAL}, "AMAD_GetUpdateTimer", $hash, 1 ); Log3 $name, 4, "AMAD ($name) - Call AMAD_GetUpdateTimer"; @@ -213,75 +241,25 @@ sub AMAD_GetUpdateTimer($) { return 1; } -sub AMAD_Set($$@) { - - my ( $hash, $name, $cmd, @val ) = @_; - my $apps = AttrVal( $name, "setOpenApp", "none" ); - - my $list = ""; - - $list .= "screenMsg "; - $list .= "ttsMsg "; - $list .= "volume:slider,0,1,15 "; - $list .= "deviceState:online,offline "; - $list .= "mediaPlayer:play,stop,next,back " if( AttrVal( $name, "fhemServerIP", "none" ) ne "none" ); - $list .= "screenBrightness:slider,0,1,255 " if( AttrVal( $name, "setScreenBrightness", "1" ) eq "1" ); - $list .= "screen:on,off "; - $list .= "screenOrientation:auto,landscape,portrait " if( AttrVal( $name, "setScreenOrientation", "1" ) eq "1" ); - $list .= "screenFullscreen:on,off " if( AttrVal( $name, "setFullscreen", "1" ) eq "1" ); - $list .= "openURL "; - $list .= "openApp:$apps " if( AttrVal( $name, "setOpenApp", "none" ) ne "none" ); - $list .= "nextAlarmTime:time "; - $list .= "statusRequest:noArg "; - $list .= "system:reboot " if( AttrVal( $name, "root", "1" ) eq "1" ); - - - if (lc $cmd eq 'screenmsg' - || lc $cmd eq 'ttsmsg' - || lc $cmd eq 'volume' - || lc $cmd eq 'mediaplayer' - || lc $cmd eq 'devicestate' - || lc $cmd eq 'screenbrightness' - || lc $cmd eq 'screenorientation' - || lc $cmd eq 'screenfullscreen' - || lc $cmd eq 'screen' - || lc $cmd eq 'openurl' - || lc $cmd eq 'openapp' - || lc $cmd eq 'nextalarmtime' - || lc $cmd eq 'system' - || lc $cmd eq 'statusrequest') { - - Log3 $name, 5, "AMAD ($name) - set $name $cmd ".join(" ", @val); - - return "set command only works if state not equal initialized, please wait for next interval run" if( ReadingsVal( $hash->{NAME}, "state", 0 ) eq "initialized"); - return "Cannot set command, FHEM Device is disabled" if( AttrVal( $name, "disable", "0" ) eq "1" ); - - return AMAD_SelectSetCmd( $hash, $cmd, @val ) if( @val ) && ( ReadingsVal( $name, "deviceState", "online" ) eq "offline" ) && ( lc $cmd eq 'devicestate' ); - return "Cannot set command, FHEM Device is offline" if( ReadingsVal( $name, "deviceState", "online" ) eq "offline" ); - - return AMAD_SelectSetCmd( $hash, $cmd, @val ) if( @val ) || ( lc $cmd eq 'statusrequest' ); - } - - return "Unknown argument $cmd, bearword as argument or wrong parameter(s), choose one of $list"; -} - sub AMAD_RetrieveAutomagicInfo($) { my ($hash) = @_; my $name = $hash->{NAME}; my $host = $hash->{HOST}; my $port = $hash->{PORT}; - my $fhemip = AttrVal( $name, "fhemServerIP", "none" ); + my $fhemip = ReadingsVal( "AMADCommBridge", "fhemServerIP", "none" ); + my $activetask = AttrVal( $name, "checkActiveTask", "none" ); + my $url = "http://" . $host . ":" . $port . "/fhem-amad/deviceInfo/"; # Path muß so im Automagic als http request Trigger drin stehen HttpUtils_NonblockingGet( { url => $url, - timeout => 5, + timeout => 60, hash => $hash, method => "GET", - header => "fhemIP: $fhemip\r\nfhemDevice: $name", + header => "fhemIP: $fhemip\r\nfhemDevice: $name\r\nactiveTask: $activetask", doTrigger => 1, callback => \&AMAD_RetrieveAutomagicInfoFinished, } @@ -313,7 +291,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { Log3 $name, 5, "AMAD ($name) - CHECK THE LAST ERROR READINGS FOR MORE INFO, DEVICE IS SET OFFLINE"; readingsBulkUpdate( $hash, "deviceState", "offline" ); - # $hash->{STATE} = "AMAD Flows inactive, device set offline"; # STATE direkt setzen ist absolete readingsBulkUpdate ( $hash, "state", "AMAD Flows inactive, device set offline"); } elsif( $hash->{helper}{infoErrorCounter} > 9 && $hash->{helper}{setCmdErrorCounter} > 4 ) { @@ -322,7 +299,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { Log3 $name, 4, "AMAD ($name) - UNKNOWN ERROR, PLEASE CONTACT THE DEVELOPER, DEVICE DISABLED"; $attr{$name}{disable} = 1; - # $hash->{STATE} = "Unknown Error, device disabled"; readingsBulkUpdate ( $hash, "state", "Unknown Error, device disabled"); $hash->{helper}{infoErrorCounter} = 0; @@ -346,7 +322,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { Log3 $name, 4, "AMAD ($name) - To many Errors please check your Network or Device Configuration, DEVICE IS SET OFFLINE"; readingsBulkUpdate( $hash, "deviceState", "offline" ); - # $hash->{STATE} = "To many Errors, device set offline"; # STATE direkt setzen ist absolete readingsBulkUpdate ( $hash, "state", "To many Errors, device set offline"); $hash->{helper}{infoErrorCounter} = 0; } @@ -356,7 +331,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { if( defined( $err ) ) { if( $err ne "" ) { readingsBeginUpdate( $hash ); - # $hash->{STATE} = $err if( $hash->{STATE} ne "initialized" ); readingsBulkUpdate ( $hash, "state", "$err") if( ReadingsVal( $name, "state", 1 ) ne "initialized" ); $hash->{helper}{infoErrorCounter} = ( $hash->{helper}{infoErrorCounter} + 1 ); @@ -380,7 +354,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { if( $data eq "" and exists( $param->{code} ) ) { readingsBeginUpdate( $hash ); - # $hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); # direktes setzen von STATE ist absolete readingsBulkUpdate ( $hash, "state", $param->{code} ) if( ReadingsVal( $name, "state", 1 ) ne "initialized" ); $hash->{helper}{infoErrorCounter} = ( $hash->{helper}{infoErrorCounter} + 1 ); @@ -399,7 +372,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { } if( ( $data =~ /Error/i ) and exists( $param->{code} ) ) { - #$hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); ## STATE direkt ist absolete readingsBeginUpdate( $hash ); readingsBulkUpdate( $hash, "state", $param->{code} ) if( ReadingsVal( $name, "state" ,0) ne "initialized" ); $hash->{helper}{infoErrorCounter} = ( $hash->{helper}{infoErrorCounter} + 1 ); @@ -427,7 +399,6 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { $hash->{helper}{infoErrorCounter} = 0; ### Begin Response Processing - # $hash->{STATE} = "active" if( $hash->{STATE} eq "initialized" || $hash->{STATE} ne "active" ); ## STATE direkt setzen ist absolete readingsSingleUpdate( $hash, "state", "active", 1) if( ReadingsVal( $name, "state", 0 ) ne "initialized" or ReadingsVal( $name, "state", 0 ) ne "active" ); my @valuestring = split( '@@@@', $data ); @@ -454,163 +425,92 @@ sub AMAD_RetrieveAutomagicInfoFinished($$$) { $hash->{helper}{infoErrorCounter} = 0; ### End Response Processing - #$hash->{STATE} = "active" if( $hash->{STATE} eq "initialized" ); ## STATE direkt setzen ist absolete readingsBulkUpdate( $hash, "state", "active" ) if( ReadingsVal( $name, "state", 0 ) eq "initialized" ); readingsEndUpdate( $hash, 1 ); return undef; } -sub AMAD_HTTP_POST($$) { +sub AMAD_Set($$@) { + + my ( $hash, $name, $cmd, @val ) = @_; + + if( $name ne "AMADCommBridge" ) { + my $apps = AttrVal( $name, "setOpenApp", "none" ); + my $btdev = AttrVal( $name, "setBluetoothDevice", "none" ); + my $activetask = AttrVal( $name, "setActiveTask", "none" ); + + my $list = ""; + $list .= "screenMsg "; + $list .= "ttsMsg "; + $list .= "volume:slider,0,1,15 "; + $list .= "deviceState:online,offline "; + $list .= "mediaPlayer:play,stop,next,back " if( ReadingsVal( "AMADCommBridge", "fhemServerIP", "none" ) ne "none"); + $list .= "screenBrightness:slider,0,1,255 " if( AttrVal( $name, "setScreenBrightness", "1" ) eq "1" ); + $list .= "screen:on,off "; + $list .= "screenOrientation:auto,landscape,portrait " if( AttrVal( $name, "setScreenOrientation", "1" ) eq "1" ); + $list .= "screenFullscreen:on,off " if( AttrVal( $name, "setFullscreen", "1" ) eq "1" ); + $list .= "openURL "; + $list .= "openApp:$apps " if( AttrVal( $name, "setOpenApp", "none" ) ne "none" ); + $list .= "nextAlarmTime:time "; + $list .= "statusRequest:noArg "; + $list .= "system:reboot " if( AttrVal( $name, "root", "1" ) eq "1" ); + $list .= "bluetooth:on,off "; + $list .= "notifySndFile "; + $list .= "clearNotificationBar:All,Automagic "; + $list .= "changetoBTDevice:$btdev " if( AttrVal( $name, "setBluetoothDevice", "none" ) ne "none" ); - my ( $hash, $url ) = @_; - my $name = $hash->{NAME}; - - #my $state = $hash->{STATE}; - my $state = ReadingsVal( $name, "state", 0 ); - - #$hash->{STATE} = "Send HTTP POST"; - readingsSingleUpdate( $hash, "state", "Send HTTP POST", 1 ); - - HttpUtils_NonblockingGet( - { - url => $url, - timeout => 5, - hash => $hash, - method => "POST", - doTrigger => 1, - callback => \&AMAD_HTTP_POSTerrorHandling, + if( lc $cmd eq 'screenmsg' + || lc $cmd eq 'ttsmsg' + || lc $cmd eq 'volume' + || lc $cmd eq 'mediaplayer' + || lc $cmd eq 'devicestate' + || lc $cmd eq 'screenbrightness' + || lc $cmd eq 'screenorientation' + || lc $cmd eq 'screenfullscreen' + || lc $cmd eq 'screen' + || lc $cmd eq 'openurl' + || lc $cmd eq 'openapp' + || lc $cmd eq 'nextalarmtime' + || lc $cmd eq 'bluetooth' + || lc $cmd eq 'system' + || lc $cmd eq 'notifysndfile' + || lc $cmd eq 'changetobtdevice' + || lc $cmd eq 'clearnotificationbar' + || lc $cmd eq 'statusrequest' ) { + + Log3 $name, 5, "AMAD ($name) - set $name $cmd ".join(" ", @val); + + return "set command only works if state not equal initialized, please wait for next interval run" if( ReadingsVal( $hash->{NAME}, "state", 0 ) eq "initialized"); + return "Cannot set command, FHEM Device is disabled" if( AttrVal( $name, "disable", "0" ) eq "1" ); + + return AMAD_SelectSetCmd( $hash, $cmd, @val ) if( @val ) && ( ReadingsVal( $name, "deviceState", "online" ) eq "offline" ) && ( lc $cmd eq 'devicestate' ); + return "Cannot set command, FHEM Device is offline" if( ReadingsVal( $name, "deviceState", "online" ) eq "offline" ); + + return AMAD_SelectSetCmd( $hash, $cmd, @val ) if( @val ) || ( lc $cmd eq 'statusrequest' ); } - ); - Log3 $name, 4, "AMAD ($name) - Send HTTP POST with URL $url"; - #$hash->{STATE} = $state; - readingsSingleUpdate( $hash, "state", $state, 1 ); - - return undef; -} - -sub AMAD_HTTP_POSTerrorHandling($$$) { - - my ( $param, $err, $data ) = @_; - my $hash = $param->{hash}; - my $name = $hash->{NAME}; + return "Unknown argument $cmd, bearword as argument or wrong parameter(s), choose one of $list"; + } - - ### Begin Error Handling - if( $hash->{helper}{setCmdErrorCounter} > 2 ) { - readingsBeginUpdate( $hash ); - readingsBulkUpdate( $hash, "lastSetCommandState", "statusRequest_error" ); + elsif( $name eq "AMADCommBridge" ) { + + my $list = ""; + + ## set Befehle für die AMAD_CommBridge + $list .= "expertMode:0,1 " if( $modules{AMAD}{defptr}{BRIDGE} ); + $list .= "fhemServerIP " if( $modules{AMAD}{defptr}{BRIDGE} ); - if( ReadingsVal( $name, "flow_Informations", "active" ) eq "inactive" && ReadingsVal( $name, "flow_SetCommands", "active" ) eq "inactive" ) { - readingsBulkUpdate( $hash, "lastSetCommandError", "AMAD flows on your device inactive, please check your device" ); - Log3 $name, 5, "AMAD ($name) - CHECK THE LAST ERROR READINGS FOR MORE INFO, DEVICE IS SET OFFLINE"; - - readingsBulkUpdate( $hash, "deviceState", "offline" ); - #$hash->{STATE} = "AMAD Flows inactive, device set offline"; # STATE direkt setzen ist absolete - readingsBulkUpdate( $hash, "state", "AMAD Flows inactive, device set offline" ); - } - elsif( $hash->{helper}{infoErrorCounter} > 9 && $hash->{helper}{setCmdErrorCounter} > 4 ) { - readingsBulkUpdate($hash, "lastSetCommandError", "unknown error, please contact the developer" ); + if( lc $cmd eq 'expertmode' + || lc $cmd eq 'fhemserverip' ) { - Log3 $name, 4, "AMAD ($name) - UNKNOWN ERROR, PLEASE CONTACT THE DEVELOPER, DEVICE DISABLED"; - - $attr{$name}{disable} = 1; - #$hash->{STATE} = "Unknown Error, device disabled"; - readingsBulkUpdate( $hash, "state", "Unknown Error, device disabled" ); - $hash->{helper}{infoErrorCounter} = 0; - $hash->{helper}{setCmdErrorCounter} = 0; + readingsSingleUpdate( $hash, $cmd, $val[0], 0 ); return; } - elsif( ReadingsVal( $name, "flow_SetCommands", "active" ) eq "inactive" ) { - readingsBulkUpdate( $hash, "lastSetCommandError", "setCommands flow on your device is inactive, will try to reactivate" ); - - Log3 $name, 4, "AMAD ($name) - Flow SetCommands on your Device is inactive, will try to reactivate"; - } - elsif( $hash->{helper}{setCmdErrorCounter} > 4 && ReadingsVal( $name, "flow_SetCommands", "active" ) eq "active" ){ - readingsBulkUpdate( $hash, "lastSetCommandError", "check automagicApp on your device" ); - - Log3 $name, 4, "AMAD ($name) - Please check the AutomagicAPP on your Device"; - } - elsif( $hash->{helper}{setCmdErrorCounter} > 9 ) { - readingsBulkUpdate( $hash, "lastSetCommandError", "to many errors, check your network or device configuration" ); - - Log3 $name, 4, "AMAD ($name) - To many Errors please check your Network or Device Configuration, DEVICE IS SET OFFLINE"; - - readingsBulkUpdate( $hash, "deviceState", "offline" ); - #$hash->{STATE} = "To many Errors, device set offline"; ## STATE direkt setzen ist absolete - readingsBulkUpdate( $hash, "state", "To many Errors, device set offline" ); - $hash->{helper}{setCmdErrorCounter} = 0; - } - readingsEndUpdate( $hash, 1 ); - } - - if( defined( $err ) ) { - if( $err ne "" ) { - readingsBeginUpdate( $hash ); - #$hash->{STATE} = $err if( $hash->{STATE} ne "initialized" ); ## STATE direkt setzen ist absolete - readingsBulkUpdate( $hash, "state", $err ) if( ReadingsVal( $name, "state", 0 ) ne "initialized" ); - $hash->{helper}{setCmdErrorCounter} = ($hash->{helper}{setCmdErrorCounter} + 1); - - readingsBulkUpdate( $hash, "lastSetCommandState", "cmd_error" ); - - if( $err =~ /timed out/ ) { - readingsBulkUpdate( $hash, "lastSetCommandError", "connect to your device is timed out. check network" ); - } - elsif( $err =~ /Keine Route zum Zielrechner/ ) { - readingsBulkUpdate( $hash, "lastSetCommandError", "no route to target. bad network configuration or network is down" ); - } else { - readingsBulkUpdate( $hash, "lastSetCommandError", "$err" ); - } - readingsEndUpdate( $hash, 1 ); - - Log3 $name, 5, "AMAD ($name) - AMAD_HTTP_POST: error while POST Command: $err"; - - return; - } - } - - if( $data eq "" and exists( $param->{code} ) && $param->{code} ne 200 ) { - readingsBeginUpdate( $hash ); - #$hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); ## STATE direkt setzen ist absolete - readingsBulkUpdate( $hash, "state", $param->{code} ) if( ReadingsVal( $hash, "state", 0 ) ne "initialized" ); - $hash->{helper}{setCmdErrorCounter} = ( $hash->{helper}{setCmdErrorCounter} + 1 ); - - readingsBulkUpdate($hash, "lastSetCommandState", "cmd_error" ); - readingsBulkUpdate($hash, "lastSetCommandError", "http Error ".$param->{code} ); - readingsEndUpdate( $hash, 1 ); - - Log3 $name, 5, "AMAD ($name) - AMAD_HTTP_POST: received http code ".$param->{code}; - - return; + return "Unknown argument $cmd, bearword as argument or wrong parameter(s), choose one of $list"; } - - if( ( $data =~ /Error/i ) and exists( $param->{code} ) ) { - readingsBeginUpdate( $hash ); - #$hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); ## STATE direkt setzen ist absolete - readingsBulkUpdate( $hash, "state", $param->{code} ) if( ReadingsVal( $name, "state", 0 ) ne "initialized" ); - - $hash->{helper}{setCmdErrorCounter} = ( $hash->{helper}{setCmdErrorCounter} + 1 ); - - readingsBulkUpdate( $hash, "lastSetCommandState", "cmd_error" ); - - if( $param->{code} eq 404 ) { - readingsBulkUpdate( $hash, "lastSetCommandError", "setCommands flow is inactive on your device!" ); - } else { - readingsBulkUpdate( $hash, "lastSetCommandError", "http error ".$param->{code} ); - } - - return; - } - - ### End Error Handling - - readingsSingleUpdate( $hash, "lastSetCommandState", "cmd_done", 1 ); - $hash->{helper}{setCmdErrorCounter} = 0; - - return undef; } sub AMAD_SelectSetCmd($$@) { @@ -649,9 +549,6 @@ sub AMAD_SelectSetCmd($$@) { my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setVolume?volume=$vol"; readingsSingleUpdate( $hash, $cmd, $vol, 1 ); - - Log3 $name, 4, "AMAD ($name) - Starte Update GetUpdateLocal"; - AMAD_GetUpdateLocal( $hash ); return AMAD_HTTP_POST( $hash, $url ); } @@ -676,9 +573,6 @@ sub AMAD_SelectSetCmd($$@) { my $bri = join( " ", @data ); my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setBrightness?brightness=$bri"; - - Log3 $name, 4, "AMAD ($name) - Starte Update GetUpdateLocal"; - AMAD_GetUpdateLocal( $hash ); return AMAD_HTTP_POST( $hash,$url ); } @@ -688,9 +582,6 @@ sub AMAD_SelectSetCmd($$@) { my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setScreenOnOff?screen=$mod"; - Log3 $name, 4, "AMAD ($name) - Starte Update GetUpdateLocal"; - AMAD_GetUpdateLocal( $hash ); - return AMAD_HTTP_POST( $hash,$url ); } @@ -698,9 +589,6 @@ sub AMAD_SelectSetCmd($$@) { my $mod = join( " ", @data ); my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setScreenOrientation?orientation=$mod"; - - Log3 $name, 4, "AMAD ($name) - Starte Update GetUpdateLocal"; - AMAD_GetUpdateLocal( $hash ); return AMAD_HTTP_POST( $hash,$url ); } @@ -728,9 +616,6 @@ sub AMAD_SelectSetCmd($$@) { my @alarm = split( ":", $alarmTime ); my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setAlarm?hour=".$alarm[0]."&minute=".$alarm[1]; - - Log3 $name, 4, "AMAD ($name) - Starte Update GetUpdateLocal"; - AMAD_GetUpdateLocal( $hash ); return AMAD_HTTP_POST( $hash, $url ); } @@ -755,10 +640,303 @@ sub AMAD_SelectSetCmd($$@) { return AMAD_HTTP_POST( $hash,$url ); } + + elsif( lc $cmd eq 'bluetooth' ) { + my $mod = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setbluetooth?bluetooth=$mod"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'notifysndfile' ) { + my $notify = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/playnotifysnd?notifyfile=$notify"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'changetobtdevice' ) { + my $swToBtDevice = join( " ", @data ); + my @swToBtMac = split( /\|/, $swToBtDevice ); + my $btDevices = AttrVal( $name, "setBluetoothDevice", "none" ) if( AttrVal( $name, "setBluetoothDevice", "none" ) ne "none" ); + my @btDevice = split( ',', $btDevices ); + my @btDeviceOne = split( /\|/, $btDevice[0] ); + my @btDeviceTwo = split( /\|/, $btDevice[1] ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setbtdevice?swToBtDeviceMac=".$swToBtMac[1]."&btDeviceOne=".$btDeviceOne[1]."&btDeviceTwo=".$btDeviceTwo[1]; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'clearnotificationbar' ) { + my $appname = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/clearnotificationbar?app=$appname"; + + return AMAD_HTTP_POST( $hash,$url ); + } return undef; } +sub AMAD_HTTP_POST($$) { + + my ( $hash, $url ) = @_; + my $name = $hash->{NAME}; + + my $state = ReadingsVal( $name, "state", 0 ); + + readingsSingleUpdate( $hash, "state", "Send HTTP POST", 1 ); + + HttpUtils_NonblockingGet( + { + url => $url, + timeout => 60, + hash => $hash, + method => "POST", + doTrigger => 1, + callback => \&AMAD_HTTP_POSTerrorHandling, + } + ); + Log3 $name, 4, "AMAD ($name) - Send HTTP POST with URL $url"; + + readingsSingleUpdate( $hash, "state", $state, 1 ); + + return undef; +} + +sub AMAD_HTTP_POSTerrorHandling($$$) { + + my ( $param, $err, $data ) = @_; + my $hash = $param->{hash}; + my $name = $hash->{NAME}; + + + ### Begin Error Handling + if( $hash->{helper}{setCmdErrorCounter} > 2 ) { + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "lastSetCommandState", "statusRequest_error" ); + + if( ReadingsVal( $name, "flow_Informations", "active" ) eq "inactive" && ReadingsVal( $name, "flow_SetCommands", "active" ) eq "inactive" ) { + readingsBulkUpdate( $hash, "lastSetCommandError", "AMAD flows on your device inactive, please check your device" ); + Log3 $name, 5, "AMAD ($name) - CHECK THE LAST ERROR READINGS FOR MORE INFO, DEVICE IS SET OFFLINE"; + + readingsBulkUpdate( $hash, "deviceState", "offline" ); + readingsBulkUpdate( $hash, "state", "AMAD Flows inactive, device set offline" ); + } + elsif( $hash->{helper}{infoErrorCounter} > 9 && $hash->{helper}{setCmdErrorCounter} > 4 ) { + readingsBulkUpdate($hash, "lastSetCommandError", "unknown error, please contact the developer" ); + + Log3 $name, 4, "AMAD ($name) - UNKNOWN ERROR, PLEASE CONTACT THE DEVELOPER, DEVICE DISABLED"; + + $attr{$name}{disable} = 1; + readingsBulkUpdate( $hash, "state", "Unknown Error, device disabled" ); + $hash->{helper}{infoErrorCounter} = 0; + $hash->{helper}{setCmdErrorCounter} = 0; + + return; + } + elsif( ReadingsVal( $name, "flow_SetCommands", "active" ) eq "inactive" ) { + readingsBulkUpdate( $hash, "lastSetCommandError", "setCommands flow on your device is inactive, will try to reactivate" ); + + Log3 $name, 4, "AMAD ($name) - Flow SetCommands on your Device is inactive, will try to reactivate"; + } + elsif( $hash->{helper}{setCmdErrorCounter} > 4 && ReadingsVal( $name, "flow_SetCommands", "active" ) eq "active" ){ + readingsBulkUpdate( $hash, "lastSetCommandError", "check automagicApp on your device" ); + + Log3 $name, 4, "AMAD ($name) - Please check the AutomagicAPP on your Device"; + } + elsif( $hash->{helper}{setCmdErrorCounter} > 9 ) { + readingsBulkUpdate( $hash, "lastSetCommandError", "to many errors, check your network or device configuration" ); + + Log3 $name, 4, "AMAD ($name) - To many Errors please check your Network or Device Configuration, DEVICE IS SET OFFLINE"; + + readingsBulkUpdate( $hash, "deviceState", "offline" ); + readingsBulkUpdate( $hash, "state", "To many Errors, device set offline" ); + $hash->{helper}{setCmdErrorCounter} = 0; + } + readingsEndUpdate( $hash, 1 ); + } + + if( defined( $err ) ) { + if( $err ne "" ) { + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "state", $err ) if( ReadingsVal( $name, "state", 0 ) ne "initialized" ); + $hash->{helper}{setCmdErrorCounter} = ($hash->{helper}{setCmdErrorCounter} + 1); + + readingsBulkUpdate( $hash, "lastSetCommandState", "cmd_error" ); + + if( $err =~ /timed out/ ) { + readingsBulkUpdate( $hash, "lastSetCommandError", "connect to your device is timed out. check network" ); + } + elsif( $err =~ /Keine Route zum Zielrechner/ ) { + readingsBulkUpdate( $hash, "lastSetCommandError", "no route to target. bad network configuration or network is down" ); + } else { + readingsBulkUpdate( $hash, "lastSetCommandError", "$err" ); + } + readingsEndUpdate( $hash, 1 ); + + Log3 $name, 5, "AMAD ($name) - AMAD_HTTP_POST: error while POST Command: $err"; + + return; + } + } + + if( $data eq "" and exists( $param->{code} ) && $param->{code} ne 200 ) { + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "state", $param->{code} ) if( ReadingsVal( $hash, "state", 0 ) ne "initialized" ); + + $hash->{helper}{setCmdErrorCounter} = ( $hash->{helper}{setCmdErrorCounter} + 1 ); + + readingsBulkUpdate($hash, "lastSetCommandState", "cmd_error" ); + readingsBulkUpdate($hash, "lastSetCommandError", "http Error ".$param->{code} ); + readingsEndUpdate( $hash, 1 ); + + Log3 $name, 5, "AMAD ($name) - AMAD_HTTP_POST: received http code ".$param->{code}; + + return; + } + + if( ( $data =~ /Error/i ) and exists( $param->{code} ) ) { + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "state", $param->{code} ) if( ReadingsVal( $name, "state", 0 ) ne "initialized" ); + + $hash->{helper}{setCmdErrorCounter} = ( $hash->{helper}{setCmdErrorCounter} + 1 ); + + readingsBulkUpdate( $hash, "lastSetCommandState", "cmd_error" ); + + if( $param->{code} eq 404 ) { + readingsBulkUpdate( $hash, "lastSetCommandError", "setCommands flow is inactive on your device!" ); + } else { + readingsBulkUpdate( $hash, "lastSetCommandError", "http error ".$param->{code} ); + } + + return; + } + + ### End Error Handling + + readingsSingleUpdate( $hash, "lastSetCommandState", "cmd_done", 1 ); + $hash->{helper}{setCmdErrorCounter} = 0; + + return undef; +} + +sub AMAD_CommBridge_Open($) { + + my ( $hash ) = @_; + my $name = $hash->{NAME}; + + # Oeffnen des TCP Sockets + my $ret = TcpServer_Open( $hash, "8090", "global" ); + + if( $ret && !$init_done ) { + Log3 $name, 3, "$ret. Exiting."; + exit(1); + } + + readingsSingleUpdate ( $hash, "state", "opened", 1 ); + Log3 $name, 5, "Socket wird geöffnet."; + + return $ret; +} + +sub AMAD_CommBridge_Read($) { + + my ( $hash ) = @_; + my $name = $hash->{NAME}; + my $brihash = $modules{AMAD}{defptr}{BRIDGE}; + + + if( $hash->{SERVERSOCKET} ) { # Accept and create a child + TcpServer_Accept( $hash, "AMAD" ); + + return; + } + + # Read 1024 byte of data + my $buf; + my $ret = sysread($hash->{CD}, $buf, 1024); + + # When there is an error in connection return + if( !defined($ret ) || $ret <= 0 ) { + CommandDelete( undef, $hash->{NAME} ); + return; + } + + my $response = "header lines: \r\n AMADCommBridge receive Data complete\r\n FHEM will process\r\n now\r\n"; + + my $c = $hash->{CD}; + print $c "HTTP/1.1 200 OK\r\n", + "Content-Type: text/plain\r\n", + "Content-Length: ".length($response)."\r\n\r\n", + $response; + + + ## hier den close Client einbauen auf hash vom Accept $chash siehe oben + ## close($hash->{CD}) + + + + ### + ## Consume Content + ### + + my @data = split( '\R\R', $buf ); + + if ( $data[0] =~ /FHEMCMD: setreading\b/ ) { + my $tv = $data[1]; + + @data = split( '\R', $data[0] ); + $data[2] =~ s/FHEMDEVICE: //; + my $chash = $defs{$data[2]}; + ### Begin Response Processing + + my @valuestring = split( '@@@@', $tv ); + my %buffer; + + foreach( @valuestring ) { + my @values = split( '@@' , $_ ); + $buffer{$values[0]} = $values[1]; + } + + my $t; + my $v; + while( ( $t, $v ) = each %buffer ) { + $v =~ s/null//g; + + readingsBeginUpdate( $chash ); + readingsBulkUpdate( $chash, $t, $v ) if( defined( $v ) ); + } + + readingsBulkUpdate( $chash, "lastStatusRequestState", "statusRequest_done" ); + readingsEndUpdate( $chash, 1 ); + ### End Response Processing + + return; + } + + elsif ( $data[0] =~ /FHEMCMD: set\b/ ) { + my $fhemCmd = $data[1]; + + fhem ("$fhemCmd") if( ReadingsVal( "AMADCommBridge", "expertMode", 0 ) eq "1" ); + readingsSingleUpdate( $brihash, "receiveFhemCommand", $fhemCmd, 1 ); + + return; + } + + elsif ( $data[0] =~ /FHEMCMD: statusrequest\b/ ) { + + @data = split( '\R', $data[0] ); + $data[2] =~ s/FHEMDEVICE: //; + my $chash = $defs{$data[2]}; + + return AMAD_GetUpdateLocal( $chash ); + } +} + 1; @@ -799,9 +977,12 @@ sub AMAD_SelectSetCmd($$@) {

With this module it is also possible to control an Android device as follows.
    -
  • State of the device (nnline, offline)
  • +
  • Switch Bluetooth on/off
  • +
  • Set or change the connection to a specific Bluetooth device
  • +
  • State of the device (online, offline)
  • Media Player control ( play / stop / next track / previous track)
  • Set next alarm time
  • +
  • Play a notification sound
  • Open an app on the device
  • Open a URL in the browser on the device
  • Set Screen on/off
  • @@ -844,14 +1025,25 @@ sub AMAD_SelectSetCmd($$@) {


Done! After connecting the device instance should already come in the first Readings within 3 minutes. +


+ + AMAD Communication Bridge +
    + When you define the first AMAD device instance another device named AMADCommBridge will also be defined. Its room attribute is AMAD.YOU SHOULD NEVER CHANGE THIS NAME. Feel free to change all other properties. You need this device for the communication fom the Andoid unit to FHEM without having received any query from FHEM. The Android unit must know the IP address of FHEM, so you must enter the set command for the corresponding reading immediately after the definition of the bridge. This is extremly important to get the functionality working properly! + The command is + set AMADCommBridge fhemServerIP . + There is another reading expertMode which allows a direct communication with FHEM without haviung to use a notify or being limited to set commands. +


Readings
  • automagic state - status messages from the AutomagicApp
  • bluetooth on / off - is Bluetooth switched on or off on the device
  • +
  • checkActiveTask - state of an app being defined before, 1=activ in the foreground, see the hint further down
  • connectedBTdevices - a list of the connected devices
  • -
  • current Music Album - currently abgespieltes Music Album of the media player used
  • +
  • connectedBTdevicesMAC – list f the MAC addresses of all connected BT devices
  • +
  • current Music Album - currently played music album of the media player used
  • current music artist - currently played music artist of the media player used
  • current Music Track - currently played music title of the media player used
  • deviceState - State of the Android device, must itself be set with setreading e.g. about the attendance check. When offline is set, the interval is set off for information retrieval.
  • @@ -874,7 +1066,43 @@ sub AMAD_SelectSetCmd($$@) {
  • volume music speaker - Media volume of the internal speakers

  • The Readings volume Music Bluetooth and music speaker volume reflect the respective media volume of the closed border is Bluetooth speakers or the internal speaker again. - Unless one the respective volumes relies exclusively on the Set command, one of the two will always agree with the "volume" Reading a. + Unless one the respective volumes relies exclusively on the Set command, one of the two will always agree with the "volume" Reading a.

    + Before using the Reading checkActivTask you must set the nme of the package name of te app to be checked innthe attribute checkActiveTask. Eample: + attr Nexus10Wohnzimmer checkActiveTask com.android.chrome for the Chrome browser. +


+ Define user specific Readings in the AMAD device +
    + You can specify your own reaqdings in the AMAD device and use them in combination with your Automagic flow. The transmission takes place immediately by means of the AMADCommBridge - so you should not update it too often. This is how you can do it: +
      +
      +
    • first you need to define an Automagic flow for the information for the reading
    • +
    • diese Information speichert man nun mittels Automagic Action Script in eine globale Variable namens global_reading_ (beim auf Groß- und Kleinschreibung achten):
    • +
      + + this information needs to be stored with the help of an Automagic action in a global variable (case sensitiv!). Example: + The Reading Touch should get the value "yes" + Action Script: global_reading_Touch="yes" + +

      +
    • abschließend muss noch die Übertragung des Wertes initiiert werden. Dies erfolgt, indem der Wert der Variable global_own_reading auf den Wert _ gesetzt wird (auch hier auf Groß- und Kleinschreibung achten):
    • +
      + + Finally you need to trigger the transmission of the value. This is dne by setting the the value of the variable global_own_reading to _ gesetzt wird (again: case sensitiv!): + Example: The Reading Touch should be transfered
      + Action Script: global_own_reading="{getDate()}_Touch"
      + Hint: you can put both actions in one script: +
        + global_reading_Touch="ja";global_own_reading="{getDate()}_Touch" +
      +
      +
      +
    • Asume you want to get an immediate information when the display of your tablet has been switched on or off then you can define the following flows: +
      + + Action Script when the display is activated: global_reading_Display="on";global_own_reading="{getDate()}_Display" + Action Script when the display is deactivated: global_reading_Display="off";global_own_reading="{getDate()}_Display"
    • + +


@@ -883,6 +1111,7 @@ sub AMAD_SelectSetCmd($$@) {
  • Device State - sets the Device Status Online / Offline. See Readings
  • Media Player - controls the default media player. Play, Stop, Back Route title, ahead of title.
  • NextAlarm time - sets the alarm time. only within the next 24hrs.
  • +
  • notifySndFile - plays the specified media file on the Android device. The file to be played must be in the folder /storage/emulated/0/Notifications/.
  • openURL - opens a URL in your default browser
  • screen - are sets the screen on / off with barrier in the car Magic settings must "Admin Function" set will not work "Screen off".
  • screenMsg - sends a message screen
  • @@ -893,6 +1122,7 @@ sub AMAD_SelectSetCmd($$@) {
    Set depending on set attributes
      +
    • changetoBtDevice - changes to another Bluetooth device. The attribute setBluetoothDevice must be set. See hint below!
    • mediaPlayer - controls the default media player. Play, Stop, Back Route title, ahead of title. Attribute fhemServerIP
    • openapp - opens a selected app. Attribute setOpenApp
    • screen Brightness - sets the screen brightness, 0-255 Attribute setScreenBrightness
    • @@ -900,7 +1130,11 @@ sub AMAD_SelectSetCmd($$@) {
    • screen fullscreen - Switches to full screen mode on / off. Attribute SetFullscreen
    • screenOrientation - Switches the screen orientation Auto / Landscape / Portrait. Attribute setScreenOrientation
    • system - set system commands from (only rooted devices). Reboot Attribut root, in the Auto Magic Settings "root function" must be set
    • - In order to use openApp you need an attribute where separated by a comma, several app names are set in order to use openapp. The app name is arbitrary and only required for recognition. The same app name must be used in the flow in SetCommands on the left below the hash expression: "openapp" be in one of the 5 paths (one app per path) entered in both diamonds. Thereafter, in the quadrangle selected the app which app through the attribute names should be started. + In order to use openApp you need an attribute where separated by a comma, several app names are set in order to use openapp. The app name is arbitrary and only required for recognition. The same app name must be used in the flow in SetCommands on the left below the hash expression: "openapp" be in one of the 5 paths (one app per path) entered in both diamonds. Thereafter, in the quadrangle selected the app which app through the attribute names should be started.

      + To switch between different Bluetooth devices, you need set the attribute setBluetoothDevice accordingly. + attr BTdeviceName1|MAC,BTDeviceName2|MAC + There may never be a sapce in BTdeviceName. There must also be the colon(:) in the MAC address after every second sign! + Example: attr Nexus10Wohnzimmer setBluetoothDevice Logitech_BT_Adapter|AB:12:CD:34:EF:32,Anker_A3565|GH:56:IJ:78:KL:76


    @@ -934,11 +1168,12 @@ sub AMAD_SelectSetCmd($$@) {
    Dieses Modul liefert, in Verbindung mit der Android APP Automagic, diverse Informationen von Android Geräten. Die AndroidAPP Automagic (welche nicht von mir stammt und 2.90Euro kostet) funktioniert wie Tasker, ist aber bei weitem User freundlicher. - Im Auslieferiungszustand werden folgende Zustände dargestellt: + Im Auslieferungszustand werden folgende Zustände dargestellt:
    • Zustand von Automagic auf dem Gerät
    • Bluetooth An/Aus
    • -
    • verbundene Bluetoothgeräte
    • +
    • Zustand einer definierten App (läuft aktiv im Vordergrund oder nicht?)
    • +
    • verbundene Bluetoothgeräte, inklusive deren MAC Adresse
    • aktuell abgespieltes Musikalbum des verwendeten Mediaplayers
    • aktuell abgespielter Musikinterpret des verwendeten Mediaplayers
    • aktuell abgespielter Musiktitel des verwendeten Mediaplayers
    • @@ -961,9 +1196,12 @@ sub AMAD_SelectSetCmd($$@) {

      Das Modul gibt Dir auch die Möglichkeit Deine Androidgeräte zu steuern. So können folgende Aktionen durchgeführt werden.
        +
      • Bluetooth Ein/Aus schalten
      • +
      • zu einem bestimmten Bluetoothgerät wechseln/verbinden
      • Status des Gerätes (Online,Offline)
      • Mediaplayer steuern (Play, Stop, nächster Titel, vorheriger Titel)
      • nächste Alarmzeit setzen
      • +
      • ein Benachrichtigungston abspielen (Notificationsound)
      • eine App auf dem Gerät öffnen
      • eine URL im Browser öffnen
      • Bildschirm An/Aus machen
      • @@ -998,20 +1236,34 @@ sub AMAD_SelectSetCmd($$@) { define WandTabletWohnzimmer AMAD 192.168.0.23

      - Diese Anweisung erstellt ein neues AMAD-Device. Der Parameter <IP-ADRESSE< legt die IP Adresse des Android Gerätes fest.
      + Diese Anweisung erstellt ein neues AMAD-Device im Raum AMAD.Der Parameter <IP-ADRESSE< legt die IP Adresse des Android Gerätes fest.
      Das Standard Abfrageinterval ist 180 Sekunden und kann über das Attribut intervall geändert werden. Wer den Port ändern möchte, kann dies über das Attribut port tun. Ihr solltet aber wissen was Ihr tut, da dieser Port im HTTP Response Trigger der beiden Flows eingestellt ist. Demzufolge muß dieser dort auch verädert werden.


    Fertig! Nach anlegen der Geräteinstanz sollten nach spätestens 3 Minuten bereits die ersten Readings reinkommen. +


    + + AMAD Communication Bridge +
      + Beim ersten anlegen einer AMAD Deviceinstanz wird automatisch ein Gerät Namens AMADCommBridge im Raum AMAD angelegt. BITTE NIEMALS DEN NAMEN DER BRIDGE ÄNDERN!!! + Alle anderen Eigenschaften können geändert werden. Dieses Gerät diehnt zur Kommunikation + vom Androidgerät zu FHEM ohne das zuvor eine Anfrage von FHEM aus ging. Damit das Androidgerät die IP von FHEM kennt, muss diese sofort nach dem anlegen der Bridge + über den set Befehl in ein entsprechendes Reading in die Bridge geschrieben werden. DAS IST SUPER WICHTIG UND FÜR DIE FUNKTION DER BRIDGE NOTWENDIG.
      + Bitte führt hierzu folgenden Befehl aus. set AMADCommBridge fhemServerIP <FHEM-IP>.
      + Als zweites Reading könnt Ihr expertModesetzen. Mit diesem Reading wird eine unmittelbare Komminikation mit FHEM erreicht ohne die Einschränkung über ein + Notify gehen zu müssen und nur reine set Befehle ausführen zu können. +


    Readings
      -
    • automagicState - Statusmeldungen von der AutomagicApp
    • +
    • automagicState - Statusmeldungen von der AutomagicApp (Voraussetzung Android >4.3). Wer ein Android >4.3 hat und im Reading steht "wird nicht unterstützt", muß in den Androideinstellungen unter Ton und Benachrichtigungen -> Benachrichtigungszugriff ein Haken setzen für Automagic
    • bluetooth on/off - ist auf dem Gerät Bluetooth an oder aus
    • -
    • connectedBTdevices - eine Lieste der verbundenen Gerät
    • +
    • checkActiveTask - Zustand einer zuvor definierten APP. 0=nicht aktiv oder nicht aktiv im Vordergrund, 1=aktiv im Vordergrund, siehe Hinweis unten
    • +
    • connectedBTdevices - eine Liste der verbundenen Gerät
    • +
    • connectedBTdevicesMAC - eine Liste der MAC Adressen aller verbundender BT Geräte
    • currentMusicAlbum - aktuell abgespieltes Musikalbum des verwendeten Mediaplayers
    • currentMusicArtist - aktuell abgespielter Musikinterpret des verwendeten Mediaplayers
    • currentMusicTrack - aktuell abgespielter Musiktitel des verwendeten Mediaplayers
    • @@ -1035,16 +1287,54 @@ sub AMAD_SelectSetCmd($$@) {
    • volumeMusikBluetooth - Media Lautstärke von angeschlossenden Bluetooth Lautsprechern
    • volumeMusikSpeaker - Media Lautstärke der internen Lautsprecher

    • - Die Readings volumeMusikBluetooth und volumeMusikSpeaker spiegeln die jeweilige Medialautstärke der angeschlossenden Bluetoothlautsprechern oder der internen Lautsprecher wieder.
      + Die Readings volumeMusikBluetooth und volumeMusikSpeaker spiegeln die jeweilige Medialautstärke der angeschlossenden Bluetoothlautsprecher oder der internen Lautsprecher wieder. Sofern man die jeweiligen Lautstärken ausschließlich über den Set Befehl setzt, wird eine der beiden immer mit dem "volume" Reading über ein stimmen.

      + Beim Reading checkActivTask muß zuvor der Packagename der zu prüfenden App als Attribut checkActiveTask angegeben werden. Beispiel: attr Nexus10Wohnzimmer + checkActiveTask com.android.chrome für den Chrome Browser. +

      +
    + Eigene Readings im AMAD-Device erstellen +
      + Es ist möglich, aus beliebigen eigenen Automagic-Flows eigene Readings im AMAD-Device zu erstellen und zu füllen. Die Übertragung zum FHEM AMAD-Device erfolgt umgehend über die AMADCommBridge - daher sollte auf eine zu häufige Aktualisierung verzichtet werden. Die Vorgehensweise in Automagic hierfür ist folgende: +
        +
        +
      • zunächst erstellt man sich, soweit nicht bereits geschehen, einen Automagic-Flow der die Information, die in ein Reading übernommen werden soll zur Verfügung stellt
      • +
      • diese Information speichert man nun mittels Automagic Action Script in eine globale Variable namens global_reading_ (beim auf Groß- und Kleinschreibung achten):
      • +
        + + Beispiel: Das Reading Touch soll den Wert "ja" erhalten + Action Script: global_reading_Touch="ja" + +

        +
      • abschließend muss noch die Übertragung des Wertes initiiert werden. Dies erfolgt, indem der Wert der Variable global_own_reading auf den Wert _ gesetzt wird (auch hier auf Groß- und Kleinschreibung achten):
      • +
        + + Beispiel: Das Reading Touch soll übertragen werden
        + Action Script: global_own_reading="{getDate()}_Touch"
        + Hinweis: man kann auch beide Aktionen in ein Script packen: +
          + global_reading_Touch="ja";global_own_reading="{getDate()}_Touch" +
        +
        +
        +
      • Möchte man nun als nächstes z.B. eine sofortige Benachrichtigung, wenn das Display des Tablets an- oder ausgeschaltet wird, könnte man sich Flows bauen, welche beim De-/Aktivieren des Display ausgeführt werden:
      • +
        + + Action Script beim Aktivieren des Displays: global_reading_Display="an";global_own_reading="{getDate()}_Display" + Action Script beim Deaktivieren des Displays: global_reading_Display="aus";global_own_reading="{getDate()}_Display" + +


    Set
      +
    • bluetooth - Schaltet Bluetooth on/off
    • +
    • clearNotificationBar - (All,Automagic) löscht alle Meldungen oder nur die Automagic Meldungen in der Statusleiste
    • deviceState - setzt den Device Status Online/Offline. Siehe Readings
    • mediaPlayer - steuert den Standard Mediaplayer. play, stop, Titel zürück, Titel vor.
    • nextAlarmTime - setzt die Alarmzeit. Geht aber nur innerhalb der nächsten 24Std.
    • +
    • notifySndFile - spielt die angegebende Mediadatei auf dem Androidgerät ab. Die aufzurufende Mediadatei muß sich im Ordner /storage/emulated/0/Notifications/ befinden.
    • openURL - öffnet eine URL im Standardbrowser
    • screen - setzt den Bildschirm on/off mit Sperre, in den Automagic Einstellungen muss "Admin Funktion" gesetzt werden sonst funktioniert "Screen off" nicht.
    • screenMsg - versendet eine Bildschirmnachricht
    • @@ -1055,6 +1345,7 @@ sub AMAD_SelectSetCmd($$@) {
      Set abhängig von gesetzten Attributen
        +
      • changetoBtDevice - wechselt zu einem anderen Bluetooth Gerät. Attribut setBluetoothDevice muß gesetzt sein. Siehe Hinweis unten!
      • mediaPlayer - steuert den Standard Mediaplayer. play, stop, Titel zürück, Titel vor. Attribut fhemServerIP
      • openApp - öffnet eine ausgewählte App. Attribut setOpenApp
      • screenBrightness - setzt die Bildschirmhelligkeit, von 0-255 Attribut setScreenBrightness
      • @@ -1063,10 +1354,14 @@ sub AMAD_SelectSetCmd($$@) {
      • screenFullscreen - Schaltet den Vollbildmodus on/off. Attribut setFullscreen
      • screenOrientation - Schaltet die Bildschirmausrichtung Auto/Landscape/Portait. Attribut setScreenOrientation
      • system - setzt Systembefehle ab (nur bei gerootetet Geräen). Reboot Attribut root, in den Automagic Einstellungen muss "Root Funktion" gesetzt werden
      • +
        Um openApp verwenden zu können, muss als Attribut ein, oder durch Komma getrennt, mehrere App Namen gesetzt werden. Der App Name ist frei wählbar und nur zur Wiedererkennung notwendig. Der selbe App Name muß im Flow SetCommands auf der linken Seite unterhalb der Raute Expression:"openApp" in einen der 5 Stränge (eine App pro Strang) in beide Rauten eingetragen werden. Danach wird - in das - Viereck die App ausgewält welche durch den Attribut App Namen gestartet werden soll. + in das Viereck die App ausgewält welche durch den Attribut App Namen gestartet werden soll.

        + Um zwischen Bluetoothgeräten wechseln zu können, muß das Attribut setBluetoothDevice mit folgender Syntax gesetzt werden. attr <DEVICE> BTdeviceName1|MAC,BTDeviceName2|MAC Es muss + zwingend darauf geachtet werden das beim BTdeviceName kein Leerzeichen vorhanden ist. Am besten zusammen oder mit Unterstrich. Achtet bei der MAC darauf das Ihr wirklich nach jeder zweiten Zahl auch + einen : drin habt
        + Beispiel: attr Nexus10Wohnzimmer setBluetoothDevice Logitech_BT_Adapter|AB:12:CD:34:EF:32,Anker_A3565|GH:56:IJ:78:KL:76


      @@ -1090,8 +1385,10 @@ sub AMAD_SelectSetCmd($$@) { Der größte Dank geht an meinen Mentor Andre (justme1968), er hat mir mit hilfreichen Tips geholfen Perlcode zu verstehen und Spaß am programmieren zu haben.
      Auch möchte ich mich bei Jens bedanken (jensb) welcher mir ebenfalls mit hilfreichen Tips bei meinen aller ersten Gehversuchen beim Perlcode schreiben unterstützt hat.
      So und nun noch ein besonderer Dank an pah (Prof. Dr. Peter Henning ), ohne seine Aussage "Keine Ahnung hatten wir alle mal, das ist keine Ausrede" hätte ich bestimmt nicht angefangen Interesse an - Modulentwicklung zu zeigen :-) + Modulentwicklung zu zeigen :-)
      + Danke an Jürgen(ujaudio) der sich um die Übersetzung der Commandref ins Englische gekümmert hat und hoffentlich weiter kümmern wird :-)
      + Danke auch an Ronny(RoBra81) für seine tolle Idee und Umsetzung von eigenen AMAD Readings aus externen Flows.
    =end html_DE -=cut \ No newline at end of file +=cut