############################################## # $Id$ package main; # Documentation: AHA-HTTP-Interface.pdf, AVM_Technical_Note_-_Session_ID.pdf use strict; use warnings; use Time::HiRes qw(gettimeofday); use FritzBoxUtils; sub FBAHAHTTP_Initialize($) { my ($hash) = @_; $hash->{WriteFn} = "FBAHAHTTP_Write"; $hash->{DefFn} = "FBAHAHTTP_Define"; $hash->{SetFn} = "FBAHAHTTP_Set"; $hash->{AttrFn} = "FBAHAHTTP_Attr"; $hash->{AttrList} = "dummy:1,0 fritzbox-user polltime"; } ##################################### sub FBAHAHTTP_Define($$) { my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); return "wrong syntax: define FBAHAHTTP hostname" if(@a != 3); $hash->{Clients} = ":FBDECT:"; my %matchList = ( "1:FBDECT" => ".*" ); $hash->{MatchList} = \%matchList; for my $d (devspec2array("TYPE=FBDECT")) { if($defs{$d}{IODev} && $defs{$d}{IODev}{TYPE} eq "FBAHA") { my $n = $defs{$d}{IODev}{NAME}; CommandAttr(undef, "$d IODev $hash->{NAME}"); CommandDelete(undef, $n) if($defs{$n}); } $defs{$d}{IODev} = $hash } return undef if($hash->{DEF} eq "none"); # DEBUGGING InternalTimer(1, "FBAHAHTTP_Poll", $hash); $hash->{STATE} = "defined"; return undef; } ##################################### sub FBAHAHTTP_Poll($) { my ($hash) = @_; my $name = $hash->{NAME}; my $dr = sub { $hash->{STATE} = $_[0]; Log 2, $hash->{STATE}; return $hash->{STATE}; }; if(!$hash->{".SID"}) { my $fb_user = AttrVal($name, "fritzbox-user", ''); return $dr->("MISSING: attr $name fritzbox-user") if(!$fb_user); my ($err, $fb_pw) = getKeyValue("FBAHAHTTP_PASSWORD_$name"); return $dr->("ERROR: $err") if($err); return $dr->("MISSING: set $name password") if(!$fb_pw); my $sid = FB_doCheckPW($hash->{DEF}, $fb_user, $fb_pw); return $dr->("$name error: cannot get SID, ". "check connection/hostname/fritzbox-user/password") if(!$sid); $hash->{".SID"} = $sid; $hash->{STATE} = "connected"; } my $sid = $hash->{".SID"}; HttpUtils_NonblockingGet({ url=>"http://$hash->{DEF}/webservices/homeautoswitch.lua?sid=$sid". "&switchcmd=getdevicelistinfos", loglevel => AttrVal($name, "verbose", 4), callback => sub { if($_[1]) { Log3 $name, 3, "$name: $_[1]"; delete $hash->{".SID"}; return; } Log 1, $_[2] if(AttrVal($name, "verbose", 1) > 4); if($_[2] !~ m,^$,s) { Log3 $name, 3, "$name: unexpected reply from device: $_[2]"; delete $hash->{".SID"}; return; } $_[2] =~ s+<(device|group) (.*?)+ Dispatch($hash, "<$1 $2", undef);""+gse; # Quick&Hack } }); my $polltime = AttrVal($name, "polltime", 300); RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$polltime, "FBAHAHTTP_Poll", $hash); return; } ##################################### sub FBAHAHTTP_Attr($@) { my ($type, $devName, $attrName, @param) = @_; my $hash = $defs{$devName}; if($attrName eq "fritzbox-user") { return "Cannot delete fritzbox-user" if($type eq "del"); if($init_done) { delete($hash->{".SID"}); FBAHAHTTP_Poll($hash); } } return undef; } ##################################### sub FBAHAHTTP_Set($@) { my ($hash, @a) = @_; my $name = shift @a; my %sets = (password=>2, refreshstate=>1); return "set $name needs at least one parameter" if(@a < 1); my $type = shift @a; return "Unknown argument $type, choose one of refreshstate:noArg password" if(!defined($sets{$type})); return "Missing argument for $type" if(int(@a) < $sets{$type}-1); if($type eq "password") { setKeyValue("FBAHAHTTP_PASSWORD_$name", $a[0]); delete($hash->{".SID"}); FBAHAHTTP_Poll($hash); return; } if($type eq "refreshstate") { FBAHAHTTP_Poll($hash); return; } return undef; } ##################################### sub FBAHAHTTP_Write($$$) { my ($hash,$fn,$msg) = @_; my $name = $hash->{NAME}; my $sid = $hash->{".SID"}; if(!$sid) { Log 1, "$name: Not connected, wont execute $msg"; return; } HttpUtils_NonblockingGet({ url=>"http://$hash->{DEF}/webservices/homeautoswitch.lua?sid=$sid". "&ain=$fn&switchcmd=$msg", loglevel => AttrVal($name, "verbose", 4), callback => sub { if($_[1]) { Log3 $name, 3, "$name: $_[1]"; delete $hash->{".SID"}; return; } Log 5, "FBAHAHTTP_Write reply for $name: $_[2]"; } }); } 1; =pod =begin html

FBAHAHTTP

=end html =cut