From 418fc94a06341f596f85eeb2d42fdbfa590d6663 Mon Sep 17 00:00:00 2001 From: Sailor Date: Sun, 6 Oct 2019 16:43:55 +0000 Subject: [PATCH] 73_DoorBird: Feature: Actions on Events git-svn-id: https://svn.fhem.de/fhem/trunk@20321 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/73_DoorBird.pm | 466 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 434 insertions(+), 32 deletions(-) diff --git a/fhem/FHEM/73_DoorBird.pm b/fhem/FHEM/73_DoorBird.pm index 63fe37159..5084fd9ed 100644 --- a/fhem/FHEM/73_DoorBird.pm +++ b/fhem/FHEM/73_DoorBird.pm @@ -81,11 +81,12 @@ sub DoorBird_Initialize($) "SipDevice:" . join(",", devspec2array("TYPE=SIP")) . " " . "SipNumber " . "ImageFileDir " . + "AudioFileDir " . "EventReset " . "SessionIdSec:slider,0,10,600 " . "WaitForHistory " . + "OpsModeList " . "disable:1,0 " . - "debug:1,0 " . "loglevel:slider,0,1,5 " . $readingFnAttributes; } @@ -165,7 +166,6 @@ sub DoorBird_Define($$) $hash->{helper}{URL} = $url; $hash->{helper}{SipDevice} = AttrVal($name,"SipDevice",""); $hash->{helper}{SipNumber} = AttrVal($name, "SipNumber", "**620"); - $hash->{helper}{debug} = 0; $hash->{helper}{PollingTimeout} = AttrVal($name,"PollingTimeout",5); $hash->{helper}{KeepAliveTimeout} = AttrVal($name, "KeepAliveTimeout", 30); $hash->{helper}{MaxHistory} = AttrVal($name, "MaxHistory", 50); @@ -173,8 +173,11 @@ sub DoorBird_Define($$) $hash->{helper}{UdpPort} = AttrVal($name, "UdpPort", 6524); $hash->{helper}{SessionIdSec} = AttrVal($name, "SessionIdSec", 540); $hash->{helper}{ImageFileDir} = AttrVal($name, "ImageFileDir", 0); + $hash->{helper}{AudioFileDir} = AttrVal($name, "AudioFileDir", 0); $hash->{helper}{EventReset} = AttrVal($name, "EventReset", 5); $hash->{helper}{WaitForHistory} = AttrVal($name, "WaitForHistory", 7); + @{$hash->{helper}{OpsModeList}} = split(/ /, AttrVal($name, "OpsModeList", "")); + ${$hash->{helper}{OpsModeListBackup}}[0] = "Initial-gJ8990Gl"; $hash->{helper}{CameraInstalled} = false; $hash->{helper}{SessionId} = 0; $hash->{helper}{UdpMessageId} = 0; @@ -252,6 +255,8 @@ sub DoorBird_Attr(@) my @a = @_; my $name = $a[1]; my $hash = $defs{$name}; + + Log3 $name, 3, $name. " : DoorBird_Attr - Subfunction entered."; ### Check whether disable attribute has been provided if ($a[2] eq "disable") { @@ -278,19 +283,6 @@ sub DoorBird_Attr(@) Log3 $name, 4, $name. " : DoorBird - Device enabled as per attribute."; } } - ### Check whether debug attribute has been provided - elsif ($a[2] eq "debug") { - ### Check whether debug is on - if ($a[3] == true) { - ### Set helper in hash - $hash->{helper}{debug} = true; - } - ### If debug is off - else { - ### Set helper in hash - $hash->{helper}{debug} = false; - } - } ### Check whether UdpPort attribute has been provided elsif ($a[2] eq "UdpPort") { ### Check whether UdpPort is numeric @@ -439,6 +431,18 @@ sub DoorBird_Attr(@) $hash->{helper}{ImageFileDir} = ""; } } + ### Check whether AudioFileSave attribute has been provided + elsif ($a[2] eq "AudioFileDir") { + ### Check whether AudioFileSave is defined + if (defined($a[3])) { + ### Set helper in hash + $hash->{helper}{AudioFileDir} = $a[3]; + } + else { + ### Set helper in hash + $hash->{helper}{AudioFileDir} = ""; + } + } ### Check whether EventReset attribute has been provided elsif ($a[2] eq "EventReset") { ### Remove Timer for Event Reset @@ -470,6 +474,25 @@ sub DoorBird_Attr(@) $hash->{helper}{WaitForHistory} = 5; } } + ### Check whether OpsModeList attribute has been provided + elsif ($a[2] eq "OpsModeList") { + ### If the attribute has not been deleted entirely or is empty + if (defined $a[3]) { + ### Save backup and empty string as internal + @{$hash->{helper}{OpsModeList}} = split(/ /, $a[3]); + + ### Update depending Readings + DoorBird_OpsModeUpdate($hash); + } + ### If the attribute has been deleted entirely or is empty + else { + ### Save backup and empty string as internal + @{$hash->{helper}{OpsModeList}} = ""; + + ### Update depending Readings + DoorBird_OpsModeUpdate($hash); + } + } ### If no attributes of the above known ones have been selected else { # Do nothing @@ -581,7 +604,9 @@ sub DoorBird_Set($@) my $command = shift @a; my $option = shift @a; my $optionString; + my $AudioFileDir = $hash->{helper}{AudioFileDir}; my @RelayAdresses = @{$hash->{helper}{RelayAdresses}}; + my @OpsModeList = @{$hash->{helper}{OpsModeList}}; ### Create String to avoid perl warning if option is empty if (defined $option) { @@ -597,15 +622,104 @@ sub DoorBird_Set($@) Log3 $name, 5, $name. " : DoorBird_Set - command : " . $command; Log3 $name, 5, $name. " : DoorBird_Set - option : " . $optionString; Log3 $name, 5, $name. " : DoorBird_Set - RelayAdresses : " . join(",", @RelayAdresses); + Log3 $name, 5, $name. " : DoorBird_Set - OpsModeList : " . join(",", @OpsModeList); ### Define "set" menu - my $usage = "Unknown argument, choose one of "; - $usage .= "Open_Door:" . join(",", @RelayAdresses) . " Restart:noArg Transmit_Audio "; + my $usage = "Unknown argument, choose one of"; + $usage .= " Test"; + $usage .= " Open_Door:" . join(",", @RelayAdresses) . " OpsMode:" . join(",", @OpsModeList) . " Restart:noArg Transmit_Audio"; + + ### If the OpsModeList is not empty + if (${$hash->{helper}{OpsModeList}}[0] ne "") { + + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_Set - The OpsModeList is empty"; + Log3 $name, 5, $name. " : DoorBird_Set - OpsModeList : " . Dumper(@{$hash->{helper}{OpsModeList}}); + + ### For each item in the list of possible Operation Modes + foreach (@OpsModeList) { + + ### Set Prefix for ReadingsName + my $OpsModeReadingPrefix = "OpsMode" . $_; + + ### For each DoorBirdEvent, create setlist for relays to be activated in case of event + $usage .= " " . $OpsModeReadingPrefix . "DoorbellRelay:" . "Off," . join(",", @RelayAdresses); + $usage .= " " . $OpsModeReadingPrefix . "MotionRelay:" . "Off," . join(",", @RelayAdresses); + #$usage .= " " . $OpsModeReadingPrefix . "KeypadRelay:" . "Off," . join(",", @RelayAdresses); + + ### If the Attribute for the directories of the audiofiles have bene provided + if ($AudioFileDir ne "") { + + ### Get current working directory + my $cwd = getcwd(); + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_Set - working directory : " . $cwd; + + ### If the path is given as UNIX file system format + if ($cwd =~ /\//) { + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_Set - file system format : LINUX"; + + ### Find out whether it is an absolute path or an relative one (leading "/") + if ($AudioFileDir =~ /^\//) { + $AudioFileDir = $AudioFileDir; + } + else { + $AudioFileDir = $cwd . "/" . $AudioFileDir; + } + + ### Remove last / of directory if exists + $AudioFileDir =~ s/\/\z//; + + } + ### If the path is given as Windows file system format + elsif ($cwd =~ /\\/) { + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_Set - file system format : WINDOWS"; + + ### Find out whether it is an absolute path or an relative one (containing ":\") + if ($AudioFileDir != /^.:\//) { + $AudioFileDir = $cwd . $AudioFileDir; + } + else { + $AudioFileDir = $AudioFileDir; + } + + ### Remove last \ of directory if exists + $AudioFileDir =~ s/\\\z//; + + } + ### If nothing matches above + else { + ### Set directory to nothing + $AudioFileDir = ""; + } + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_Set - AudioFileDir : " . $AudioFileDir; + + ### Get content of subdirectory and eliminate the root directories "." and ".." + opendir(ReadOut,$AudioFileDir) || die $!; + my @AudioFileList = grep(/^([^.]+)./, readdir(ReadOut)); + close ReadOut; + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_Set - AudioFileList : " . join(",", @AudioFileList); + + ### For each DoorBirdEvent, create setlist for the file path for the audio messages + $usage .= " " . $OpsModeReadingPrefix . "DoorbellAudio:Off,". join(",", @AudioFileList); + $usage .= " " . $OpsModeReadingPrefix . "MotionAudio:Off,". join(",", @AudioFileList); + #$usage .= " " . $OpsModeReadingPrefix . "KeypadAudio:Off," . join(",", @AudioFileList); + } + } + } ### If DoorBird has a Camera installed if ($hash->{helper}{CameraInstalled} == true) { ### Create Selection List for camera - $usage .= "Live_Video:on,off Light_On:noArg Live_Audio:on,off "; + $usage .= " Live_Video:on,off Light_On:noArg Live_Audio:on,off "; } ### If DoorBird has NO Camera installed else { @@ -618,6 +732,8 @@ sub DoorBird_Set($@) ### Log Entry for debugging purposes Log3 $name, 5, $name. " : DoorBird_Set - usage : " . $usage; + ######### Section for response on set-command ######### + ### LIVE VIDEO REQUEST if ($command eq "Live_Video") { ### Call Subroutine and hand back return value @@ -626,7 +742,8 @@ sub DoorBird_Set($@) ### OPEN DOOR elsif ($command eq "Open_Door") { ### Call Subroutine and hand back return value - return DoorBird_Open_Door($hash, $option) + $hash->{helper}{OpenRelay} = $option; + return DoorBird_Open_Door($hash); } ### LIGHT ON elsif ($command eq "Light_On") { @@ -644,24 +761,263 @@ sub DoorBird_Set($@) ### Call Subroutine and hand back return value return DoorBird_Live_Audio($hash, $option) } - ### LIVE AUDIO TRANSMIT elsif ($command eq "Transmit_Audio") { ### Call Subroutine and hand back return value return DoorBird_Transmit_Audio($hash, $option) } + ### TEST + elsif ($command eq "Test") { + ### Call Subroutine and hand back return value + return DoorBird_OpsModeExecute($hash, "doorbell") + } ### ADD OR CHANGE FAVORITE ### DELETE FAVORITE ### ADD OR UPDATE SCHEDULE ENTRY ### DELETE SCHEDULE ENTRY ### If none of the above have been selected else { - ### Do nothing + ### Update Reading + readingsSingleUpdate($hash, $command, $option, 1); + + ### Save new Readings in stat file + WriteStatefile(); return } } ####END####### Manipulate service after "Set" command by fhem ##################################################END##### +###START###### Update Readings and variables after update of Operation Mode ###################################START#### +sub DoorBird_OpsModeUpdate($) { + my ($hash) = @_; + + ### Obtain values from hash + my $name = $hash->{NAME}; + my @OpsModeList = @{$hash->{helper}{OpsModeList}}; + my $OpsModeActive = ReadingsVal($name, "OpsMode", ""); + my $AudioFileDir = $hash->{helper}{AudioFileDir}; + + ### Log Entry for debugging purposes + Log3 $name, 3, $name. " : DoorBird_OpsModeUpdate ____________________________________________________________"; + Log3 $name, 3, $name. " : DoorBird_OpsModeUpdate - OpsModeList : " . Dumper(@{$hash->{helper}{OpsModeList}}); + Log3 $name, 3, $name. " : DoorBird_OpsModeUpdate - OpsModeListBackup : " . Dumper(@{$hash->{helper}{OpsModeListBackup}}); + Log3 $name, 3, $name. " : DoorBird_OpsModeUpdate - Size of OpsModeList : " . @OpsModeList; + Log3 $name, 3, $name. " : DoorBird_OpsModeUpdate - OpsModeActive : " . $OpsModeActive; + Log3 $name, 3, $name. " : DoorBird_OpsModeUpdate - AudioFileDir : " . $AudioFileDir; + + + ### If the OpsModeList has not been deleted (is not empty) and the list has not been changed + if ((${$hash->{helper}{OpsModeList}}[0] ne "") && (${$hash->{helper}{OpsModeListBackup}}[0] ne "Initial-gJ8990Gl")) { + + ### Save new list as backup + @{$hash->{helper}{OpsModeListBackup}} = @{$hash->{helper}{OpsModeList}}; + + ### Extract all names of Readings which start with "OpsMode" + my @OpsModeReadings = grep(/OpsMode/, keys(%{$hash->{READINGS}})); + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - The OpsModeList is filled "; + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - OpsModeList : " . Dumper(@{$hash->{helper}{OpsModeList}}); + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - Readings : " . Dumper(@OpsModeReadings); + + ### Delete all Readings which start with "OpsMode" + foreach (@OpsModeReadings) { + ### Delete all depending Readings + readingsDelete($hash, $_); + } + + ### Update Reading for the active Operation Mode with the first item of the list + readingsSingleUpdate($hash, "OpsMode", ${$hash->{helper}{OpsModeList}}[0], 1); + + ### For each item in the list of possible Operation Modes + foreach (@OpsModeList) { + + ### Set Prefix for ReadingsName + my $OpsModeReadingPrefix = "OpsMode" . $_; + + ### For each DoorBirdEvent, create Reading for the file path for the audio messages + readingsSingleUpdate($hash, $OpsModeReadingPrefix . "DoorbellAudio", "", 1); + readingsSingleUpdate($hash, $OpsModeReadingPrefix . "MotionAudio", "", 1); + #readingsSingleUpdate($hash, $OpsModeReadingPrefix . "KeypadAudio", "", 1); + + ### For each DoorBirdEvent, create Reading for relays to be activated in case of event + readingsSingleUpdate($hash, $OpsModeReadingPrefix . "DoorbellRelay", "", 1); + readingsSingleUpdate($hash, $OpsModeReadingPrefix . "MotionRelay", "", 1); + #readingsSingleUpdate($hash, $OpsModeReadingPrefix . "KeypadRelay", "", 1); + } + ### Save new Readings in stat file + WriteStatefile(); + } + ### If the OpsModeList is empty + else { + ### Extract all names of Readings which start with "OpsMode" + my @OpsModeReadings = grep(/OpsMode/, keys(%{$hash->{READINGS}})); + + ### Save new list as backup + @{$hash->{helper}{OpsModeListBackup}} = @{$hash->{helper}{OpsModeList}}; + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - The OpsModeList is empty"; + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - OpsModeList : " . Dumper(@{$hash->{helper}{OpsModeList}}); + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - OpsModeListBackup : " . Dumper(@{$hash->{helper}{OpsModeListBackup}}); + Log3 $name, 5, $name. " : DoorBird_OpsModeUpdate - Readings : " . Dumper(@OpsModeReadings); + + ### Delete all Readings which start with "OpsMode" + foreach (@OpsModeReadings) { + ### Delete all depending Readings + readingsDelete($hash, $_); + } + } +} +####END####### Update Readings and variables after update of Operation Mode ####################################END##### + +###START###### Execution of automatic events depending on operation mode ######################################START#### +sub DoorBird_OpsModeExecute($$) { + my ($hash, $OpsModeEvent) = @_; + + ### Obtain values from hash + my $name = $hash->{NAME}; + my $AudioFileDir = $hash->{helper}{AudioFileDir}; + my $Sox = $hash->{helper}{SOX}; + my @OpsModeList = @{$hash->{helper}{OpsModeList}}; + my $OpsModeActive = ReadingsVal($name, "OpsMode", ""); + my $OpsModeReadingPrefix = "OpsMode" . $OpsModeActive; + my $ReadingNameRelay; + my $ReadingNameAudio; + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute ___________________________________________________________"; + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - OpsModeList : " . Dumper(@OpsModeList); + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - OpsModeActive : " . $OpsModeActive; + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - AudioFileDir : " . $AudioFileDir; + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - OpsModeEvent : " . $OpsModeEvent; + + ### Get current working directory + my $cwd = getcwd(); + + ### Log Entry for debugging purposes + Log3 $name, 3, $name. " : DoorBird_OpsModeExecute - working directory : " . $cwd; + + ### If the path is given as UNIX file system format + if ($cwd =~ /\//) { + ### Log Entry for debugging purposes + Log3 $name, 3, $name. " : DoorBird_OpsModeExecute - file system format : LINUX"; + + ### Find out whether it is an absolute path or an relative one (leading "/") + if ($AudioFileDir =~ /^\//) { + $AudioFileDir = $AudioFileDir; + } + else { + $AudioFileDir = $cwd . "/" . $AudioFileDir; + } + + ### Remove last / of directory if exists + $AudioFileDir =~ s/\/\z//; + + ### Add last / for definitiv + $AudioFileDir .= "/"; + } + ### If the path is given as Windows file system format + elsif ($cwd =~ /\\/) { + ### Log Entry for debugging purposes + Log3 $name, 3, $name. " : DoorBird_OpsModeExecute - file system format : WINDOWS"; + + ### Find out whether it is an absolute path or an relative one (containing ":\") + if ($AudioFileDir != /^.:\//) { + $AudioFileDir = $cwd . $AudioFileDir; + } + else { + $AudioFileDir = $AudioFileDir; + } + + ### Remove last \ of directory if exists + $AudioFileDir =~ s/\\\z//; + + ### Add last \ for definitiv + $AudioFileDir .= "\\"; + } + ### If nothing matches above + else { + ### Set directory to nothing + $AudioFileDir = ""; + } + + ### If the event has been triggered by a doorbell event + if ($OpsModeEvent =~ m/doorbell/) { + ### Construct name of reading for the current actions + $ReadingNameRelay = $OpsModeReadingPrefix . "DoorbellRelay"; + $ReadingNameAudio = $OpsModeReadingPrefix . "DoorbellAudio"; + } + ### If the event has been triggered by a motion event + elsif ($OpsModeEvent =~ m/motion/) { + ### Construct name of reading for the current actions + $ReadingNameRelay = $OpsModeReadingPrefix . "MotionRelay"; + $ReadingNameAudio = $OpsModeReadingPrefix . "MotionAudio"; + } + ### If the event has been triggered by a keypad event + elsif ($OpsModeEvent =~ m/keypad/) { + ### Construct name of reading for the current actions + $ReadingNameRelay = $OpsModeReadingPrefix . "KeypadRelay"; + $ReadingNameAudio = $OpsModeReadingPrefix . "KeypadAudio"; + } + ### If none of the nown events has been triggering this subroutine + else { + ### Log Entry for debugging purposes + Log3 $name, 3, $name. " : DoorBird_OpsModeExecute - Unknown OpsModeEvent has been triggered. Ignoring."; + + ### Do nothing + } + + ### Get Values of Readings + my $ReadingValueRelay = ReadingsVal($name, "$ReadingNameRelay",""); + my $ReadingValueAudio = ReadingsVal($name, "$ReadingNameAudio",""); + + ### Create full path to audio file + my $AudioFilePath = $AudioFileDir . $ReadingValueAudio; + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - AudioFilePath : " . $AudioFilePath; + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - ReadingValueAudio : " . $ReadingValueAudio; + + ### Create Sox - command + my $SoxCmd = $Sox . " " . $AudioFilePath . " -n stat stats"; + + ### Convert file + my $AudioLength; + + ### If the value of the Readings for audiofile is not empty or "Off" + if ($ReadingValueAudio ne "" && $ReadingValueAudio ne "Off") { + + ### Get FileInfo and extract the length of mediafile in seconds + my @FileInfo = qx($SoxCmd 2>&1); + $AudioLength = $FileInfo[1]; + $AudioLength =~ s/Length \(seconds\)\://; + $AudioLength =~ s/\s+//g; + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_OpsModeExecute - AudioLength : " . $AudioLength; + + + ### Transmit Audiofile + DoorBird_Transmit_Audio($hash, $AudioFilePath); + + ### Log Entry for debugging purposes + Log3 $name, 4, $name. " : DoorBird_OpsModeExecute - Audiofile transmitted : ". $AudioFilePath; + + } + ### If the value of the Readings for relay ID is not empty of "Off" + if ($ReadingValueRelay ne "" && $ReadingValueRelay ne "Off") { + + ### Execute Relay (=Open Door) + $hash->{helper}{OpenRelay} = $ReadingValueRelay; + InternalTimer(gettimeofday()+ $AudioLength, "DoorBird_Open_Door", $hash, 0); + + ### Log Entry for debugging purposes + Log3 $name, 4, $name. " : DoorBird_OpsModeExecute - Relay triggered : ". $ReadingValueRelay; + } +} +####END####### Execution of automatic events depending on operation mode #######################################END##### + ###START###### After return of UDP message ####################################################################START#### sub DoorBird_Read($) { my ($hash) = @_; @@ -1015,6 +1371,9 @@ sub DoorBird_Read($) { $Container{"Reading"} = $ReadingEvent; InternalTimer(gettimeofday()+ $hash->{helper}{EventReset}, "DoorBird_EventReset", \%Container, 0); + ### Execute event trigger for Operation Mode + DoorBird_OpsModeExecute($hash, "motion"); + ### Log Entry Log3 $name, 3, $name. " : An event has been triggered by the DoorBird unit : " . $EVENT; Log3 $name, 5, $name. " : DoorBird_Read - Timer for reset reading in : " . $hash->{helper}{EventReset}; @@ -1077,6 +1436,9 @@ sub DoorBird_Read($) { $Container{"Reading"} = $ReadingEvent; InternalTimer(gettimeofday()+ $hash->{helper}{EventReset}, "DoorBird_EventReset", \%Container, 0); + ### Execute event trigger for Operation Mode + DoorBird_OpsModeExecute($hash, "keypad"); + ### Log Entry Log3 $name, 3, $name. " : An event has been triggered by the DoorBird unit : " . $EVENT; Log3 $name, 5, $name. " : DoorBird_Read - Timer for reset reading in : " . $hash->{helper}{EventReset}; @@ -1139,6 +1501,9 @@ sub DoorBird_Read($) { $Container{"HashReference"} = $hash; $Container{"Reading"} = $ReadingEvent; InternalTimer(gettimeofday()+ $hash->{helper}{EventReset}, "DoorBird_EventReset", \%Container, 0); + + ### Execute event trigger for Operation Mode + DoorBird_OpsModeExecute($hash, "doorbell"); ### Log Entry Log3 $name, 3, $name. " : An event has been triggered by the DoorBird unit : " . $EVENT; @@ -1377,6 +1742,15 @@ sub DoorBird_FW_detailFn($$$$) { my @HistoryDoorbell; my @HistoryMotion; +# ### If Operation Mode(s) have been provided +# if (@{$hash->{helper}{OpsModeList}} > 0) { +# ### Log Entry for debugging purposes +# Log3 $name, 5, $name. " : DoorBird_FW_detailFn - OpsModeList : " . Dumper(@{$hash->{helper}{OpsModeList}}); +# } +# else { +# ### Log Entry for debugging purposes +# Log3 $name, 5, $name. " : DoorBird_FW_detailFn - OpsModeList is empty"; +# } ### Only if DoorBird has a Camera installed view the Image and History Part if ($hash->{helper}{CameraInstalled} == true) { @@ -2268,17 +2642,21 @@ sub DoorBird_LastEvent_Image($$$) { ####END####### Define Subfunction for LAST EVENT IMAGE REQUEST #################################################END##### ###START###### Define Subfunction for OPEN DOOR ###############################################################START#### -sub DoorBird_Open_Door($$) { - my ($hash, $option) = @_; +sub DoorBird_Open_Door($) { + my ($hash) = @_; my $name = $hash->{NAME}; - my $command = "open-door.cgi?r=" . $option; + my $relay = $hash->{helper}{OpenRelay}; + my $command = "open-door.cgi?r=" . $relay; my $method = "GET"; my $header = "Accept: application/json"; my $username = DoorBird_credential_decrypt($hash->{helper}{".USER"}); my $err; my $data; my $json; - + + ### Delete Helper + $hash->{helper}{OpenRelay} = ""; + ### Activate Relay ($err, $data) = DoorBird_BlockGet($hash, $command, $method, $header); @@ -2303,10 +2681,10 @@ sub DoorBird_Open_Door($$) { ### Create return messages and log entries based on error codes returned if ($json->{BHA}{RETURNCODE} eq "1") { ### Log Entry - Log3 $name, 3, $name. " : DoorBird_Open_Door - Door ". $option . " successfully triggered."; + Log3 $name, 3, $name. " : DoorBird_Open_Door - Door ". $relay . " successfully triggered."; ### Create popup message - return "Door ". $option . " successful triggered."; + return "Door ". $relay . " successful triggered."; } elsif ($json->{BHA}{RETURNCODE} eq "204") { ### Log Entry @@ -3512,10 +3890,16 @@ sub DoorBird_BlockGet($$$$) { The default value is **620
+ + + AudioFileDir : The relative (e.g. "audio") or absolute (e.g. "/mnt/NAS/audio") with or without trailing "/" directory path to which the audio files supposed to be stored.
+ The default value is "" = disabled
+ + ImageFileDir : The relative (e.g. "images") or absolute (e.g. "/mnt/NAS/images") with or without trailing "/" directory path to which the image files supposed to be stored.
- The default value is 0 = disabled
+ The default value is "" = disabled
@@ -3530,6 +3914,12 @@ sub DoorBird_BlockGet($$$$) { The default value is 7s
+ + + OpsModeList : A space separated list of names for operational modes (e.g. "Normal Party Fire") on which the DoorBird reacts automatically on events.
+ The default value is "" = disabled
+ + @@ -3637,25 +4027,25 @@ sub DoorBird_BlockGet($$$$) { - KeepAliveTimeout : Timeout in Sekunden ohne "still-alive" - UDP Datagramme bevor der Status des Gerätes auf "disconnected" gesetzt wird.
+ KeepAliveTimeout : Timeout in Sekunden ohne "still-alive" - UDP Datagramme bevor der Status des Gerätes auf "disconnected" gesetzt wird.
Der Default Wert ist 30s
- MaxHistory : Anzahl der herunterzuladenden Bilder aus dem Historien-Archiv sowohl für Ereignisse seitens der Türklingel als auch für den Bewegungssensor.
+ MaxHistory : Anzahl der herunterzuladenden Bilder aus dem Historien-Archiv sowohl für Ereignisse seitens der Türklingel als auch für den Bewegungssensor.
Der Default Wert ist "50" = Maximum.
- PollingTimeout : Timeout in Sekunden before der Download-Versuch aufgrund fehlender Antwort seitens der DoorBird-Anlage terminiert wird. Eine Adjustierung mag notwendig sein, sobald Netzwerk-Latenzen aufteten.
+ PollingTimeout : Timeout in Sekunden before der Download-Versuch aufgrund fehlender Antwort seitens der DoorBird-Anlage terminiert wird. Eine Adjustierung mag notwendig sein, sobald Netzwerk-Latenzen aufteten.
Der Default-Wert ist 10s.
- UdpPort : Port Nummer auf welcher das DoorBird - Modul nach den UDP Datagrammen der DoorBird - Anlage hören soll. Die Ports sind von der Firmware vorgegeben.
+ UdpPort : Port Nummer auf welcher das DoorBird - Modul nach den UDP Datagrammen der DoorBird - Anlage hören soll. Die Ports sind von der Firmware vorgegeben.
Der Default Port ist 6524
@@ -3677,6 +4067,12 @@ sub DoorBird_BlockGet($$$$) { Der Default Wert ist **620
+ + + AudioFileDir : Der relative (z.B. "audio") oder absolute (z.B. "/mnt/NAS/audio") Verzeichnispfad mit oder ohne nachfolgendem Pfadzeichen "/" in welchen die Audio-Dateien abgelegt sind.
+ Der Default Wert ist 0 = deaktiviert
+ + ImageFileDir : Der relative (z.B. "images") oder absolute (z.B. "/mnt/NAS/images") Verzeichnispfad mit oder ohne nachfolgendem Pfadzeichen "/" in welchen die Bild-Dateien gespeichert werden sollen.
@@ -3695,6 +4091,12 @@ sub DoorBird_BlockGet($$$$) { Der Default Wert ist 7s
+ + + OpsModeList : Eine durch Leerzeichen getrennte Liste von Namen für Operationszustände (e.g. "Normal Party Feuer" auf diese der DoorBird automatisch bei Events reagiert.
+ Der Default Wert ist "" = deaktiviert
+ +