From cbe73ecfce7f8a01b882a6b8001b4e133a9b0d2d Mon Sep 17 00:00:00 2001 From: zap <> Date: Wed, 23 Mar 2022 09:24:41 +0000 Subject: [PATCH] AndroidDB: added FHEM reading attributes git-svn-id: https://svn.fhem.de/fhem/trunk@25875 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/89_AndroidDB.pm | 1117 +++++++++++++++++---------------- fhem/FHEM/89_AndroidDBHost.pm | 9 +- 3 files changed, 565 insertions(+), 562 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 8ec03fa98..cad6d102d 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # 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: 89_AndroidDB: Added FHEM reading attributes - bugfix: 70_SVDRP.pm: bugfix in NextTimer - bugfix: 38_netatmo: fixed average wind angle calculation for PUBLIC - feature: 10_KNX.pm: new dpt22.101, fixes: (UTF8) & dpt20 encode diff --git a/fhem/FHEM/89_AndroidDB.pm b/fhem/FHEM/89_AndroidDB.pm index e38415fb5..517b176ce 100644 --- a/fhem/FHEM/89_AndroidDB.pm +++ b/fhem/FHEM/89_AndroidDB.pm @@ -4,7 +4,7 @@ # # 89_AndroidDB # -# Version 0.6 +# Version 0.7 # # FHEM Integration for Android Devices # @@ -23,24 +23,25 @@ package main; use strict; use warnings; +use SetExtensions; sub AndroidDB_Initialize ($) { - my ($hash) = @_; + my ($hash) = @_; - $hash->{DefFn} = "AndroidDB::Define"; - $hash->{UndefFn} = "AndroidDB::Undef"; - $hash->{SetFn} = "AndroidDB::Set"; - $hash->{GetFn} = "AndroidDB::Get"; - $hash->{AttrFn} = "AndroidDB::Attr"; - $hash->{ShutdownFn} = "AndroidDB::Shutdown"; + $hash->{DefFn} = "AndroidDB::Define"; + $hash->{UndefFn} = "AndroidDB::Undef"; + $hash->{SetFn} = "AndroidDB::Set"; + $hash->{GetFn} = "AndroidDB::Get"; + $hash->{AttrFn} = "AndroidDB::Attr"; + $hash->{ShutdownFn} = "AndroidDB::Shutdown"; - $hash->{parseParams} = 1; - $hash->{AttrList} = 'connect:0,1 macros:textField-long preset presetFile'; + $hash->{parseParams} = 1; + $hash->{AttrList} = 'connect:0,1 macros:textField-long preset presetFile '.$readingFnAttributes; - $data{RC_layout}{MagentaTVStick} = "AndroidDB::RCLayoutMagentaTVStick"; - $data{RC_layout}{MagentaOne} = "AndroidDB::RCLayoutMagentaOne"; - $data{RC_layout}{MagentaTVExtended} = "AndroidDB::RCLayoutMagentaTVExt"; + $data{RC_layout}{MagentaTVStick} = "AndroidDB::RCLayoutMagentaTVStick"; + $data{RC_layout}{MagentaOne} = "AndroidDB::RCLayoutMagentaOne"; + $data{RC_layout}{MagentaTVExtended} = "AndroidDB::RCLayoutMagentaTVExt"; } package AndroidDB; @@ -52,109 +53,109 @@ use Storable qw(dclone); use GPUtils qw(:all); BEGIN { - GP_Import(qw( - readingsSingleUpdate - readingsBulkUpdate - readingsBulkUpdateIfChanged - readingsBeginUpdate - readingsEndUpdate - setDevAttrList - CommandDefine - CommandSet - CommandAttr - Log3 - AttrVal - ReadingsVal - AssignIoPort - InternalTimer - asyncOutput - gettimeofday - parseParams - defs - attr - modules - data - init_done - )) + GP_Import(qw( + readingsSingleUpdate + readingsBulkUpdate + readingsBulkUpdateIfChanged + readingsBeginUpdate + readingsEndUpdate + setDevAttrList + CommandDefine + CommandSet + CommandAttr + Log3 + AttrVal + ReadingsVal + AssignIoPort + InternalTimer + asyncOutput + gettimeofday + parseParams + defs + attr + modules + data + init_done + )) }; # Remote control presets my $PRESET = { - 'MagentaTVStick' => { - 'ASSISTANT' => 'KEYCODE_ASSIST', - 'APPS' => 'KEYCODE_ALL_APPS', - 'BACK' => 'KEYCODE_BACK', - 'EPG' => 'KEYCODE_TV_INPUT_HDMI_2', - 'HOME' => 'KEYCODE_HOME', - 'LEFT' => 'KEYCODE_DPAD_LEFT', - 'RIGHT' => 'KEYCODE_DPAD_RIGHT', - 'UP' => 'KEYCODE_DPAD_UP', - 'DOWN' => 'KEYCODE_DPAD_DOWN', - 'INFO' => 'KEYCODE_INFO', - 'MEGATHEK' => 'KEYCODE_TV_INPUT_HDMI_3', - 'MUTE' => 'KEYCODE_VOLUME_MUTE', - 'OK' => 'KEYCODE_DPAD_CENTER', - 'PLAYPAUSE' => 'KEYCODE_MEDIA_PLAY_PAUSE', - 'POWER' => 'KEYCODE_POWER', - 'PROG+' => 'KEYCODE_CHANNEL_UP', - 'PROG-' => 'KEYCODE_CHANNEL_DOWN', - 'RECORD' => 'KEYCODE_MEDIA_RECORD', - 'SEARCH' => 'KEYCODE_TV_INPUT_HDMI_1', - 'STREAMINFO' => '--longpress,KEYCODE_INFO', - 'TV' => 'KEYCODE_TV_INPUT_HDMI_4', - 'VOL+' => 'KEYCODE_VOLUME_UP', - 'VOL-' => 'KEYCODE_VOLUME_DOWN' - }, - 'MagentaOne' => { - 'ASSISTANT' => 'KEYCODE_ASSIST', - 'APPS' => 'KEYCODE_ALL_APPS', - 'BACK' => 'KEYCODE_BACK', - 'EPG' => 'KEYCODE_TV_INPUT_HDMI_2', - 'HOME' => 'KEYCODE_HOME', - 'LEFT' => 'KEYCODE_DPAD_LEFT', - 'RIGHT' => 'KEYCODE_DPAD_RIGHT', - 'UP' => 'KEYCODE_DPAD_UP', - 'DOWN' => 'KEYCODE_DPAD_DOWN', - 'INFO' => 'KEYCODE_INFO', - 'MEGATHEK' => 'KEYCODE_TV_INPUT_HDMI_3', - 'MUTE' => 'KEYCODE_VOLUME_MUTE', - 'OK' => 'KEYCODE_DPAD_CENTER', - 'PLAYPAUSE' => 'KEYCODE_MEDIA_PLAY_PAUSE', - 'POWER' => 'KEYCODE_POWER', - 'PROG+' => 'KEYCODE_CHANNEL_UP', - 'PROG-' => 'KEYCODE_CHANNEL_DOWN', - 'RECORD' => 'KEYCODE_MEDIA_RECORD', - 'SEARCH' => 'KEYCODE_TV_INPUT_HDMI_1', - 'STREAMINFO' => '--longpress,KEYCODE_INFO', - 'TV' => 'KEYCODE_TV_INPUT_HDMI_4', - 'VOL+' => 'KEYCODE_VOLUME_UP', - 'VOL-' => 'KEYCODE_VOLUME_DOWN' - }, - 'AndroidTV' => { - 'APPS' => 'KEYCODE_ALL_APPS', - 'BACK' => 'KEYCODE_BACK', - 'EPG' => 'KEYCODE_GUIDE', - 'HOME' => 'KEYCODE_HOME', - 'LEFT' => 'KEYCODE_DPAD_LEFT', - 'RIGHT' => 'KEYCODE_DPAD_RIGHT', - 'UP' => 'KEYCODE_DPAD_UP', - 'DOWN' => 'KEYCODE_DPAD_DOWN', - 'INFO' => 'KEYCODE_INFO', - 'MUTE' => 'KEYCODE_VOLUME_MUTE', - 'OK' => 'KEYCODE_DPAD_CENTER', - 'PLAYPAUSE' => 'KEYCODE_MEDIA_PLAY_PAUSE', - 'POWER' => 'KEYCODE_POWER', - 'PROG+' => 'KEYCODE_CHANNEL_UP', - 'PROG-' => 'KEYCODE_CHANNEL_DOWN', - 'RECORD' => 'KEYCODE_MEDIA_RECORD', - 'SEARCH' => 'KEYCODE_SEARCH', - 'VOL+' => 'KEYCODE_VOLUME_UP', - 'VOL-' => 'KEYCODE_VOLUME_DOWN', - 'RED' => 'KEYCODE_PROG_RED', - 'GREEN' => 'KEYCODE_PROG_GREEN', - 'BLUE' => 'KEYCODE_PROG_BLUE', - 'YELLOW' => 'KEYCODE_PROG_YELLOW' - } + 'MagentaTVStick' => { + 'ASSISTANT' => 'KEYCODE_ASSIST', + 'APPS' => 'KEYCODE_ALL_APPS', + 'BACK' => 'KEYCODE_BACK', + 'EPG' => 'KEYCODE_TV_INPUT_HDMI_2', + 'HOME' => 'KEYCODE_HOME', + 'LEFT' => 'KEYCODE_DPAD_LEFT', + 'RIGHT' => 'KEYCODE_DPAD_RIGHT', + 'UP' => 'KEYCODE_DPAD_UP', + 'DOWN' => 'KEYCODE_DPAD_DOWN', + 'INFO' => 'KEYCODE_INFO', + 'MEGATHEK' => 'KEYCODE_TV_INPUT_HDMI_3', + 'MUTE' => 'KEYCODE_VOLUME_MUTE', + 'OK' => 'KEYCODE_DPAD_CENTER', + 'PLAYPAUSE' => 'KEYCODE_MEDIA_PLAY_PAUSE', + 'POWER' => 'KEYCODE_POWER', + 'PROG+' => 'KEYCODE_CHANNEL_UP', + 'PROG-' => 'KEYCODE_CHANNEL_DOWN', + 'RECORD' => 'KEYCODE_MEDIA_RECORD', + 'SEARCH' => 'KEYCODE_TV_INPUT_HDMI_1', + 'STREAMINFO' => '--longpress,KEYCODE_INFO', + 'TV' => 'KEYCODE_TV_INPUT_HDMI_4', + 'VOL+' => 'KEYCODE_VOLUME_UP', + 'VOL-' => 'KEYCODE_VOLUME_DOWN' + }, + 'MagentaOne' => { + 'ASSISTANT' => 'KEYCODE_ASSIST', + 'APPS' => 'KEYCODE_ALL_APPS', + 'BACK' => 'KEYCODE_BACK', + 'EPG' => 'KEYCODE_TV_INPUT_HDMI_2', + 'HOME' => 'KEYCODE_HOME', + 'LEFT' => 'KEYCODE_DPAD_LEFT', + 'RIGHT' => 'KEYCODE_DPAD_RIGHT', + 'UP' => 'KEYCODE_DPAD_UP', + 'DOWN' => 'KEYCODE_DPAD_DOWN', + 'INFO' => 'KEYCODE_INFO', + 'MEGATHEK' => 'KEYCODE_TV_INPUT_HDMI_3', + 'MUTE' => 'KEYCODE_VOLUME_MUTE', + 'OK' => 'KEYCODE_DPAD_CENTER', + 'PLAYPAUSE' => 'KEYCODE_MEDIA_PLAY_PAUSE', + 'POWER' => 'KEYCODE_POWER', + 'PROG+' => 'KEYCODE_CHANNEL_UP', + 'PROG-' => 'KEYCODE_CHANNEL_DOWN', + 'RECORD' => 'KEYCODE_MEDIA_RECORD', + 'SEARCH' => 'KEYCODE_TV_INPUT_HDMI_1', + 'STREAMINFO' => '--longpress,KEYCODE_INFO', + 'TV' => 'KEYCODE_TV_INPUT_HDMI_4', + 'VOL+' => 'KEYCODE_VOLUME_UP', + 'VOL-' => 'KEYCODE_VOLUME_DOWN' + }, + 'AndroidTV' => { + 'APPS' => 'KEYCODE_ALL_APPS', + 'BACK' => 'KEYCODE_BACK', + 'EPG' => 'KEYCODE_GUIDE', + 'HOME' => 'KEYCODE_HOME', + 'LEFT' => 'KEYCODE_DPAD_LEFT', + 'RIGHT' => 'KEYCODE_DPAD_RIGHT', + 'UP' => 'KEYCODE_DPAD_UP', + 'DOWN' => 'KEYCODE_DPAD_DOWN', + 'INFO' => 'KEYCODE_INFO', + 'MUTE' => 'KEYCODE_VOLUME_MUTE', + 'OK' => 'KEYCODE_DPAD_CENTER', + 'PLAYPAUSE' => 'KEYCODE_MEDIA_PLAY_PAUSE', + 'POWER' => 'KEYCODE_POWER', + 'PROG+' => 'KEYCODE_CHANNEL_UP', + 'PROG-' => 'KEYCODE_CHANNEL_DOWN', + 'RECORD' => 'KEYCODE_MEDIA_RECORD', + 'SEARCH' => 'KEYCODE_SEARCH', + 'VOL+' => 'KEYCODE_VOLUME_UP', + 'VOL-' => 'KEYCODE_VOLUME_DOWN', + 'RED' => 'KEYCODE_PROG_RED', + 'GREEN' => 'KEYCODE_PROG_GREEN', + 'BLUE' => 'KEYCODE_PROG_BLUE', + 'YELLOW' => 'KEYCODE_PROG_YELLOW' + } }; # Command presets @@ -163,260 +164,260 @@ my $MACRO = { }; sub Define ($$$) { my ($hash, $a, $h) = @_; - - my $usage = "define $hash->{NAME} AndroidDB {NameOrIP[:Port]}"; - - return $usage if (scalar(@$a) < 3); - # Set parameters - my ($devName, $devPort) = split (':', $$a[2]); - $hash->{ADBDevice} = $devName.':'.($devPort // '5555'); - - AssignIoPort ($hash); - - $attr{$hash->{NAME}}{webCmd} = 'remoteControl'; - - # Clone predefined presets and macros - $hash->{adb}{preset} = dclone $PRESET; - $hash->{adb}{macro} = dclone $MACRO; - - InitAfterStart ($hash) if ($init_done); - + my $usage = "define $hash->{NAME} AndroidDB {NameOrIP[:Port]}"; + + return $usage if (scalar(@$a) < 3); + + # Set parameters + my ($devName, $devPort) = split (':', $$a[2]); + $hash->{ADBDevice} = $devName.':'.($devPort // '5555'); + + AssignIoPort ($hash); + + $attr{$hash->{NAME}}{webCmd} = 'remoteControl'; + + # Clone predefined presets and macros + $hash->{adb}{preset} = dclone $PRESET; + $hash->{adb}{macro} = dclone $MACRO; + + InitAfterStart ($hash) if ($init_done); + return undef; } sub InitAfterStart ($) { - my ($hash) = @_; - - my @presets = map { $_ eq '_custom_' ? () : $_ } keys %{$hash->{adb}{preset}}; + my ($hash) = @_; + + my @presets = map { $_ eq '_custom_' ? () : $_ } keys %{$hash->{adb}{preset}}; - if (scalar(@presets) > 0) { - my $attrPreset = 'preset:select,'.join(',',@presets); - my $attributes = $modules{AndroidDB}{AttrList}; - $attributes =~ s/preset/$attrPreset/; - setDevAttrList ($hash->{NAME}, $attributes); - } + if (scalar(@presets) > 0) { + my $attrPreset = 'preset:select,'.join(',',@presets); + my $attributes = $modules{AndroidDB}{AttrList}; + $attributes =~ s/preset/$attrPreset/; + setDevAttrList ($hash->{NAME}, $attributes); + } } sub Undef ($$) { my ($hash, $name) = @_; - AndroidDBHost::Disconnect ($hash); + AndroidDBHost::Disconnect ($hash); return undef; } sub Shutdown ($) { - my ($hash) = @_; - - AndroidDBHost::Disconnect ($hash); + my ($hash) = @_; + + AndroidDBHost::Disconnect ($hash); } sub Set ($@) { - my ($hash, $a, $h) = @_; - - my $name = shift @$a; - my $opt = shift @$a // return 'No set command specified'; + my ($hash, $a, $h) = @_; + + my $name = shift @$a; + my $opt = shift @$a // return 'No set command specified'; - # - # Preprare list of available commands - # - - # Standard commands - my $options = 'exportPresets reboot rollHorz rollVert sendKey sendNumKeys sendText shell tap'; - - # Add remote control key presets to command remoteControl - my @presetList = (); - my $preset = AttrVal ($name, 'preset', ''); - push @presetList, sort keys %{$hash->{adb}{preset}{$preset}} if ($preset ne '' && exists($hash->{adb}{preset}{$preset})); - push @presetList, sort keys %{$hash->{adb}{preset}{_custom_}} if (exists($hash->{adb}{preset}{_custom_})); - my %e; - $options .= ' remoteControl:'.join(',', sort grep { !$e{$_}++ } @presetList) if (scalar(@presetList) > 0); - - # Add remote control layouts to command createRemote - my @layouts = keys %{$data{RC_layout}}; - $options .= ' createRemote:'.join(',', sort @layouts) if (scalar(@layouts) > 0); - - # Add command macros to command list - my @macroList = (); - push @macroList, sort keys %{$hash->{adb}{macro}{$preset}} if ($preset ne '' && exists($hash->{adb}{macro}{$preset})); - push @macroList, sort keys %{$hash->{adb}{macro}{_custom_}} if (exists($hash->{adb}{macro}{_custom_})); - my %e; - $options .= ' '.join(' ', sort grep { !$e{$_}++ } @macroList) if (scalar(@macroList) > 0); + # + # Preprare list of available commands + # + + # Standard commands + my $options = 'exportPresets reboot rollHorz rollVert sendKey sendNumKeys sendText shell tap'; + + # Add remote control key presets to command remoteControl + my @presetList = (); + my $preset = AttrVal ($name, 'preset', ''); + push @presetList, sort keys %{$hash->{adb}{preset}{$preset}} if ($preset ne '' && exists($hash->{adb}{preset}{$preset})); + push @presetList, sort keys %{$hash->{adb}{preset}{_custom_}} if (exists($hash->{adb}{preset}{_custom_})); + my %e1; + $options .= ' remoteControl:'.join(',', sort grep { !$e1{$_}++ } @presetList) if (scalar(@presetList) > 0); + + # Add remote control layouts to command createRemote + my @layouts = keys %{$data{RC_layout}}; + $options .= ' createRemote:'.join(',', sort @layouts) if (scalar(@layouts) > 0); + + # Add command macros to command list + my @macroList = (); + push @macroList, sort keys %{$hash->{adb}{macro}{$preset}} if ($preset ne '' && exists($hash->{adb}{macro}{$preset})); + push @macroList, sort keys %{$hash->{adb}{macro}{_custom_}} if (exists($hash->{adb}{macro}{_custom_})); + my %e2; + $options .= ' '.join(' ', sort grep { !$e2{$_}++ } @macroList) if (scalar(@macroList) > 0); - my $lcopt = lc($opt); + my $lcopt = lc($opt); - if ($lcopt eq 'sendkey') { - return "Usage: set $name $opt [--longpress] KeyCode [...]" if (scalar(@$a) == 0); - return "Only one KeyCode allowed when option '--longpress' is specified" - if ($$a[0] eq '--longpress' && scalar(@$a) > 2); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'keyevent', @$a); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'sendnumkeys') { - my $number = shift @$a // return "Usage: set $name $opt Number"; - return 'Parameter Number must be in range 1-9999' if ($number !~ /^[0-9]+$/ || $number < 1 || $number > 9999); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'text', $number); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'sendtext') { - return "Usage: set $name $opt Text" if (scalar(@$a) < 1); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'text', join(' ',@$a)); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'reboot') { - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $opt); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'shell') { - return "Usage: set $name $opt ShellCommand" if (scalar(@$a) == 0); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $opt, '.*', @$a); - return $result.$error, - } - elsif ($lcopt eq 'remotecontrol') { - my $macroName = shift @$a // return "Usage: set $name $opt MacroName"; - $preset = '_custom_' if (exists($hash->{adb}{preset}{_custom_}) && exists($hash->{adb}{preset}{_custom_}{$macroName})); - return "Preset and/or macro $macroName not defined in preset $preset" - if ($preset eq '' || !exists($hash->{adb}{preset}{$preset}{$macroName})); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'keyevent', - split (',', $hash->{adb}{preset}{$preset}{$macroName})); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'tap') { - my ($x, $y) = @$a; - return "Usage: set $name $opt tap X Y" if (!defined($y)); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'tap', $x, $y); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'rollhorz' || $lcopt eq 'rollvert') { - my $delta = shift @$a // return "Usage: set $name $opt Delta"; - my ($dx, $dy) = $opt eq 'rollhorz' ? ($delta, 0) : (0, $delta); - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'roll', $dx, $dy); - return $error if ($rc == 0); - } - elsif ($lcopt eq 'createremote') { - my $layout = shift @$a // return "Usage: set $name $opt LayoutName"; - my $rcName = $name.'_RC'; - return "$name: Can't create remotecontrol device $rcName" - if (CommandDefine (undef, "$rcName remotecontrol")); - Log3 $name, 2, "$name: Created remotecontrol device $rcName"; - return "$name: Can't select layout $layout for remotecontrol device $rcName" - if (CommandSet (undef, "$rcName layout $layout")); - Log3 $name, 2, "Selected layout $layout for $rcName"; - my $room = AttrVal ($name, 'room', ''); - if ($room ne '') { - Log3 $name, 2, "$name: Assigning $rcName to room $room"; - CommandAttr (undef, "$rcName room $room"); - } - CommandSet (undef, "$rcName makenotify $name"); - CommandAttr (undef, "$name group $name"); - CommandAttr (undef, "$rcName group $name"); - Log3 $name, 2, "Created notify device notify_$rcName"; - } - elsif ($lcopt eq 'exportpresets') { - my $filename = shift @$a // return "Usage: set $name $opt Filename"; - my $rc = ExportPresets ($hash, $filename); - return "Error while saving presets to file $filename" if ($rc == 0); - return "Presets saved to file $filename"; - } - elsif (exists($hash->{adb}{macro}{_custom_}) && exists($hash->{adb}{macro}{_custom_}{$opt})) { - my ($args, $pars) = parseParams ($hash->{adb}{macro}{_custom_}{$opt}); - my $cmd = shift @$args; - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $cmd, '.*', @$args); - return $rc == 0 ? $error : $result; - } - elsif ($preset ne '' && exists($hash->{adb}{macro}{$preset}) && exists($hash->{adb}{macro}{$preset}{$opt})) { - my ($args, $pars) = parseParams ($hash->{adb}{macro}{$preset}{$opt}); - my $cmd = shift @$args; - my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $cmd, '.*', @$args); - return $rc == 0 ? $error : $result; - } - else { - return "Unknown argument $opt, choose one of $options"; - } + if ($lcopt eq 'sendkey') { + return "Usage: set $name $opt [--longpress] KeyCode [...]" if (scalar(@$a) == 0); + return "Only one KeyCode allowed when option '--longpress' is specified" + if ($$a[0] eq '--longpress' && scalar(@$a) > 2); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'keyevent', @$a); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'sendnumkeys') { + my $number = shift @$a // return "Usage: set $name $opt Number"; + return 'Parameter Number must be in range 1-9999' if ($number !~ /^[0-9]+$/ || $number < 1 || $number > 9999); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'text', $number); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'sendtext') { + return "Usage: set $name $opt Text" if (scalar(@$a) < 1); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'text', join(' ',@$a)); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'reboot') { + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $opt); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'shell') { + return "Usage: set $name $opt ShellCommand" if (scalar(@$a) == 0); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $opt, '.*', @$a); + return $result.$error, + } + elsif ($lcopt eq 'remotecontrol') { + my $macroName = shift @$a // return "Usage: set $name $opt MacroName"; + $preset = '_custom_' if (exists($hash->{adb}{preset}{_custom_}) && exists($hash->{adb}{preset}{_custom_}{$macroName})); + return "Preset and/or macro $macroName not defined in preset $preset" + if ($preset eq '' || !exists($hash->{adb}{preset}{$preset}{$macroName})); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'keyevent', + split (',', $hash->{adb}{preset}{$preset}{$macroName})); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'tap') { + my ($x, $y) = @$a; + return "Usage: set $name $opt tap X Y" if (!defined($y)); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'tap', $x, $y); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'rollhorz' || $lcopt eq 'rollvert') { + my $delta = shift @$a // return "Usage: set $name $opt Delta"; + my ($dx, $dy) = $opt eq 'rollhorz' ? ($delta, 0) : (0, $delta); + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, 'shell', '.*', 'input', 'roll', $dx, $dy); + return $error if ($rc == 0); + } + elsif ($lcopt eq 'createremote') { + my $layout = shift @$a // return "Usage: set $name $opt LayoutName"; + my $rcName = $name.'_RC'; + return "$name: Can't create remotecontrol device $rcName" + if (CommandDefine (undef, "$rcName remotecontrol")); + Log3 $name, 2, "$name: Created remotecontrol device $rcName"; + return "$name: Can't select layout $layout for remotecontrol device $rcName" + if (CommandSet (undef, "$rcName layout $layout")); + Log3 $name, 2, "Selected layout $layout for $rcName"; + my $room = AttrVal ($name, 'room', ''); + if ($room ne '') { + Log3 $name, 2, "$name: Assigning $rcName to room $room"; + CommandAttr (undef, "$rcName room $room"); + } + CommandSet (undef, "$rcName makenotify $name"); + CommandAttr (undef, "$name group $name"); + CommandAttr (undef, "$rcName group $name"); + Log3 $name, 2, "Created notify device notify_$rcName"; + } + elsif ($lcopt eq 'exportpresets') { + my $filename = shift @$a // return "Usage: set $name $opt Filename"; + my $rc = ExportPresets ($hash, $filename); + return "Error while saving presets to file $filename" if ($rc == 0); + return "Presets saved to file $filename"; + } + elsif (exists($hash->{adb}{macro}{_custom_}) && exists($hash->{adb}{macro}{_custom_}{$opt})) { + my ($args, $pars) = parseParams ($hash->{adb}{macro}{_custom_}{$opt}); + my $cmd = shift @$args; + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $cmd, '.*', @$args); + return $rc == 0 ? $error : $result; + } + elsif ($preset ne '' && exists($hash->{adb}{macro}{$preset}) && exists($hash->{adb}{macro}{$preset}{$opt})) { + my ($args, $pars) = parseParams ($hash->{adb}{macro}{$preset}{$opt}); + my $cmd = shift @$args; + my ($rc, $result, $error) = AndroidDBHost::Run ($hash, $cmd, '.*', @$args); + return $rc == 0 ? $error : $result; + } + else { + return "Unknown argument $opt, choose one of $options"; + } } sub Get ($@) { - my ($hash, $a, $h) = @_; + my ($hash, $a, $h) = @_; - my $name = shift @$a; - my $opt = shift @$a // return 'No get command specified'; - - my $options = 'keyPreset'; - my @presetList = sort keys %{$hash->{adb}{preset}}; - $options .= ':'.join(',', @presetList) if (scalar(@presetList) > 0); - my @macroList = sort keys %{$hash->{adb}{macro}}; - $options .= ' cmdPreset:'.join(',', @macroList) if (scalar(@macroList) > 0); - - my $attrPreset = AttrVal ($name, 'preset', ''); - - my $lcopt = lc($opt); - - if ($lcopt eq 'keypreset') { - my $preset = shift @$a // $attrPreset; - return "Usage: get $name $opt PresetName" if ($preset eq ''); - return "Key preset $preset not found" if (!exists($hash->{adb}{preset}{$preset})); - my $presetDef = "Definition of key preset $preset:

"; - foreach my $macro (sort keys %{$hash->{adb}{preset}{$preset}}) { - $presetDef .= "$macro = $hash->{adb}{preset}{$preset}{$macro}
"; - } - return $presetDef; - } - elsif ($lcopt eq 'cmdpreset') { - my $preset = shift @$a // $attrPreset; - return "Usage: get $name $opt PresetName" if ($preset eq ''); - return "Command preset $preset not found" if (!exists($hash->{adb}{macro}{$preset})); - my $macroDef = "Definition of command preset $preset:

"; - foreach my $macro (sort keys %{$hash->{adb}{macro}{$preset}}) { - $macroDef .= "$macro = $hash->{adb}{macro}{$preset}{$macro}
"; - } - return $macroDef; - } - else { - return "Unknown argument $opt, choose one of $options"; - } + my $name = shift @$a; + my $opt = shift @$a // return 'No get command specified'; + + my $options = 'keyPreset'; + my @presetList = sort keys %{$hash->{adb}{preset}}; + $options .= ':'.join(',', @presetList) if (scalar(@presetList) > 0); + my @macroList = sort keys %{$hash->{adb}{macro}}; + $options .= ' cmdPreset:'.join(',', @macroList) if (scalar(@macroList) > 0); + + my $attrPreset = AttrVal ($name, 'preset', ''); + + my $lcopt = lc($opt); + + if ($lcopt eq 'keypreset') { + my $preset = shift @$a // $attrPreset; + return "Usage: get $name $opt PresetName" if ($preset eq ''); + return "Key preset $preset not found" if (!exists($hash->{adb}{preset}{$preset})); + my $presetDef = "Definition of key preset $preset:

"; + foreach my $macro (sort keys %{$hash->{adb}{preset}{$preset}}) { + $presetDef .= "$macro = $hash->{adb}{preset}{$preset}{$macro}
"; + } + return $presetDef; + } + elsif ($lcopt eq 'cmdpreset') { + my $preset = shift @$a // $attrPreset; + return "Usage: get $name $opt PresetName" if ($preset eq ''); + return "Command preset $preset not found" if (!exists($hash->{adb}{macro}{$preset})); + my $macroDef = "Definition of command preset $preset:

"; + foreach my $macro (sort keys %{$hash->{adb}{macro}{$preset}}) { + $macroDef .= "$macro = $hash->{adb}{macro}{$preset}{$macro}
"; + } + return $macroDef; + } + else { + return "Unknown argument $opt, choose one of $options"; + } } sub Attr ($@) { - my ($cmd, $name, $attrName, $attrVal) = @_; - my $hash = $defs{$name}; + my ($cmd, $name, $attrName, $attrVal) = @_; + my $hash = $defs{$name}; - if ($cmd eq 'set') { - if ($attrName eq 'macros') { - foreach my $macroDef (split /;/, $attrVal) { - my ($macroName, $macroPar) = split (':', $macroDef); - if (!defined($macroDef)) { - Log3 $name, 2, "Missing defintion for macro $macroName"; - return "Missing definition for macro $macroName"; - } - if ($macroPar =~ /^[0-9]+/ || $macroPar =~ /^KEYCODE_/) { - $hash->{adb}{preset}{_custom_}{$macroName} = $macroPar; - } - else { - $hash->{adb}{macro}{_custom_}{$macroName} = $macroPar; - } - } - } - elsif ($attrName eq 'presetFile') { - if (!LoadPresets ($hash, $attrVal)) { - return "Cannot load presets from file $attrVal"; - } - } - elsif ($attrName eq 'connect') { - AndroidDBHost::Connect ($hash) if (!$init_done && $attrVal eq '1'); - } - } - elsif ($cmd eq 'del') { - delete $hash->{adb}{preset}{_custom_} if (exists($hash->{adb}{preset}{_custom_})); - } + if ($cmd eq 'set') { + if ($attrName eq 'macros') { + foreach my $macroDef (split /;/, $attrVal) { + my ($macroName, $macroPar) = split (':', $macroDef); + if (!defined($macroDef)) { + Log3 $name, 2, "Missing defintion for macro $macroName"; + return "Missing definition for macro $macroName"; + } + if ($macroPar =~ /^[0-9]+/ || $macroPar =~ /^KEYCODE_/) { + $hash->{adb}{preset}{_custom_}{$macroName} = $macroPar; + } + else { + $hash->{adb}{macro}{_custom_}{$macroName} = $macroPar; + } + } + } + elsif ($attrName eq 'presetFile') { + if (!LoadPresets ($hash, $attrVal)) { + return "Cannot load presets from file $attrVal"; + } + } + elsif ($attrName eq 'connect') { + AndroidDBHost::Connect ($hash) if (!$init_done && $attrVal eq '1'); + } + } + elsif ($cmd eq 'del') { + delete $hash->{adb}{preset}{_custom_} if (exists($hash->{adb}{preset}{_custom_})); + } - return undef; + return undef; } ############################################################################## @@ -433,101 +434,101 @@ sub Attr ($@) sub LoadPresets ($$) { - my ($hash, $fileName) = @_; + my ($hash, $fileName) = @_; - # Read file - my @lines; - if (open (PRESETFILE, "<$fileName")) { - @lines = ; - close (PRESETFILE); - } - else { - ShowMessage ($hash, 2, "Can't open file $fileName"); - return 0; - } + # Read file + my @lines; + if (open (PRESETFILE, "<$fileName")) { + @lines = ; + close (PRESETFILE); + } + else { + ShowMessage ($hash, 2, "Can't open file $fileName"); + return 0; + } - # Delete old presets - my @presets = keys %{$hash->{adb}{preset}}; - my @macros = keys %{$hash->{adb}{macro}}; - foreach my $e (@presets) { delete $hash->{adb}{preset}{$e} if ($e ne '_custom_'); } - foreach my $e (@macros) { delete $hash->{adb}{macro}{$e} if ($e ne '_custom_'); } + # Delete old presets + my @presets = keys %{$hash->{adb}{preset}}; + my @macros = keys %{$hash->{adb}{macro}}; + foreach my $e (@presets) { delete $hash->{adb}{preset}{$e} if ($e ne '_custom_'); } + foreach my $e (@macros) { delete $hash->{adb}{macro}{$e} if ($e ne '_custom_'); } - chomp @lines; - my $presetName = ''; - - foreach my $l (@lines) { - next if ($l =~ /^#/); # Comments are allowed + chomp @lines; + my $presetName = ''; + + foreach my $l (@lines) { + next if ($l =~ /^#/); # Comments are allowed - my ($macroName, $macroPar) = split (':', $l); - if (!defined($macroPar)) { - next if (!defined($macroName) || $macroName eq ''); - if ($macroName !~ /^[a-zA-Z0-9-_]+$/) { - ShowMessage ($hash, 2, "Invalid character in macro name $macroName in file $fileName"); - return 0; - } - $presetName = $macroName; - } - else { - if ($presetName eq '') { - ShowMessage ($hash, 2, "No preset name set for macro name $macroName in file $fileName"); - return 0; - } - if ($macroPar =~ /^[0-9]+/ || $macroPar =~ /^(KEYCODE_|--longpress)/) { - $hash->{adb}{preset}{$presetName}{$macroName} = $macroPar; - } - else { - $hash->{adb}{macro}{$presetName}{$macroName} = $macroPar; - } - } - } - - # Init options of attribute 'preset' - InitAfterStart ($hash); - - return 1; + my ($macroName, $macroPar) = split (':', $l); + if (!defined($macroPar)) { + next if (!defined($macroName) || $macroName eq ''); + if ($macroName !~ /^[a-zA-Z0-9-_]+$/) { + ShowMessage ($hash, 2, "Invalid character in macro name $macroName in file $fileName"); + return 0; + } + $presetName = $macroName; + } + else { + if ($presetName eq '') { + ShowMessage ($hash, 2, "No preset name set for macro name $macroName in file $fileName"); + return 0; + } + if ($macroPar =~ /^[0-9]+/ || $macroPar =~ /^(KEYCODE_|--longpress)/) { + $hash->{adb}{preset}{$presetName}{$macroName} = $macroPar; + } + else { + $hash->{adb}{macro}{$presetName}{$macroName} = $macroPar; + } + } + } + + # Init options of attribute 'preset' + InitAfterStart ($hash); + + return 1; } sub ExportPresets ($$) { - my ($hash, $filename) = @_; + my ($hash, $filename) = @_; - if (open (PRESETFILE, ">$filename")) { - foreach my $preset (sort keys %{$hash->{adb}{preset}}) { - next if ($preset eq '_custom_'); - print PRESETFILE "#\n# Preset $preset\n#\n$preset\n#\n"; - foreach my $macro (sort keys %{$hash->{adb}{preset}{$preset}}) { - print PRESETFILE "$macro:$hash->{adb}{preset}{$preset}{$macro}\n"; - } - if (exists($hash->{adb}{macro}{$preset})) { - foreach my $macro (sort keys %{$hash->{adb}{macro}{$preset}}) { - print PRESETFILE "$macro:$hash->{adb}{macro}{$preset}{$macro}\n"; - } - } - } - foreach my $preset (sort keys %{$hash->{adb}{macro}}) { - next if ($preset eq '_custom_' || exists($hash->{adb}{preset}{$preset})); - print PRESETFILE "#\n# Preset $preset\n#\n$preset\n#\n"; - foreach my $macro (sort keys %{$hash->{adb}{macro}{$preset}}) { - print PRESETFILE "$macro:$hash->{adb}{macro}{$preset}{$macro}\n"; - } - } - close (PRESETFILE); - return 1; - } - - return 0; + if (open (PRESETFILE, ">$filename")) { + foreach my $preset (sort keys %{$hash->{adb}{preset}}) { + next if ($preset eq '_custom_'); + print PRESETFILE "#\n# Preset $preset\n#\n$preset\n#\n"; + foreach my $macro (sort keys %{$hash->{adb}{preset}{$preset}}) { + print PRESETFILE "$macro:$hash->{adb}{preset}{$preset}{$macro}\n"; + } + if (exists($hash->{adb}{macro}{$preset})) { + foreach my $macro (sort keys %{$hash->{adb}{macro}{$preset}}) { + print PRESETFILE "$macro:$hash->{adb}{macro}{$preset}{$macro}\n"; + } + } + } + foreach my $preset (sort keys %{$hash->{adb}{macro}}) { + next if ($preset eq '_custom_' || exists($hash->{adb}{preset}{$preset})); + print PRESETFILE "#\n# Preset $preset\n#\n$preset\n#\n"; + foreach my $macro (sort keys %{$hash->{adb}{macro}{$preset}}) { + print PRESETFILE "$macro:$hash->{adb}{macro}{$preset}{$macro}\n"; + } + } + close (PRESETFILE); + return 1; + } + + return 0; } sub ShowMessage ($$$) { - my ($hash, $level, $msg) = @_; - - Log3 $hash->{NAME}, $level, $msg; - - if ($init_done && exists($hash->{CL})) { - my $cl = $hash->{CL}; - InternalTimer (gettimeofday()+1, sub { asyncOutput ($cl, $msg) }, undef, 1); - } + my ($hash, $level, $msg) = @_; + + Log3 $hash->{NAME}, $level, $msg; + + if ($init_done && exists($hash->{CL})) { + my $cl = $hash->{CL}; + InternalTimer (gettimeofday()+1, sub { asyncOutput ($cl, $msg) }, undef, 1); + } } ############################################################################## @@ -535,22 +536,22 @@ sub ShowMessage ($$$) ############################################################################## sub RCLayoutMagentaTVStick () { - my @row = ( - 'sendKey KEYCODE_POWER:POWEROFF,:blank,sendKey KEYCODE_VOLUME_MUTE:MUTE', - ':blank,sendKey KEYCODE_TV_INPUT_HDMI_3:PS3Rectangle,:blank', - ':blank,sendKey KEYCODE_ALL_APPS:TOOLS,:blank', - 'sendKey KEYCODE_TV_INPUT_HDMI_4:TV,:blank,sendKey KEYCODE_TV_INPUT_HDMI_2:GUIDE', - ':blank,sendKey KEYCODE_DPAD_UP:UP,:blank', - 'sendKey KEYCODE_DPAD_LEFT:LEFT,sendKey KEYCODE_DPAD_CENTER:OK,sendKey KEYCODE_DPAD_RIGHT:RIGHT', - ':blank,sendKey KEYCODE_DPAD_DOWN:DOWN,:blank', - 'sendKey KEYCODE_BACK:BACKDroid,sendKey KEYCODE_HOME:HOMEDroid,sendKey KEYCODE_INFO:INFO', - 'sendKey KEYCODE_MEDIA_RECORD:REC,sendKey KEYCODE_TV_INPUT_HDMI_1:SEARCH,sendKey KEYCODE_VOLUME_UP:VOLUP', - 'sendKey KEYCODE_MEDIA_PLAY_PAUSE:PLAYPAUSE,sendKey KEYCODE_ASSIST:SOURCE,sendKey KEYCODE_VOLUME_DOWN:VOLDOWN', - 'attr rc_iconpath icons/remotecontrol', - 'attr rc_iconprefix black_btn_' - ); - - return @row; + my @row = ( + 'sendKey KEYCODE_POWER:POWEROFF,:blank,sendKey KEYCODE_VOLUME_MUTE:MUTE', + ':blank,sendKey KEYCODE_TV_INPUT_HDMI_3:PS3Rectangle,:blank', + ':blank,sendKey KEYCODE_ALL_APPS:TOOLS,:blank', + 'sendKey KEYCODE_TV_INPUT_HDMI_4:TV,:blank,sendKey KEYCODE_TV_INPUT_HDMI_2:GUIDE', + ':blank,sendKey KEYCODE_DPAD_UP:UP,:blank', + 'sendKey KEYCODE_DPAD_LEFT:LEFT,sendKey KEYCODE_DPAD_CENTER:OK,sendKey KEYCODE_DPAD_RIGHT:RIGHT', + ':blank,sendKey KEYCODE_DPAD_DOWN:DOWN,:blank', + 'sendKey KEYCODE_BACK:BACKDroid,sendKey KEYCODE_HOME:HOMEDroid,sendKey KEYCODE_INFO:INFO', + 'sendKey KEYCODE_MEDIA_RECORD:REC,sendKey KEYCODE_TV_INPUT_HDMI_1:SEARCH,sendKey KEYCODE_VOLUME_UP:VOLUP', + 'sendKey KEYCODE_MEDIA_PLAY_PAUSE:PLAYPAUSE,sendKey KEYCODE_ASSIST:SOURCE,sendKey KEYCODE_VOLUME_DOWN:VOLDOWN', + 'attr rc_iconpath icons/remotecontrol', + 'attr rc_iconprefix black_btn_' + ); + + return @row; } ############################################################################## @@ -558,25 +559,25 @@ sub RCLayoutMagentaTVStick () { ############################################################################## sub RCLayoutMagentaOne () { - my @row = ( - 'sendKey KEYCODE_POWER:POWEROFF,:blank,sendKey KEYCODE_VOLUME_MUTE:MUTE', - ':blank,:blank,:blank', - 'sendKey KEYCODE_TV_INPUT_HDMI_1:SEARCH,sendKey KEYCODE_ASSIST:SOURCE,sendKey KEYCODE_GUIDE:GUIDE', - 'sendKey KEYCODE_BACK:BACKDroid,sendKey KEYCODE_HOME:HOMEDroid,sendKey KEYCODE_ALL_APPS:MENUDroid', - ':blank,sendKey KEYCODE_DPAD_UP:UP,:blank', - 'sendKey KEYCODE_DPAD_LEFT:LEFT,sendKey KEYCODE_DPAD_CENTER:OK,sendKey KEYCODE_DPAD_RIGHT:RIGHT', - ':blank,sendKey KEYCODE_DPAD_DOWN:DOWN,:blank', - 'sendKey KEYCODE_VOLUME_UP:VOLUP,sendKey KEYCODE_MEDIA_PLAY_PAUSE:PLAYPAUSE,sendKey KEYCODE_CHANNEL_UP:CHUP', - 'sendKey KEYCODE_VOLUME_DOWN:VOLDOWN,:blank,sendKey KEYCODE_CHANNEL_DOWN:CHDOWN', - 'sendKey KEYCODE_1:1,sendKey KEYCODE_2:2,sendKey KEYCODE_3:3', - 'sendKey KEYCODE_4:4,sendKey KEYCODE_5:5,sendKey KEYCODE_6:6', - 'sendKey KEYCODE_7:7,sendKey KEYCODE_8:8,sendKey KEYCODE_9:9', - 'sendKey KEYCODE_INFO:INFO,sendKey KEYCODE_0:0,sendKey KEYCODE_MEDIA_RECORD:REC', - 'attr rc_iconpath icons/remotecontrol', - 'attr rc_iconprefix black_btn_' - ); - - return @row; + my @row = ( + 'sendKey KEYCODE_POWER:POWEROFF,:blank,sendKey KEYCODE_VOLUME_MUTE:MUTE', + ':blank,:blank,:blank', + 'sendKey KEYCODE_TV_INPUT_HDMI_1:SEARCH,sendKey KEYCODE_ASSIST:SOURCE,sendKey KEYCODE_GUIDE:GUIDE', + 'sendKey KEYCODE_BACK:BACKDroid,sendKey KEYCODE_HOME:HOMEDroid,sendKey KEYCODE_ALL_APPS:MENUDroid', + ':blank,sendKey KEYCODE_DPAD_UP:UP,:blank', + 'sendKey KEYCODE_DPAD_LEFT:LEFT,sendKey KEYCODE_DPAD_CENTER:OK,sendKey KEYCODE_DPAD_RIGHT:RIGHT', + ':blank,sendKey KEYCODE_DPAD_DOWN:DOWN,:blank', + 'sendKey KEYCODE_VOLUME_UP:VOLUP,sendKey KEYCODE_MEDIA_PLAY_PAUSE:PLAYPAUSE,sendKey KEYCODE_CHANNEL_UP:CHUP', + 'sendKey KEYCODE_VOLUME_DOWN:VOLDOWN,:blank,sendKey KEYCODE_CHANNEL_DOWN:CHDOWN', + 'sendKey KEYCODE_1:1,sendKey KEYCODE_2:2,sendKey KEYCODE_3:3', + 'sendKey KEYCODE_4:4,sendKey KEYCODE_5:5,sendKey KEYCODE_6:6', + 'sendKey KEYCODE_7:7,sendKey KEYCODE_8:8,sendKey KEYCODE_9:9', + 'sendKey KEYCODE_INFO:INFO,sendKey KEYCODE_0:0,sendKey KEYCODE_MEDIA_RECORD:REC', + 'attr rc_iconpath icons/remotecontrol', + 'attr rc_iconprefix black_btn_' + ); + + return @row; } ############################################################################## @@ -584,26 +585,26 @@ sub RCLayoutMagentaOne () { ############################################################################## sub RCLayoutMagentaTVExt () { - my @row = ( - 'sendKey KEYCODE_POWER:POWEROFF,:blank,sendKey KEYCODE_VOLUME_MUTE:MUTE,:blank', - ':blank,:blank,:blank,:blank', - 'sendKey KEYCODE_TV_INPUT_HDMI_1:SEARCH,sendKey KEYCODE_ASSIST:SOURCE,sendKey KEYCODE_GUIDE:GUIDE,sendKey KEYCODE_TV_INPUT_HDMI_4:TV', - 'sendKey KEYCODE_BACK:BACKDroid,sendKey KEYCODE_HOME:HOMEDroid,sendKey KEYCODE_ALL_APPS:MENUDroid,:blank', - ':blank,sendKey KEYCODE_DPAD_UP:UP,:blank,:blank', - 'sendKey KEYCODE_DPAD_LEFT:LEFT,sendKey KEYCODE_DPAD_CENTER:OK,sendKey KEYCODE_DPAD_RIGHT:RIGHT,:blank', - ':blank,sendKey KEYCODE_DPAD_DOWN:DOWN,:blank,:blank', - 'sendKey KEYCODE_VOLUME_UP:VOLUP,sendKey KEYCODE_MEDIA_PLAY_PAUSE:PLAYPAUSE,sendKey KEYCODE_CHANNEL_UP:CHUP,:blank', - 'sendKey KEYCODE_VOLUME_DOWN:VOLDOWN,:blank,sendKey KEYCODE_CHANNEL_DOWN:CHDOWN,:blank', - 'sendKey KEYCODE_1:1,sendKey KEYCODE_2:2,sendKey KEYCODE_3:3,:blank', - 'sendKey KEYCODE_4:4,sendKey KEYCODE_5:5,sendKey KEYCODE_6:6,:blank', - 'sendKey KEYCODE_7:7,sendKey KEYCODE_8:8,sendKey KEYCODE_9:9,:blank', - 'sendKey KEYCODE_INFO:INFO,sendKey KEYCODE_0:0,sendKey KEYCODE_MEDIA_RECORD:REC,:blank', - 'sendKey KEYCODE_PROG_RED:RED,sendKey KEYCODE_PROG_GREEN:GREEN,sendKey KEYCODE_PROG_YELLOW:YELLOW,sendKey KEYCODE_PROG_BLUE:BLUE', - 'attr rc_iconpath icons/remotecontrol', - 'attr rc_iconprefix black_btn_' - ); - - return @row; + my @row = ( + 'sendKey KEYCODE_POWER:POWEROFF,:blank,sendKey KEYCODE_VOLUME_MUTE:MUTE,:blank', + ':blank,:blank,:blank,:blank', + 'sendKey KEYCODE_TV_INPUT_HDMI_1:SEARCH,sendKey KEYCODE_ASSIST:SOURCE,sendKey KEYCODE_GUIDE:GUIDE,sendKey KEYCODE_TV_INPUT_HDMI_4:TV', + 'sendKey KEYCODE_BACK:BACKDroid,sendKey KEYCODE_HOME:HOMEDroid,sendKey KEYCODE_ALL_APPS:MENUDroid,:blank', + ':blank,sendKey KEYCODE_DPAD_UP:UP,:blank,:blank', + 'sendKey KEYCODE_DPAD_LEFT:LEFT,sendKey KEYCODE_DPAD_CENTER:OK,sendKey KEYCODE_DPAD_RIGHT:RIGHT,:blank', + ':blank,sendKey KEYCODE_DPAD_DOWN:DOWN,:blank,:blank', + 'sendKey KEYCODE_VOLUME_UP:VOLUP,sendKey KEYCODE_MEDIA_PLAY_PAUSE:PLAYPAUSE,sendKey KEYCODE_CHANNEL_UP:CHUP,:blank', + 'sendKey KEYCODE_VOLUME_DOWN:VOLDOWN,:blank,sendKey KEYCODE_CHANNEL_DOWN:CHDOWN,:blank', + 'sendKey KEYCODE_1:1,sendKey KEYCODE_2:2,sendKey KEYCODE_3:3,:blank', + 'sendKey KEYCODE_4:4,sendKey KEYCODE_5:5,sendKey KEYCODE_6:6,:blank', + 'sendKey KEYCODE_7:7,sendKey KEYCODE_8:8,sendKey KEYCODE_9:9,:blank', + 'sendKey KEYCODE_INFO:INFO,sendKey KEYCODE_0:0,sendKey KEYCODE_MEDIA_RECORD:REC,:blank', + 'sendKey KEYCODE_PROG_RED:RED,sendKey KEYCODE_PROG_GREEN:GREEN,sendKey KEYCODE_PROG_YELLOW:YELLOW,sendKey KEYCODE_PROG_BLUE:BLUE', + 'attr rc_iconpath icons/remotecontrol', + 'attr rc_iconprefix black_btn_' + ); + + return @row; } 1; @@ -617,17 +618,17 @@ sub RCLayoutMagentaTVExt () {

AndroidDB

@@ -635,56 +636,56 @@ sub RCLayoutMagentaTVExt () { Set

Get

@@ -692,48 +693,48 @@ sub RCLayoutMagentaTVExt () { =end html diff --git a/fhem/FHEM/89_AndroidDBHost.pm b/fhem/FHEM/89_AndroidDBHost.pm index 0481b9118..dd476a445 100644 --- a/fhem/FHEM/89_AndroidDBHost.pm +++ b/fhem/FHEM/89_AndroidDBHost.pm @@ -4,7 +4,7 @@ # # 89_AndroidDBHost # -# Version 0.6 +# Version 0.7 # # FHEM Integration for Android Debug Bridge # @@ -23,6 +23,7 @@ package main; use strict; use warnings; +use SetExtensions; sub AndroidDBHost_Initialize ($) { @@ -35,18 +36,18 @@ sub AndroidDBHost_Initialize ($) $hash->{NotifyFn} = "AndroidDBHost::Notify"; $hash->{ShutdownFn} = "AndroidDBHost::Shutdown"; - $hash->{parseParams} = 1; + $hash->{parseParams} = 1; } package AndroidDBHost; use strict; use warnings; +use SetExtensions; # use Data::Dumper; use IPC::Open3; -use SetExtensions; # use POSIX; use GPUtils qw(:all); @@ -58,7 +59,7 @@ BEGIN { readingsBulkUpdateIfChanged readingsBeginUpdate readingsEndUpdate - devspec2array + devspec2array Log3 AttrVal ReadingsVal