2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00
fhem-mirror/fhem/contrib/WebViewControl/95_WebViewControl.pm
dirkho d4792c1d03 WebViewControl: first commit
git-svn-id: https://svn.fhem.de/fhem/trunk@8178 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2015-03-09 00:55:07 +00:00

312 lines
8.0 KiB
Perl

################################################################################
# 95_webViewControl.pm
# Modul for FHEM
#
# Modul for communication between WebViewControl Android App and FHEM
#
# contributed by Dirk Hoffmann 01/2013
# $Id:
#
################################################################################
package main;
use Data::Dumper; # for debugging only
use strict;
use warnings;
use URI::Escape;
use vars qw {%data %attr %defs %modules $FW_RET}; #supress errors in Eclipse EPIC
use constant {
webViewControl_Version => '0.5.1_beta',
};
#########################
# Forward declaration
sub webViewControl_Initialize($); # Initialize
sub webViewControl_Define($$); # define <name> WEBVIEWCONTROL
sub webViewControl_Undef($$); # delete
sub webViewControl_modifyJsInclude($); # include js parts
sub webViewControl_Set($@); # set
sub webViewControl_Get($@); # get
sub webViewControl_Cgi(); # analyze and parse URL
sub webViewControl_Attr(@);
#########################
# Global variables
my $fhemUrl = '/webviewcontrol' ;
my %sets = (
'screenBrightness' => 'screenBrightness', # slider,1,1,100',
'volume' => 'volume', # slider,1,1,100',
'keepScreenOn' => 'keepScreenOn',
'toastMessage' => 'toastMessage',
'reload' => 'reload',
'audioPlay' => 'audioPlay',
'audioStop' => 'audioStop',
'ttsSay' => 'ttsSay',
'voiceRec' => 'voiceRec',
'newUrl' => 'newUrl',
'reload' => 'reload',
);
my %gets = (
'powerLevel' => 1,
'powerPlugged' => 1,
'voiceRecognitionLastError' => 1,
'voiceRecognitionLastResult'=> 1,
);
my $FW_encoding="UTF-8"; # like in FHEMWEB: encoding hardcoded
################################################################################
# Implements Initialize function
#
# @param hash $hash hash of device addressed
#
################################################################################
sub webViewControl_Initialize($) {
my ($hash) = @_;
$hash->{DefFn} = 'webViewControl_Define';
$hash->{UndefFn} = 'webViewControl_Undef';
$hash->{SetFn} = 'webViewControl_Set';
$hash->{GetFn} = 'webViewControl_Get';
$hash->{AttrFn} = "webViewControl_Attr";
$hash->{AttrList} = 'loglevel:0,1,2,3,4,5,6 model userJsFile userCssFile '
. $readingFnAttributes;
# CGI
$data{FWEXT}{$fhemUrl}{FUNC} = 'webViewControl_Cgi';
}
################################################################################
# Implements DefFn function
#
# @param hash $hash hash of device addressed
# @param string $def definition string
#
# @return string
#
################################################################################
sub webViewControl_Define($$) {
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
my $name = $hash->{NAME};
return "wrong syntax: define <name> WEBVIEWCONTROL APP-ID" if int(@a)!=3;
$hash->{appID} = $a[2];
$modules{webViewControl}{defptr}{$name} = $hash;
webViewControl_modifyJsInclude($hash);
$hash->{VERSION} = webViewControl_Version;
return undef;
}
#############################
sub webViewControl_Undef($$) {
my ($hash, $name) = @_;
delete($modules{webViewControl}{defptr}{$name});
webViewControl_modifyJsInclude($hash);
return undef;
}
sub webViewControl_Attr (@) {
my (undef, $name, $attr, $val) = @_;
my $hash = $defs{$name};
my $msg = '';
if ($attr eq 'userJsFile' || $attr eq 'userCssFile') {
$attr{$name}{$attr} = $val;
webViewControl_modifyJsInclude($hash);
}
return undef;
}
sub webViewControl_modifyJsInclude($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my @appsArray;
foreach my $appName (keys %{ $modules{webViewControl}{defptr} } ) {
push(@appsArray, '\'' . $modules{webViewControl}{defptr}{$appName}->{appID} . '\': \'' . $appName . '\'');
}
my $vars = 'var wvcDevices = {' . join(', ', @appsArray) . '}';
my $userJs = AttrVal($name, 'userJsFile', '');
$userJs = $userJs ? '<script type="text/javascript" src="/fhem/pgm2/' . $userJs . '"></script>' : '';
my $userCss = AttrVal($name, 'userCssFile', '');
if ($userCss) {
$vars.= '; var wvcUserCssFile="' . $userCss . '"';
}
$data{FWEXT}{$fhemUrl}{SCRIPT} = 'cordova-2.3.0.js"></script>' .
'<script type="text/javascript" src="/fhem/pgm2/webviewcontrol.js"></script>' .
$userJs .
'<script type="text/javascript">' . $vars . '</script>' .
'<script type="text/javascript" charset="UTF-8';
}
###################################
sub webViewControl_Set($@) {
my ($hash, @a) = @_;
my $setArgs = join(' ', sort values %sets);
my $name = shift @a;
if (int(@a) == 1 && $a[0] eq '?') {
my %localSets = %sets;
$localSets{screenBrightness}.=':slider,1,1,255';
$localSets{volume}.=':slider,0,1,15';
my $setArgs = join(' ', sort values %localSets);
return $setArgs;
}
if ((int(@a) < 1) || (!defined $sets{$a[0]}) ) {
return 'Please specify one of following set value: ' . $setArgs;
}
my $cmd = $a[0];
if (! (($sets{$cmd} eq 'reload') || ($sets{$cmd} eq 'audioStop')) ) {
if ($sets{$cmd} eq 'toastMessage' && (int(@a)) < 2) {
return 'Please input a text for toastMessage';
} elsif ($sets{$cmd} eq 'keepScreenOn') {
if ($a[1] ne 'on' && $a[1] ne 'off') {
return 'keepScreenOn needs on of off';
} else {
$a[1] = ($a[1] eq 'on') ? 'true' : 'false';
}
} elsif ($sets{$cmd} eq 'screenBrightness' && (int($a[1]) < 1 || int($a[1]) > 255)) {
return 'screenBrightness needs value from 1 to 255';
} elsif ($sets{$cmd} eq 'volume' && (int($a[1]) < 0 || int($a[1]) > 15)) {
return 'volume needs value from 0 to 15';
} elsif ($sets{$cmd} eq 'audioPlay' && (int(@a)) < 2 ) {
return 'Please input a url where Audio to play.';
} elsif ($sets{$cmd} eq 'ttsSay' && (int(@a)) < 2 ) {
return 'Please input a text to say.';
} elsif ($sets{$cmd} eq 'voiceRec' && ($a[1] ne 'start' && $a[1] ne 'stop')) {
return 'voiceRec must set to start or stop';
} elsif ($sets{$cmd} eq 'newUrl') {
if ((int(@a)) < 2 ) {
return 'Please input a url.';
} else {
shift(@a);
my $v = uri_escape(join(' ', @a));
@a = ($cmd, $v);
}
}
}
my $v = join(' ', @a);
$hash->{CHANGED}[0] = $v;
$hash->{STATE} = $v;
$hash->{lastCmd} = $v;
$hash->{READINGS}{state}{TIME} = TimeNow();
$hash->{READINGS}{state}{VAL} = $v;
return undef;
}
sub webViewControl_Get($@) {
my ($hash, @a) = @_;
return ('argument missing, usage is <attribute>') if(@a!=2);
if(!$gets{$a[1]}) {
return $a[1] . 'Not supported by get. Supported attributes: ' . join(' ', keys %gets) ;
}
my $retVal;
if ($hash->{READINGS}{$a[1]}{VAL}) {
$retVal = $hash->{READINGS}{$a[1]}{VAL};
} else {
$retVal = $a[1] . ' not yet set';
}
return $retVal;
}
##################
# Answer requests for webviewcontrol url for set some readings
sub webViewControl_Cgi() {
my ($htmlarg) = @_; #URL
$htmlarg =~ s/^\///;
my @htmlpart = ();
@htmlpart = split("\\?", $htmlarg) if ($htmlarg); #split URL by ?
if ($htmlpart[1]) {
$htmlpart[1] =~ s,^[?/],,;
my @states = ();
my $name = undef;
my %readings = ();
my $timeNow = TimeNow();
foreach my $pv (split("&", $htmlpart[1])) { #per each URL-section devided by &
$pv =~ s/\+/ /g;
$pv =~ s/%(..)/chr(hex($1))/ge;
my ($p,$v) = split("=",$pv, 2); #$p = parameter, $v = value
$p =~ s/[\r]\n/\\\n/g;
$v =~ s/[\r]\n/\\\n/g;
if ($p eq 'id') {
$name = $v;
} else {
$readings{$p} = $v;
push(@states, $p . '=' . $v);
}
}
if ($modules{webViewControl}{defptr}{$name}) {
my $state = join(', ', @states);
my $hash = $modules{webViewControl}{defptr}{$name};
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "state", $state);
foreach my $reading (keys %readings) {
readingsBulkUpdate($hash, $reading, $readings{$reading});
}
readingsEndUpdate($hash, 1);
}
}
return ("text/html; charset=$FW_encoding", $FW_RET); # $FW_RET composed by FW_pO, FP_pH etc
}
1;
=pod
=begin html
<a name="WebViewControl"></a>
<h3>WebViewControl</h3>
<ul>
WebViewCountrol ist the interface for the android APP WebviewControl
<br><br>
</ul>
=end html
=cut