From f43790cdfe64d60602afc799e458986942870519 Mon Sep 17 00:00:00 2001 From: markooldenburg <> Date: Thu, 10 Sep 2015 08:16:54 +0000 Subject: [PATCH] feature: new Module 74_AMAD to request Information and control Android Devices in cooperation with AutomagicApp on the Device (Forum #39773) (by M. Oldenburg) git-svn-id: https://svn.fhem.de/fhem/trunk@9221 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 3 + fhem/FHEM/74_AMAD.pm | 919 +++++++++++++++++++ fhem/FHEM/lib/74_AMADautomagicFlows0.6.0.xml | 902 ++++++++++++++++++ 3 files changed, 1824 insertions(+) create mode 100644 fhem/FHEM/74_AMAD.pm create mode 100644 fhem/FHEM/lib/74_AMADautomagicFlows0.6.0.xml diff --git a/fhem/CHANGED b/fhem/CHANGED index e77d96155..be8de0ea2 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # 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. + - feature: new Module 74_AMAD to request Information and control Android Devices + in cooperation with AutomagicApp on the Device (Forum #39773) + (by M. Oldenburg) - bugfix: 70_PushNotifier.pm: regex error handling - bugfix: 31_MilightDevice.pm: fixed bug that lead to crash on lost bridge connection, added module name prefix to round function - bugfix: 38_CO20.pm: removed unneccesary error messages due to USB timeout diff --git a/fhem/FHEM/74_AMAD.pm b/fhem/FHEM/74_AMAD.pm new file mode 100644 index 000000000..d732e5959 --- /dev/null +++ b/fhem/FHEM/74_AMAD.pm @@ -0,0 +1,919 @@ +################################################################ +# +# Developed with Kate +# +# (c) 2015 Copyright: Marko Oldenburg (leongaultier at gmail dot com) +# All rights reserved +# +# This script 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 +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script 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. +# +################################################################ + + + + +package main; + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday); + +use HttpUtils; + +my $version = "0.6.0"; + + + +sub AMAD_Initialize($) { + + my ($hash) = @_; + + $hash->{SetFn} = "AMAD_Set"; + $hash->{DefFn} = "AMAD_Define"; + $hash->{UndefFn} = "AMAD_Undef"; + $hash->{AttrFn} = "AMAD_Attr"; + $hash->{ReadFn} = "AMAD_Read"; + $hash->{AttrList} = "setOpenApp ". + "setFullscreen:0,1 ". + "setScreenOrientation:0,1 ". + "setScreenBrightness:0,1 ". + "fhemServerIP ". + "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; + } +} + +sub AMAD_Define($$) { + +my ( $hash, $def ) = @_; + my @a = split( "[ \t][ \t]*", $def ); + + return "too few parameters: define AMAD " if ( @a != 3 ); + + + my $name = $a[0]; + my $host = $a[2]; + my $port = 8090; + my $interval = 180; + + $hash->{HOST} = $host; + $hash->{PORT} = $port; + $hash->{INTERVAL} = $interval; + $hash->{VERSION} = $version; + $hash->{helper}{infoErrorCounter} = 0; + $hash->{helper}{setCmdErrorCounter} = 0; + + Log3 $name, 3, "AMAD ($name) - defined with host $hash->{HOST} on port $hash->{HOST} and interval $hash->{INTERVAL} (sec)"; + + AMAD_GetUpdateLocal( $hash ); + + InternalTimer( gettimeofday()+$hash->{INTERVAL}, "AMAD_GetUpdateTimer", $hash, 0 ); + + $hash->{STATE} = "initialized"; + readingsSingleUpdate ( $hash, "deviceState", "online", 0 ); + + return undef; +} + +sub AMAD_Undef($$) { + +my ( $hash, $arg ) = @_; + + RemoveInternalTimer( $hash ); + + return undef; +} + +sub AMAD_Attr(@) { + +my ( $cmd, $name, $attrName, $attrVal ) = @_; + my $hash = $defs{$name}; + + if( $attrName eq "disable" ) { + if( $cmd eq "set" ) { + if( $attrVal eq "0" ) { + RemoveInternalTimer( $hash ); + InternalTimer( gettimeofday()+2, "AMAD_GetUpdateTimer", $hash, 0 ) if( $hash->{STATE} eq "disabled" ); + $hash->{STATE}='active'; + Log3 $name, 3, "AMAD ($name) - enabled"; + } else { + $hash->{STATE} = 'disabled'; + RemoveInternalTimer( $hash ); + Log3 $name, 3, "AMAD ($name) - disabled"; + } + } + elsif( $cmd eq "del" ) { + RemoveInternalTimer( $hash ); + InternalTimer( gettimeofday()+2, "AMAD_GetUpdateTimer", $hash, 0 ) if( $hash->{STATE} eq "disabled" ); + $hash->{STATE}='active'; + Log3 $name, 3, "AMAD ($name) - enabled"; + + } else { + if($cmd eq "set") { + $attr{$name}{$attrName} = $attrVal; + Log3 $name, 3, "AMAD ($name) - $attrName : $attrVal"; + } + elsif( $cmd eq "del" ) { + } + } + } + + if( $attrName eq "interval" ) { + if( $cmd eq "set" ) { + if( $attrVal < 60 ) { + Log3 $name, 3, "AMAD ($name) - interval too small, please use something > 60 (sec), default is 180 (sec)"; + return "interval too small, please use something > 60 (sec), default is 180 (sec)"; + } else { + $hash->{INTERVAL} = $attrVal; + Log3 $name, 3, "AMAD ($name) - set interval to $attrVal"; + } + } + elsif( $cmd eq "del" ) { + $hash->{INTERVAL} = 180; + Log3 $name, 3, "AMAD ($name) - set interval to default"; + + } else { + if( $cmd eq "set" ) { + $attr{$name}{$attrName} = $attrVal; + Log3 $name, 3, "AMAD ($name) - $attrName : $attrVal"; + } + elsif( $cmd eq "del" ) { + } + } + } + + if( $attrName eq "port" ) { + if( $cmd eq "set" ) { + $hash->{PORT} = $attrVal; + Log3 $name, 3, "AMAD ($name) - set port to $attrVal"; + } + elsif( $cmd eq "del" ) { + $hash->{PORT} = 8090; + Log3 $name, 3, "AMAD ($name) - set port to default"; + + } else { + if( $cmd eq "set" ) { + $attr{$name}{$attrName} = $attrVal; + Log3 $name, 3, "AMAD ($name) - $attrName : $attrVal"; + } + elsif( $cmd eq "del" ) { + } + } + } + + return undef; +} + +sub AMAD_GetUpdateLocal($) { + +my ( $hash ) = @_; + my $name = $hash->{NAME}; + + AMAD_RetrieveAutomagicInfo( $hash ) if( ReadingsVal( $name, "deviceState", "online" ) eq "online" && $hash->{STATE} ne "initialized" && AttrVal( $name, "disable", 0 ) ne "1" ); ### deviceState muß von Hand online/offline gesetzt werden z.B. über RESIDENZ Modul + + return 1; +} + +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. über RESIDENZ Modul + + InternalTimer( gettimeofday()+$hash->{INTERVAL}, "AMAD_GetUpdateTimer", $hash, 1 ); + Log3 $name, 4, "AMAD ($name) - Call 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( $hash->{STATE} 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 $url = "http://" . $host . ":" . $port . "/fhem-amad/deviceInfo/"; # Path muß so im Automagic als http request Trigger drin stehen + + HttpUtils_NonblockingGet( + { + url => $url, + timeout => 5, + hash => $hash, + method => "GET", + header => "fhemIP: $fhemip\r\nfhemDevice: $name", + doTrigger => 1, + callback => \&AMAD_RetrieveAutomagicInfoFinished, + } + ); + Log3 $name, 4, "AMAD ($name) - NonblockingGet get URL"; + Log3 $name, 4, "AMAD ($name) - AMAD_RetrieveAutomagicInfo: calling Host: $host"; +} + +sub AMAD_RetrieveAutomagicInfoFinished($$$) { + + my ( $param, $err, $data ) = @_; + my $hash = $param->{hash}; + my $doTrigger = $param->{doTrigger}; + my $name = $hash->{NAME}; + my $host = $hash->{HOST}; + + Log3 $name, 4, "AMAD ($name) - AMAD_RetrieveAutomagicInfoFinished: processed request data"; + + + + ### Begin Error Handling + if( $hash->{helper}{infoErrorCounter} > 2 ) { + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "lastStatusRequestState", "statusRequest_error" ); + + if( ReadingsVal( $name, "flow_Informations", "active" ) eq "inactive" && ReadingsVal( $name, "flow_SetCommands", "active" ) eq "inactive" ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "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"; + } + elsif( $hash->{helper}{infoErrorCounter} > 9 && $hash->{helper}{setCmdErrorCounter} > 4 ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "unknown error, please contact the developer" ); + + Log3 $name, 4, "AMAD ($name) - UNKNOWN ERROR, PLEASE CONTACT THE DEVELOPER, DEVICE DISABLED"; + + $attr{$name}{disable} = 1; + $hash->{STATE} = "Unknown Error, device disabled"; + $hash->{helper}{infoErrorCounter} = 0; + $hash->{helper}{setCmdErrorCounter} = 0; + + return; + } + elsif( ReadingsVal( $name, "flow_Informations", "active" ) eq "inactive" ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "informations flow on your device is inactive, will try to reactivate" ); + + Log3 $name, 4, "AMAD ($name) - Informations Flow on your Device is inactive, will try to reactivate"; + } + elsif($hash->{helper}{infoErrorCounter} > 4 && ReadingsVal( $name, "flow_Informations", "active" ) eq "active" ){ + readingsBulkUpdate( $hash, "lastStatusRequestError", "check automagicApp on your device" ); + + Log3 $name, 4, "AMAD ($name) - Please check the AutomagicAPP on your Device"; + } + elsif( $hash->{helper}{infoErrorCounter} > 9 ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "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"; + $hash->{helper}{infoErrorCounter} = 0; + } + readingsEndUpdate( $hash, 1 ); + } + + if( defined( $err ) ) { + if( $err ne "" ) { + $hash->{STATE} = $err if( $hash->{STATE} ne "initialized" ); + $hash->{helper}{infoErrorCounter} = ( $hash->{helper}{infoErrorCounter} + 1 ); + + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "lastStatusRequestState", "statusRequest_error" ); + + if( $err =~ /timed out/ ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "connect to your device is timed out. check network "); + } + elsif( ( $err =~ /Keine Route zum Zielrechner/ ) && $hash->{helper}{infoErrorCounter} > 1 ) { + readingsBulkUpdate( $hash,"lastStatusRequestError", "no route to target. bad network configuration or network is down "); + } else { + readingsBulkUpdate($hash, "lastStatusRequestError", "$err" ); + } + + readingsEndUpdate( $hash, 1 ); + + Log3 $name, 4, "AMAD ($name) - AMAD_RetrieveAutomagicInfoFinished: error while requesting AutomagicInfo: $err"; + return; + } + } + + if( $data eq "" and exists( $param->{code} ) ) { + $hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); + $hash->{helper}{infoErrorCounter} = ( $hash->{helper}{infoErrorCounter} + 1 ); + + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "lastStatusRequestState", "statusRequest_error" ); + + if( $param->{code} ne 200 ) { + readingsBulkUpdate( $hash," lastStatusRequestError", "http Error ".$param->{code} ); + } + + readingsBulkUpdate( $hash, "lastStatusRequestError", "empty response, check automagicApp on your device" ); + readingsEndUpdate( $hash, 1 ); + + Log3 $name, 4, "AMAD ($name) - AMAD_RetrieveAutomagicInfoFinished: received http code ".$param->{code}." without any data after requesting AMAD AutomagicInfo"; + + return; + } + + if( ( $data =~ /Error/i ) and exists( $param->{code} ) ) { + $hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); + $hash->{helper}{infoErrorCounter} = ( $hash->{helper}{infoErrorCounter} + 1 ); + + readingsBeginUpdate( $hash ); + readingsBulkUpdate( $hash, "lastStatusRequestState", "statusRequest_error" ); + + if( $param->{code} eq 404 && ReadingsVal( $name, "flow_Informations", "inactive" ) eq "inactive" ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "check the informations flow on your device" ); + } + elsif( $param->{code} eq 404 && ReadingsVal( $name, "flow_Informations", "active" ) eq "active" ) { + readingsBulkUpdate( $hash, "lastStatusRequestError", "check the automagicApp on your device" ); + } else { + readingsBulkUpdate( $hash, "lastStatusRequestError", "http error ".$param->{code} ); + } + + readingsEndUpdate( $hash, 1 ); + + Log3 $name, 4, "AMAD ($name) - AMAD_RetrieveAutomagicInfoFinished: received http code ".$param->{code}." receive Error after requesting AMAD AutomagicInfo"; + + return; + } + + ### End Error Handling + + $hash->{helper}{infoErrorCounter} = 0; + + ### Begin Response Processing + $hash->{STATE} = "active" if( $hash->{STATE} eq "initialized" || $hash->{STATE} ne "active" ); + + my @valuestring = split( '@@@@', $data ); + my %buffer; + foreach( @valuestring ) { + my @values = split( '@@' , $_ ); + $buffer{$values[0]} = $values[1]; + } + + + readingsBeginUpdate( $hash ); + + my $t; + my $v; + while( ( $t, $v ) = each %buffer ) { + $v =~ s/null//g; + readingsBulkUpdate( $hash, $t, $v ) if( defined( $v ) ); + } + + readingsBulkUpdate( $hash, "lastStatusRequestState", "statusRequest_done" ); + + readingsEndUpdate( $hash, 1 ); + + $hash->{helper}{infoErrorCounter} = 0; + ### End Response Processing + + $hash->{STATE} = "active" if( $hash->{STATE} eq "initialized" ); + + return undef; +} + +sub AMAD_HTTP_POST($$) { + + my ( $hash, $url ) = @_; + my $name = $hash->{NAME}; + + my $state = $hash->{STATE}; + + $hash->{STATE} = "Send HTTP POST"; + + HttpUtils_NonblockingGet( + { + url => $url, + timeout => 5, + hash => $hash, + method => "POST", + doTrigger => 1, + callback => \&AMAD_HTTP_POSTerrorHandling, + } + ); + Log3 $name, 4, "AMAD ($name) - Send HTTP POST with URL $url"; + + $hash->{STATE} = $state; + + 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" ); + $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; + $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" ); + $hash->{STATE} = "To many Errors, device set offline"; + $hash->{helper}{setCmdErrorCounter} = 0; + } + readingsEndUpdate( $hash, 1 ); + } + + if( defined( $err ) ) { + if( $err ne "" ) { + $hash->{STATE} = $err if( $hash->{STATE} ne "initialized" ); + $hash->{helper}{setCmdErrorCounter} = ($hash->{helper}{setCmdErrorCounter} + 1); + + readingsBeginUpdate( $hash ); + 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 ) { + $hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); + $hash->{helper}{setCmdErrorCounter} = ( $hash->{helper}{setCmdErrorCounter} + 1 ); + + readingsBeginUpdate( $hash ); + 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} ) ) { + $hash->{STATE} = $param->{code} if( $hash->{STATE} ne "initialized" ); + $hash->{helper}{setCmdErrorCounter} = ( $hash->{helper}{setCmdErrorCounter} + 1 ); + + readingsBeginUpdate( $hash ); + 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($$@) { + + my ( $hash, $cmd, @data ) = @_; + my $name = $hash->{NAME}; + my $host = $hash->{HOST}; + my $port = $hash->{PORT}; + + if( lc $cmd eq 'screenmsg' ) { + my $msg = join( " ", @data ); + + $msg =~ s/%/%25/g; + $msg =~ s/\s/%20/g; + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/screenMsg?message=$msg"; + Log3 $name, 4, "AMAD ($name) - Sub AMAD_SetScreenMsg"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'ttsmsg' ) { + my $msg = join( " ", @data ); + + $msg =~ s/%/%25/g; + $msg =~ s/\s/%20/g; + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/ttsMsg?message=$msg"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'volume' ) { + my $vol = join( " ", @data ); + + 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 ); + } + + elsif( lc $cmd eq 'mediaplayer' ) { + my $btn = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/mediaPlayer?button=$btn"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'devicestate' ) { + my $v = join( " ", @data ); + + readingsSingleUpdate( $hash, $cmd, $v, 1 ); + + return undef; + } + + elsif( lc $cmd eq 'screenbrightness' ) { + 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 ); + } + + elsif( lc $cmd eq 'screen' ) { + my $mod = join( " ", @data ); + + 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 ); + } + + elsif( lc $cmd eq 'screenorientation' ) { + 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 ); + } + + elsif( lc $cmd eq 'screenfullscreen' ) { + my $mod = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/setScreenFullscreen?fullscreen=$mod"; + + readingsSingleUpdate( $hash, $cmd, $mod, 1 ); + + return AMAD_HTTP_POST( $hash, $url ); + } + + elsif( lc $cmd eq 'openurl' ) { + my $openurl = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/openURL?url=$openurl"; + + return AMAD_HTTP_POST( $hash, $url ); + } + + elsif (lc $cmd eq 'nextalarmtime') { + my $alarmTime = join( " ", @data ); + 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 ); + } + + elsif( lc $cmd eq 'statusrequest' ) { + AMAD_GetUpdateLocal( $hash ); + return undef; + } + + elsif( lc $cmd eq 'openapp' ) { + my $app = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/openApp?app=$app"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + elsif( lc $cmd eq 'system' ) { + my $systemcmd = join( " ", @data ); + + my $url = "http://" . $host . ":" . $port . "/fhem-amad/setCommands/systemcommand?syscmd=$systemcmd"; + + return AMAD_HTTP_POST( $hash,$url ); + } + + return undef; +} + + +1; + + +=pod +=begin html + + +

AMAD

+ + +=end html +=begin html_DE + + +

AMAD

+ + +=end html_DE +=cut \ No newline at end of file diff --git a/fhem/FHEM/lib/74_AMADautomagicFlows0.6.0.xml b/fhem/FHEM/lib/74_AMADautomagicFlows0.6.0.xml new file mode 100644 index 000000000..0dfa0f2b6 --- /dev/null +++ b/fhem/FHEM/lib/74_AMADautomagicFlows0.6.0.xml @@ -0,0 +1,902 @@ + + + + false + com.android.music.metachanged + true + com.android.music.metachanged + + + + + + + + global_artist = getString("artist"); +global_track = getString("track"); +global_album = getString("album"); + false + + + false + HTTP Request: /fhem-amad/deviceInfo/ + true + /fhem-amad/deviceInfo/ + 8090 + true + + + false + HTTP Request: /fhem-amad/setCommands/* + true + /fhem-amad/setCommands/* + 8090 + true + + + true + Akku Ladestand: grösser als 0% + 0 + HIGHER_THAN + + + false + App Task läuft: App3 (neuster) + + true + + + false + App Task läuft: App4 (neuster) + + true + + + false + App Task läuft: App5 (neuster) + + true + + + false + App Task läuft: gplay (neuster) + com.google.android.music + true + + + false + App Task läuft: tuneinradio (neuster) + tunein.player + true + + + false + Benachrichtigung in Statusbar angezeigt: Automagic + ch.gridvision.ppam.androidautomagic + TEXT + CONTAINS_TEXT + + false + false + + + true + Bluetooth eingeschaltet + + + true + Bluetooth Gerät verbunden: Beliebiges Geräte + true + + + + + true + Display automatisch drehen eingeschaltet + + + true + Display eingeschaltet + + + true + Display Orientierung: Portrait + true + + + false + Expression: App3 + param_app == "" + + + false + Expression: App4 + param_app == "" + + + false + Expression: App5 + param_app == "" + + + true + Expression: global_fhemdevice == "null" + global_fhemdevice == "null" + + + true + Expression: global_fhemip == "null" + global_fhemip == "null" + + + false + Expression: gplay + param_app == "gplay" + + + false + Expression: mediaPlayer" + request_path == "/fhem-amad/setCommands/mediaPlayer" + + + false + Expression: openApp" + request_path == "/fhem-amad/setCommands/openApp" + + + false + Expression: openURL" + request_path == "/fhem-amad/setCommands/openURL" + + + true + Expression: param_button == "back" + param_button == "back" + + + true + Expression: param_button == "next" + param_button == "next" + + + true + Expression: param_button == "play" + param_button == "play" + + + true + Expression: param_button == "stop" + param_button == "stop" + + + true + Expression: param_fullscreen == "off" + param_fullscreen == "off" + + + true + Expression: param_fullscreen == "on" + param_fullscreen == "on" + + + true + Expression: param_orientation == "auto" + param_orientation == "auto" + + + true + Expression: param_orientation == "landscape" + param_orientation == "landscape" + + + true + Expression: param_orientation == "portrait" + param_orientation == "portrait" + + + true + Expression: param_screen=="off" + param_screen=="off" + + + true + Expression: param_screen=="on" + param_screen=="on" + + + false + Expression: Reboot + param_syscmd == "reboot" + + + false + Expression: screenMsg" + request_path == "/fhem-amad/setCommands/screenMsg" + + + false + Expression: setAlarm" + request_path == "/fhem-amad/setCommands/setAlarm" + + + false + Expression: setBrightness" + request_path == "/fhem-amad/setCommands/setBrightness" + + + false + Expression: setScreenFullscreen" + request_path == "/fhem-amad/setCommands/setScreenFullscreen" + + + false + Expression: setScreenOnOff" + request_path == "/fhem-amad/setCommands/setScreenOnOff" + + + false + Expression: setScreenOrientation" + request_path == "/fhem-amad/setCommands/setScreenOrientation" + + + false + Expression: setVolume" + request_path == "/fhem-amad/setCommands/setVolume" + + + false + Expression: System Command" + request_path == "/fhem-amad/setCommands/systemcommand" + + + true + Expression: trigger == "com.android.music.metachanged" + trigger == "com.android.music.metachanged" + + + true + Expression: trigger == "HTTP Request: /fhem-amad/setCommands/*" + trigger == "HTTP Request: /fhem-amad/setCommands/*" + + + false + Expression: ttsMsg" + request_path == "/fhem-amad/setCommands/ttsMsg" + + + false + Expression: tuneinradio + param_app == "tuneinradio" + + + true + Flow Aktiv: Informations + Informations + + + true + Flow Aktiv: SetCommands + SetCommands + + + true + Musik Aktiv + + + true + WLAN Verbunden: Alle SSIDs + true + + + + false + App Starten: App3 + + + + + false + App Starten: App4 + + + + + false + App Starten: App5 + + + + + false + App Starten: PlayMusic + com.google.android.music + + + + false + App Starten: tuneinradio + tunein.player + + + + true + Audio Player steuern: Medienknopf Play (Google Play Musik) + true + LAUNCH + KEYCODE_MEDIA_PLAY + true + com.google.android.music + com.google.android.music.playback.MediaButtonIntentReceiver + Google Play Musik + + + true + Audio Player steuern: Medienknopf Stopp (Google Play Musik) + true + LAUNCH + KEYCODE_MEDIA_STOP + true + com.google.android.music + com.google.android.music.playback.MediaButtonIntentReceiver + Google Play Musik + + + true + Audio Player steuern: Medienknopf Weiter (Google Play Musik) + true + LAUNCH + KEYCODE_MEDIA_NEXT + true + com.google.android.music + com.google.android.music.playback.MediaButtonIntentReceiver + Google Play Musik + + + true + Audio Player steuern: Medienknopf Zurück (Google Play Musik) + true + LAUNCH + KEYCODE_MEDIA_PREVIOUS + true + com.google.android.music + com.google.android.music.playback.MediaButtonIntentReceiver + Google Play Musik + + + true + Benachrichtigung auf Bildschirm: {param_message} (lange) + true + {param_message} + + 200 + 250 + false + 1.0 + true + false + TOP_LEFT + 0 + 0 + + + true + Display automatisch drehen ein-/ausschalten: Aus + false + + + true + Display automatisch drehen ein-/ausschalten: Ein + true + + + true + Gerät sperren + + + true + HTTP Request: GET http://{global_fhemip}:8085/fhem?cmd=sleep%202%3Bset%20{global_fhemdevice}%20statusRequest speichern in response + http://{global_fhemip}:8085/fhem?cmd=sleep%202%3Bset%20{global_fhemdevice}%20statusRequest + true + false + + GET + X_WWW_FORM_URLENCODED + text/plain + + Lastname=XYZ,Firstname=ABC + 60000 + false + + true + response + /storage/emulated/0/Download/file.bin + + + false + HTTP Response Information + powerLevel@@{battery_percentage}@@@@powerPlugged@@{battery_plugged}@@@@volumeMusikBluetooth@@{volumeMusikBluetooth}@@@@volumeMusikSpeaker@@{volumeMusikSpeaker}@@@@screenBrightness@@{screenBrightness}@@@@nextAlarmTime@@{next_alarmtime}@@@@nextAlarmDay@@{next_alarmday}@@@@screen@@{screen_state}@@@@automagicState@@{notification_text}@@@@screenOrientation@@{screen_orientation}@@@@currentMusicTrack@@{global_track}@@@@currentMusicAlbum@@{global_album}@@@@currentMusicArtist@@{global_artist}@@@@bluetooth@@{bluetooth_state}@@@@connectedBTdevices@@{connected_devices_names}@@@@flow_SetCommands@@{setCommandFlow_state} + true + text/plain + + + false + HTTP Response SetCommand + flow_informations@@{informationFlow_state}@@@@ + true + text/plain + + + false + Initialisiere Variable Nächster Alarm: next_alarm + next_alarm + + + false + Initialisiere Variable Systemeinstellung: screenBrightness + SYSTEM + screen_brightness + screenBrightness + + + false + Initialisiere Variable Systemeinstellung: volumeMusikBluetooth + SYSTEM + volume_music_bt_a2dp + volumeMusikBluetooth + + + false + Initialisiere Variable Systemeinstellung: volumeMusikSpeaker + SYSTEM + volume_music_speaker + volumeMusikSpeaker + + + false + Lautstärken setzen + false + global_volume_alarm + false + global_volume_dtmf + true + param_volume + false + global_volume_notification + false + global_volume_ring + false + global_volume_system + false + global_volume_voice_call + false + global_ringer_mode + false + global_interruptions_mode + + + true + Neustart + + + + true + Pause: 2s (Gerät wach halten) + 2s + true + + + true + Schalte Display ein: Hell für 120s + true + 120s + true + + + true + Script: bluetooth_state = "off" + + + + true + Script: bluetooth_state = "on" + + + + true + Script: global_artist = "no soundplayer activ"; global_track = "no soundplayer activ"; global_album = "no soundplayer activ"; + + + + true + Script: global_fhemip = {header_fhemip} global_fhemdevice = {header_fhemdevice} + + + + true + Script: informationFlow_state = "aktiv" + + + + true + Script: informationFlow_state = "inaktiv" + + + + true + Script: next_alarmday = "{next_alarm,dateformat,c}" + + + + true + Script: next_alarmtime = "{next_alarm,dateformat,HH:mm}" + + + + true + Script: notification_text = "no supported from your device" + + + + true + Script: screen_orientation = "auto" + + + + true + Script: screen_orientation = "landscape" + + + + true + Script: screen_orientation = "portrait" + + + + true + Script: screen_state = "off" + + + + true + Script: screen_state = "on" + + + + true + Script: setCommandFlow_state = "aktiv" + + + + true + Script: setCommandFlow_state = "inaktiv" + + + + true + Setze Alarm: um {param_hour}:{param_minute} + + {param_hour} + {param_minute} + + + true + Setze Display Orientierung: Auf Default zurücksetzen + UNSPECIFIED + false + + + true + Setze Display Orientierung: Landscape + LANDSCAPE + false + + + true + Setze Display Orientierung: Portrait + PORTRAIT + false + + + true + Setze Flow Status: Aktivieren Informations + true + Informations + + + + true + Setze Flow Status: Aktivieren SetCommands + true + SetCommands + + + + true + Setze Systemeinstellung: System screen_brightness auf {param_brightness} + SYSTEM + screen_brightness + {param_brightness} + true + + + true + Setze Vollbild Modus: Auf Default zurücksetzen + UNSPECIFIED + false + + + true + Setze Vollbild Modus: Navigation nicht anzeigen + HIDE_NAVIGATION + false + + + true + Sprachausgabe: {param_message} + MUSIC + {param_message} + de_DE + true + 1.0 + true + 1.0 + true + false + false + false + TRANSIENT + + + true + URL in Browser öffnen: {param_url} (mit Chrome) + {param_url} + true + com.android.chrome + com.google.android.apps.chrome.Main + Chrome + + + Informations + FHEM Info / Steuerung über AMAD Modul v0.6 + true + SKIP + 120 + + com.android.music.metachanged + HTTP Request: /fhem-amad/deviceInfo/ + + Script: notification_text = "no supported from your device" + Script: screen_orientation = "auto" + Display automatisch drehen eingeschaltet + Script: screen_orientation = "portrait" + Display Orientierung: Portrait + Script: screen_orientation = "landscape" + Bluetooth eingeschaltet + Script: bluetooth_state = "on" + Bluetooth Gerät verbunden: Beliebiges Geräte + Script: bluetooth_state = "off" + Script: screen_state = "off" + Script: screen_state = "on" + Display eingeschaltet + Script: next_alarmtime = "{next_alarm,dateformat,HH:mm}" + Initialisiere Variable Nächster Alarm: next_alarm + Script: next_alarmday = "{next_alarm,dateformat,c}" + Initialisiere Variable Systemeinstellung: screenBrightness + Initialisiere Variable Systemeinstellung: volumeMusikSpeaker + Initialisiere Variable Systemeinstellung: volumeMusikBluetooth + Expression: global_fhemip == "null" + Expression: global_fhemdevice == "null" + Script: global_fhemip = {header_fhemip} global_fhemdevice = {header_fhemdevice} + Flow Aktiv: SetCommands + Script: setCommandFlow_state = "aktiv" + Script: setCommandFlow_state = "inaktiv" + Setze Flow Status: Aktivieren SetCommands + Benachrichtigung in Statusbar angezeigt: Automagic + HTTP Response Information + Akku Ladestand: grösser als 0% + Script: global_artist = "no soundplayer activ"; global_track = "no soundplayer activ"; global_album = "no soundplayer activ"; + Musik Aktiv + Pause: 2s (Gerät wach halten) + Expression: trigger == "com.android.music.metachanged" + WLAN Verbunden: Alle SSIDs + HTTP Request: GET http://{global_fhemip}:8085/fhem?cmd=sleep%202%3Bset%20{global_fhemdevice}%20statusRequest speichern in response + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SetCommands + FHEM Info / Steuerung über AMAD Modul v0.6 + true + QUEUE + 120 + + HTTP Request: /fhem-amad/deviceInfo/ + HTTP Request: /fhem-amad/setCommands/* + + Expression: param_screen=="on" + Sprachausgabe: {param_message} + Expression: ttsMsg" + Expression: setBrightness" + Expression: setAlarm" + Expression: screenMsg" + Expression: openURL" + Setze Alarm: um {param_hour}:{param_minute} + URL in Browser öffnen: {param_url} (mit Chrome) + Benachrichtigung auf Bildschirm: {param_message} (lange) + Schalte Display ein: Hell für 120s + Expression: setScreenFullscreen" + Expression: param_orientation == "auto" + Setze Display Orientierung: Portrait + Setze Display Orientierung: Landscape + Expression: param_orientation == "landscape" + Expression: param_orientation == "portrait" + Expression: param_fullscreen == "off" + Setze Vollbild Modus: Navigation nicht anzeigen + Expression: param_fullscreen == "on" + Setze Vollbild Modus: Auf Default zurücksetzen + Audio Player steuern: Medienknopf Zurück (Google Play Musik) + Expression: param_button == "back" + Display automatisch drehen ein-/ausschalten: Aus + Expression: param_button == "next" + Setze Display Orientierung: Auf Default zurücksetzen + Display automatisch drehen ein-/ausschalten: Ein + Audio Player steuern: Medienknopf Play (Google Play Musik) + Expression: param_button == "play" + Expression: mediaPlayer" + Audio Player steuern: Medienknopf Weiter (Google Play Musik) + Audio Player steuern: Medienknopf Stopp (Google Play Musik) + Expression: param_button == "stop" + Expression: param_screen=="off" + Gerät sperren + Expression: setScreenOnOff" + Expression: setVolume" + Lautstärken setzen + App Task läuft: App5 (neuster) + Expression: App5 + Expression: App4 + App Task läuft: App3 (neuster) + Expression: App3 + App Starten: App3 + App Starten: App4 + App Task läuft: App4 (neuster) + Expression: tuneinradio + App Task läuft: tuneinradio (neuster) + App Starten: tuneinradio + App Starten: App5 + App Task läuft: gplay (neuster) + Expression: gplay + App Starten: PlayMusic + Expression: openApp" + Expression: System Command" + Expression: setScreenOrientation" + Expression: Reboot + Neustart + Setze Systemeinstellung: System screen_brightness auf {param_brightness} + Expression: trigger == "HTTP Request: /fhem-amad/setCommands/*" + Setze Flow Status: Aktivieren Informations + Script: informationFlow_state = "inaktiv" + Script: informationFlow_state = "aktiv" + Flow Aktiv: Informations + HTTP Response SetCommand + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file