diff --git a/fhem/contrib/DoorPi/70_DoorPi.pm b/fhem/contrib/DoorPi/70_DoorPi.pm index b92db920f..855849ac9 100644 --- a/fhem/contrib/DoorPi/70_DoorPi.pm +++ b/fhem/contrib/DoorPi/70_DoorPi.pm @@ -2,11 +2,11 @@ # # DoorPi.pm # -# FHEM module to communite with a Raspberry Pi door station +# FHEM module to communicate with a Raspberry Pi door station # # Prof. Dr. Peter A. Henning, 2016 # -# Version 0.3 - April 2016 +# Version 0.4 - April 2016 # ######################################################################################## # @@ -26,6 +26,7 @@ # GNU General Public License for more details. # ######################################################################################## + package main; use strict; @@ -45,7 +46,6 @@ my %gets = ( "history:noArg" => "H" ); - ######################################################################################## # # DoorPi_Initialize @@ -194,7 +194,7 @@ sub DoorPi_Get ($@) { Log GetLogLevel($name,2), "[DoorPi_Get] $a[1] error $v"; return "$a[0] $a[1] => Error $v"; } - return "$a[0] $a[1] => OK"; + return "$a[0] $a[1] => ok"; } ######################################################################################## @@ -238,15 +238,31 @@ sub DoorPi_Set ($@) { $value = shift @a; return "[DoorPi_Set] With unknown argument $key, choose one of " . join(" ", @{$hash->{HELPER}->{CMDS}}) - if ( !grep( /$key/, @{$hash->{HELPER}->{CMDS}} ) ); + if ( !grep( /$key/, @{$hash->{HELPER}->{CMDS}} ) && !($key eq "call") ); - if( $key eq "$door" ){ + #-- hidden command to be used by DoorPi for adding a new call + if( $key eq "call" ){ + if( $value eq "start" ){ + readingsSingleUpdate($hash,"call","started",1); + }elsif( $value eq "end" ){ + readingsSingleUpdate($hash,"call","ended",1); + DoorPi_GetHistory($hash); + }elsif( $value eq "rejected" ){ + readingsSingleUpdate($hash,"call","rejected",1); + DoorPi_GetHistory($hash); + }elsif( $value eq "dismissed" ){ + readingsSingleUpdate($hash,"call","dismissed",1); + DoorPi_GetHistory($hash); + } + #-- door opening + }elsif( $key eq "$door" ){ if( $value eq "open" ){ $v=DoorPi_Cmd($hash,"door"); if(AttrVal($name, "dooropencmd",undef)){ fhem(AttrVal($name, "dooropencmd",undef)); } } + #-- scene lighting }elsif( $key eq "$light" ){ my $light = AttrVal($name, "lightbutton", "light"); if( $value eq "on" ){ @@ -256,6 +272,7 @@ sub DoorPi_Set ($@) { $v=DoorPi_Cmd($hash,"lightoff"); readingsSingleUpdate($hash,$light,"off",1); } + #-- dashboard lighting }elsif( $key eq "$dashlight" ){ my $dashlight = AttrVal($name, "dashlightbutton", "dashlight"); if( $value eq "on" ){ @@ -277,7 +294,7 @@ sub DoorPi_Set ($@) { Log GetLogLevel($name,2), "[DoorPi_Set] $key error $v"; return "$key => Error $v"; } - return "$key => OK"; + return "$key => ok"; } ####################################################################################### @@ -347,7 +364,7 @@ sub DoorPi_GetConfig () { #-- put into READINGS readingsSingleUpdate($hash,"state","Initialized",1); - readingsSingleUpdate($hash,"config","OK",1); + readingsSingleUpdate($hash,"config","ok",1); return undef; } @@ -459,7 +476,7 @@ sub DoorPi_GetHistory () { $callend = "busy"; last; }elsif( $jhash2->{"state"} eq "Call ended" ){ - $callend = "OK"; + $callend = "ok"; last; } } @@ -496,7 +513,7 @@ sub DoorPi_GetHistory () { $record =~ s/^.*records\///; #-- workaround for buggy DoorPi $record = sprintf("%d-%02d-%2d_%02d-%02d-%02d.wav", $year,($month+1),$day,$hour, $min, $sec) - if( $callend eq "OK"); + if( $callend eq "ok"); #-- this is the snapshot file if taken at the same time my $snapshot = sprintf("%d-%02d-%2d_%02d-%02d-%02d.jpg", $year,($month+1),$day,$hour, $min, $sec); @@ -566,7 +583,7 @@ sub DoorPi_GetHistory () { #--put into READINGS readingsBeginUpdate($hash); readingsBulkUpdate($hash,"number_calls",int(@{ $hash->{DATA}})); - readingsBulkUpdate($hash,"history","OK"); + readingsBulkUpdate($hash,"history","ok"); readingsBulkUpdate($hash,$dashlight,$dashlightstate); readingsBulkUpdate($hash,$light,$lightstate); readingsEndUpdate($hash,1); @@ -598,7 +615,7 @@ sub DoorPi_GetHistory () { $url = "http://".$hash->{TCPIP}."/control/trigger_event?". "event_name=OnKeyPressed_".$hash->{HELPER}->{vkeyboard}.".". $cmd."&event_source=doorpi.keyboard.from_filesystem"; - Log 1,"[DoorPi_Cmd] called with only hash => Issue a non-blocking call to $url"; + #Log 1,"[DoorPi_Cmd] called with only hash => Issue a non-blocking call to $url"; HttpUtils_NonblockingGet({ url => $url, callback=>sub($$$){ DoorPi_Cmd($hash,$cmd,$_[1],$_[2]) } @@ -628,6 +645,8 @@ sub DoorPi_GetHistory () { return undef; } + + ####################################################################################### # # DoorPi_maketable diff --git a/fhem/contrib/DoorPi/doorpi.ini.safe b/fhem/contrib/DoorPi/doorpi.ini.safe index a75bbb8e0..65044fb5e 100644 --- a/fhem/contrib/DoorPi/doorpi.ini.safe +++ b/fhem/contrib/DoorPi/doorpi.ini.safe @@ -55,8 +55,19 @@ guests = dashboard [EVENT_OnStartup] 10 = sleep:1 +#-- notify the FHEM module [EVENT_BeforeSipPhoneMakeCall] -10 = take_snapshot +10 = url_call:http://192.168.0.20:8083/fhem?XHR=1&cmd.DoorPi=set DoorPi call start +20 = take_snapshot + +[EVENT_OnCallStateDisconnect] +10 = url_call:http://192.168.0.20:8083/fhem?XHR=1&cmd.DoorPi=set DoorPi call end + +[EVENT_OnCallStateDismissed] +10 = url_call:http://192.168.0.20:8083/fhem?XHR=1&cmd.DoorPi=set DoorPi call dismissed + +[EVENT_OnCallStateReject] +10 = url_call:http://192.168.0.20:8083/fhem?XHR=1&cmd.DoorPi=set DoorPi call rejected [SIP-Phone] identity = DoorPi @@ -64,7 +75,7 @@ local_port = 5060 firewallpolicy = PolicyNoFirewall # sipphonetyp = linphone -sipserver_password = +sipserver_password = xxxxxxxxxxxx sipserver_realm = fritz.box sipserver_server = 192.168.0.254 sipserver_username = 620 @@ -99,13 +110,16 @@ base_path_input = /home/doorpi/keyboard/inputs/ base_path_output = /home/doorpi/keyboard/outputs/ [webservice_InputPins] -door = out:door,1,0,3 -lighton = out:light -lightoff= out:light -purge = sleep:0 -clear = sleep:0 -button1 = sleep:0 -button2 = sleep:0 +door = out:door,1,0,3 +lighton = out:light,1 +lightonfortimer = out:light,1,0,60 +lightoff = out:light,0 +dashlighton = out:dashlight,1 +dashlightoff = out:dashlight,0 +purge = sleep:0 +clear = sleep:0 +button1 = sleep:0 +button2 = sleep:0 [EVENT_OnKeyPressed_webservice.purge] 10 = os_execute:/home/doorpi/purge.sh purge @@ -113,8 +127,11 @@ button2 = sleep:0 [EVENT_OnKeyPressed_webservice.clear] 10 = os_execute:/home/doorpi/purge.sh clear +[EVENT_OnKeyPressed_webservice.button1] +10 = call:722622 + [EVENT_OnKeyPressed_webservice.button2] -10 = os_execute:/home/doorpi/test.sh +10 = sleep:0 [onboardpins_keyboard] pull_up_down = PUD_UP @@ -122,7 +139,8 @@ pull_up_down = PUD_UP [onboardpins_OutputPins] 0 = door 1 = light -2 = blinking_led +2 = dashlight +3 = blinking_led [onboardpins_InputPins] 0 = call:722622 diff --git a/fhem/contrib/DoorPi/url_call.py b/fhem/contrib/DoorPi/url_call.py new file mode 100644 index 000000000..bab693773 --- /dev/null +++ b/fhem/contrib/DoorPi/url_call.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import logging +logger = logging.getLogger(__name__) +logger.debug("%s loaded", __name__) + +from doorpi.action.base import SingleAction +import doorpi + +import urllib2 +import ssl +import urlparse + +def fire_command(url): + try: + if "@" in url: + nurl = urlparse.urlsplit(url) + username = nurl.username + password = nurl.password + url = url.replace(username + ':' + password + '@', '') + url = url.replace(" ", "%20") + logger.debug('url: %s' % url) + ssl._create_default_https_context = ssl._create_unverified_context + p = urllib2.HTTPPasswordMgrWithDefaultRealm() + p.add_password(None, url, username, password) + handler = urllib2.HTTPBasicAuthHandler(p) + opener = urllib2.build_opener(handler) + urllib2.install_opener(opener) + url = url.replace(" ", "%20") + logger.info('url: %s' % url) + return urllib2.urlopen( + url=url, + data=None, + timeout=1 + ) + except urllib2.HTTPError as exp: + logger.error('HTTPError: %s - %s' % (exp.code, exp.reason)) + except urllib2.URLError as exp: + logger.error('URLError: %s' % exp.reason) + + return False + +def get(parameters): + parsed_parameters = doorpi.DoorPi().parse_string(parameters) + return UrlCallAction(fire_command, url=parsed_parameters) + + +class UrlCallAction(SingleAction): + pass +