73_DoorBird: New Feature for ftui image history
git-svn-id: https://svn.fhem.de/fhem/trunk@21857 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -59,6 +59,7 @@ use LWP::UserAgent;
|
||||
use constant false => 0;
|
||||
use constant true => 1;
|
||||
use Data::Dumper;
|
||||
use File::Spec::Functions ':ALL';
|
||||
|
||||
###START###### Initialize module ##############################################################################START####
|
||||
sub DoorBird_Initialize($)
|
||||
@@ -89,6 +90,7 @@ sub DoorBird_Initialize($)
|
||||
"VideoDurationDoorbell " .
|
||||
"VideoDurationMotion " .
|
||||
"VideoDurationKeypad " .
|
||||
"HistoryFilePath:1,0 " .
|
||||
"EventReset " .
|
||||
"SessionIdSec:slider,0,10,600 " .
|
||||
"WaitForHistory " .
|
||||
@@ -188,6 +190,7 @@ sub DoorBird_Define($$)
|
||||
$hash->{helper}{EventReset} = AttrVal($name, "EventReset", 5);
|
||||
$hash->{helper}{WaitForHistory} = AttrVal($name, "WaitForHistory", 7);
|
||||
$hash->{helper}{CameraInstalled} = false;
|
||||
$hash->{helper}{HistoryFilePath} = 0;
|
||||
$hash->{helper}{SessionId} = 0;
|
||||
$hash->{helper}{UdpMessageId} = 0;
|
||||
$hash->{helper}{UdpMotionId} = 0;
|
||||
@@ -538,6 +541,30 @@ sub DoorBird_Attr(@)
|
||||
$hash->{helper}{VideoDurationKeypad} = "0";
|
||||
}
|
||||
}
|
||||
### Check whether HistoryFilePath attribute has been provided
|
||||
elsif ($a[2] eq "HistoryFilePath") {
|
||||
### Check whether HistoryFilePath is defined
|
||||
if (defined($a[3])) {
|
||||
### Set helper in hash
|
||||
$hash->{helper}{HistoryFilePath} = $a[3];
|
||||
|
||||
if ($a[3] == true) {
|
||||
### Update the history list for images and videos
|
||||
DoorBird_History_List($hash);
|
||||
}
|
||||
else {
|
||||
### Delete all reading entries to files
|
||||
fhem("deleteReading " . $name . " HistoryFilePath.*");
|
||||
}
|
||||
}
|
||||
else {
|
||||
### Set helper in hash
|
||||
$hash->{helper}{HistoryFilePath} = "0";
|
||||
|
||||
### Delete all reading entries to files
|
||||
fhem("deleteReading " . $name . " HistoryFilePath.*");
|
||||
}
|
||||
}
|
||||
### Check whether VideoFileFormat attribute has been provided
|
||||
elsif ($a[2] eq "VideoFileFormat") {
|
||||
### Check whether VideoFileFormat is defined
|
||||
@@ -907,6 +934,10 @@ sub DoorBird_Set($@)
|
||||
### Call Subroutine and hand back return value
|
||||
return DoorBird_Transmit_Audio($hash, $option)
|
||||
}
|
||||
### TEST
|
||||
elsif ($command eq "Test") {
|
||||
DoorBird_History_List($hash);
|
||||
}
|
||||
### ADD OR CHANGE FAVORITE
|
||||
### DELETE FAVORITE
|
||||
### ADD OR UPDATE SCHEDULE ENTRY
|
||||
@@ -2550,6 +2581,9 @@ sub DoorBird_Image_Request($$) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_Image_Request - write file : Successfully written " . $ImageFileName;
|
||||
|
||||
### Update the history list for images and videos
|
||||
DoorBird_History_List($hash);
|
||||
|
||||
### Close file or write error message in log
|
||||
close $fh or do {
|
||||
### Log Entry
|
||||
@@ -2771,6 +2805,9 @@ sub DoorBird_LastEvent_Image($$$) {
|
||||
|
||||
### Write Last Image into reading
|
||||
readingsSingleUpdate($hash, $ReadingImage, $ImageFileName, 1);
|
||||
|
||||
### Update the history list for images and videos
|
||||
DoorBird_History_List($hash);
|
||||
}
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_LastEvent_Image - ImageData - event : " . length($ImageData);
|
||||
@@ -3519,6 +3556,9 @@ sub DoorBird_History_Request_Parse($) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_Request - write file : Successfully written " . $ImageFileName;
|
||||
|
||||
### Update the history list for images and videos
|
||||
DoorBird_History_List($hash);
|
||||
|
||||
### Close file or write error message in log
|
||||
close $fh or do {
|
||||
### Log Entry
|
||||
@@ -3555,6 +3595,284 @@ sub DoorBird_History_Request_Parse($) {
|
||||
}
|
||||
####END####### Define Subfunction for HISTORY IMAGE REQUEST ####################################################END#####
|
||||
|
||||
###START###### Define Subfunction for history list update as readings #########################################START####
|
||||
sub DoorBird_History_List($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
### Obtain values from hash
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
### If the HistoryFile List shall be created
|
||||
if ($hash->{helper}{HistoryFilePath} == true) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List ___________________________________________________________";
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - The HistoryList has been activated. Processing...";
|
||||
|
||||
### Delete all older reading entries to files
|
||||
#fhem("deleteReading " . $name . " HistoryFilePath.*", 1);
|
||||
|
||||
foreach my $DeleteReading (keys %{$hash->{READINGS}}) {
|
||||
if ($DeleteReading =~ m/HistoryFilePath/ ){
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - Delete Reading : " . $DeleteReading;
|
||||
|
||||
### Delete Reading
|
||||
readingsDelete($hash, $DeleteReading);
|
||||
}
|
||||
}
|
||||
|
||||
### Get current working directory
|
||||
my $cwd = getcwd();
|
||||
|
||||
### If the ImageFileDir has been defined and images are taken
|
||||
if ((defined($hash->{helper}{ImageFileDir})) && (($hash->{helper}{ImageFileDir} =~ m/\/fhem\/www/)) || (($hash->{helper}{ImageFileDir} =~ m/\\fhem\\www/))){
|
||||
my $ImageFileName;
|
||||
my @ImageFileList;
|
||||
|
||||
### If the path is given as UNIX file system format
|
||||
if ($cwd =~ /\//) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - file system format : UNIX";
|
||||
|
||||
### Find out whether it is an absolute path or an relative one (leading "/")
|
||||
if ($hash->{helper}{ImageFileDir} =~ /^\//) {
|
||||
$ImageFileName = $hash->{helper}{ImageFileDir};
|
||||
}
|
||||
else {
|
||||
$ImageFileName = $cwd . "/" . $hash->{helper}{ImageFileDir};
|
||||
}
|
||||
}
|
||||
|
||||
### If the path is given as Windows file system format
|
||||
if ($hash->{helper}{ImageFileDir} =~ /\\/) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - file system format : WINDOWS";
|
||||
|
||||
### Find out whether it is an absolute path or an relative one (containing ":\")
|
||||
if ($hash->{helper}{ImageFileDir} != /^.:\//) {
|
||||
$ImageFileName = $cwd . $hash->{helper}{ImageFileDir};
|
||||
}
|
||||
else {
|
||||
$ImageFileName = $hash->{helper}{ImageFileDir};
|
||||
}
|
||||
}
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ImageFileName : " . $ImageFileName;
|
||||
|
||||
### Get list of directory items
|
||||
if (opendir(FileSearch,$ImageFileName)) {
|
||||
@ImageFileList = readdir(FileSearch);
|
||||
close FileSearch;
|
||||
|
||||
### Define Types to be searched for
|
||||
my @FileTypes = ("motionsensor", "doorbell", "keypad", "snapshot", "manual");
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
foreach my $SearchType (@FileTypes) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - SearchType : " . $SearchType;
|
||||
|
||||
### Extract all Filenames which matches the SearchType
|
||||
my @ImageFileListSearch = grep {/$SearchType/} @ImageFileList;
|
||||
|
||||
### Extract all Filenames which matches the file extension
|
||||
my @ImageFileListExt = grep {/jpg/} @ImageFileListSearch;
|
||||
|
||||
# Sort list
|
||||
@ImageFileListExt=sort(@ImageFileListExt);
|
||||
|
||||
### Get the last n elements (hash->{helper}{MaxHistory})
|
||||
@ImageFileListExt = ($hash->{helper}{MaxHistory} >= @ImageFileListExt) ? @ImageFileListExt : @ImageFileListExt[-$hash->{helper}{MaxHistory}..-1];
|
||||
|
||||
# Sort list
|
||||
@ImageFileListExt=sort({$b cmp $a} @ImageFileListExt);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ImageFileListSearch : \n" . Dumper(@ImageFileListExt);
|
||||
|
||||
### Update Readings
|
||||
my $index = 0;
|
||||
foreach my $FileName (@ImageFileListExt){
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - FileName : " . $FileName;
|
||||
|
||||
### Extract timestamp from Filename
|
||||
my $TimeStamp = substr($FileName,0,4) . "-" . substr($FileName, 4,2) . "-" . substr($FileName, 6,2) . " ";
|
||||
$TimeStamp .= substr($FileName,9,2) . ":" . substr($FileName,11,2) . ":" . substr($FileName,13,2);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - TimeStamp : " . $TimeStamp;
|
||||
|
||||
### Complete relative path from /opt/fhem/www/tablet to $hash->{helper}{ImageFileDir}
|
||||
my $FilePath = abs2rel(rel2abs($ImageFileName), rel2abs("/opt/fhem/www/tablet"));
|
||||
my $ReadingsValue = $FilePath . "/" . $FileName;
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - FilePath : " . $FilePath;
|
||||
|
||||
### Create ReadingsName for Imagepath and write reading
|
||||
my $ReadingsName = "HistoryFilePath_" . $SearchType . "_Image_" . sprintf("%02d", $index);
|
||||
readingsBulkUpdate($hash, $ReadingsName, $ReadingsValue);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsName-Image : " . $ReadingsName;
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsValue-Image : " . $ReadingsValue;
|
||||
|
||||
|
||||
### Create ReadingsName for Timestamp and write reading
|
||||
$ReadingsName = "HistoryFilePath_" . $SearchType . "_Image_" . sprintf("%02d", $index) . "_Timestamp";
|
||||
readingsBulkUpdate($hash, $ReadingsName, $TimeStamp);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsName-Timestamp : " . $ReadingsName;
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsValue-Timestamp : " . $TimeStamp;
|
||||
|
||||
### Increase Index
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
### Log Entry for warning
|
||||
Log3 $name, 2, $name. " : DoorBird_History_List - The Attribute \"ImageFileDir\" leads to an directory which produced an error! - Does it actually exist?";
|
||||
}
|
||||
}
|
||||
else {
|
||||
### Log Entry for warning
|
||||
Log3 $name, 4, $name. " : DoorBird_History_List - The ImageFileDir has not been provided or has not been created below the web-folder e.g. \"/opt/fhem/www/doorbird-images/\"";
|
||||
}
|
||||
### If the VideoFileDir has been defined and Videos are taken
|
||||
if ((defined($hash->{helper}{VideoFileDir})) && (($hash->{helper}{VideoFileDir} =~ m/\/fhem\/www/) || (($hash->{helper}{ImageFileDir} =~ m/\\fhem\\www/)))){
|
||||
my $VideoFileName;
|
||||
my @VideoFileList;
|
||||
|
||||
### If the path is given as UNIX file system format
|
||||
if ($cwd =~ /\//) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - file system format : UNIX";
|
||||
|
||||
### Find out whether it is an absolute path or an relative one (leading "/")
|
||||
if ($hash->{helper}{VideoFileDir} =~ /^\//) {
|
||||
$VideoFileName = $hash->{helper}{VideoFileDir};
|
||||
}
|
||||
else {
|
||||
$VideoFileName = $cwd . "/" . $hash->{helper}{VideoFileDir};
|
||||
}
|
||||
}
|
||||
|
||||
### If the path is given as Windows file system format
|
||||
if ($hash->{helper}{VideoFileDir} =~ /\\/) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - file system format : WINDOWS";
|
||||
|
||||
### Find out whether it is an absolute path or an relative one (containing ":\")
|
||||
if ($hash->{helper}{VideoFileDir} != /^.:\//) {
|
||||
$VideoFileName = $cwd . $hash->{helper}{VideoFileDir};
|
||||
}
|
||||
else {
|
||||
$VideoFileName = $hash->{helper}{VideoFileDir};
|
||||
}
|
||||
}
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - VideoFileName : " . $VideoFileName;
|
||||
|
||||
### Get list of directory items
|
||||
if (opendir(FileSearch,$VideoFileName)) {
|
||||
@VideoFileList = readdir(FileSearch);
|
||||
close FileSearch;
|
||||
|
||||
### Define Types to be searched for
|
||||
my @FileTypes = ("motionsensor", "doorbell", "keypad", "snapshot", "manual");
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
foreach my $SearchType (@FileTypes) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - SearchType : " . $SearchType;
|
||||
|
||||
### Extract all Filenames which matches the SearchType
|
||||
my @VideoFileListSearch = grep {/$SearchType/} @VideoFileList;
|
||||
|
||||
### Extract all Filenames which matches the file extension
|
||||
my @VideoFileListExt = grep {/$hash->{helper}{VideoFileFormat}/} @VideoFileListSearch;
|
||||
|
||||
# Sort list
|
||||
@VideoFileListExt=sort(@VideoFileListExt);
|
||||
|
||||
### Get the last n elements (hash->{helper}{MaxHistory})
|
||||
@VideoFileListExt = ($hash->{helper}{MaxHistory} >= @VideoFileListExt) ? @VideoFileListExt : @VideoFileListExt[-$hash->{helper}{MaxHistory}..-1];
|
||||
|
||||
# Sort list
|
||||
@VideoFileListExt=sort({$b cmp $a} @VideoFileListExt);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - VideoFileListSearch : \n" . Dumper(@VideoFileListExt);
|
||||
|
||||
### Update Readings
|
||||
my $index = 0;
|
||||
foreach my $FileName (@VideoFileListExt){
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - FileName : " . $FileName;
|
||||
|
||||
### Extract timestamp from Filename
|
||||
my $TimeStamp = substr($FileName,0,4) . "-" . substr($FileName, 4,2) . "-" . substr($FileName, 6,2) . " ";
|
||||
$TimeStamp .= substr($FileName,9,2) . ":" . substr($FileName,11,2) . ":" . substr($FileName,13,2);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - TimeStamp : " . $TimeStamp;
|
||||
|
||||
### Complete relative path from /opt/fhem/www/tablet to $hash->{helper}{VideoFileDir}
|
||||
my $FilePath = abs2rel(rel2abs($VideoFileName), rel2abs("/opt/fhem/www/tablet"));
|
||||
my $ReadingsValue = $FilePath . "/" . $FileName;
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - FilePath : " . $FilePath;
|
||||
|
||||
### Create ReadingsName for Videopath and write reading
|
||||
my $ReadingsName = "HistoryFilePath_" . $SearchType . "_Video_" . sprintf("%02d", $index);
|
||||
readingsBulkUpdate($hash, $ReadingsName, $ReadingsValue);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsName-Video : " . $ReadingsName;
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsValue-Video : " . $ReadingsValue;
|
||||
|
||||
|
||||
### Create ReadingsName for Timestamp and write reading
|
||||
$ReadingsName = "HistoryFilePath_" . $SearchType . "_Video_" . sprintf("%02d", $index) . "_Timestamp";
|
||||
readingsBulkUpdate($hash, $ReadingsName, $TimeStamp);
|
||||
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsName-Timestamp : " . $ReadingsName;
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - ReadingsValue-Timestamp : " . $TimeStamp;
|
||||
|
||||
### Increase Index
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
### Log Entry for warning
|
||||
Log3 $name, 2, $name. " : DoorBird_History_List - The Attribute \"VideoFileDir\" leads to an directory which produced an error! - Does it actually exist?";
|
||||
}
|
||||
}
|
||||
else {
|
||||
### Log Entry for warning
|
||||
Log3 $name, 4, $name. " : DoorBird_History_List - The VideoFileDir has not been provided or has not been created below the web-folder e.g. \"/opt/fhem/www/doorbird-videos/\"";
|
||||
}
|
||||
|
||||
### Initiate Readings Update
|
||||
readingsEndUpdate($hash, 1);
|
||||
}
|
||||
else {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 5, $name. " : DoorBird_History_List - The HistoryList has been disabled. Not Links to pictures are provided.";
|
||||
}
|
||||
}
|
||||
####END####### Define Subfunction for history list update as readings ##########################################END#####
|
||||
|
||||
###START###### Define Subfunction for VIDEO REQUEST ###########################################################START####
|
||||
sub DoorBird_Video_Request($$$$) {
|
||||
my ($hash, $duration, $event, $timestamp) = @_;
|
||||
@@ -3709,6 +4027,9 @@ sub DoorBird_Video_Request($$$$) {
|
||||
### Log Entry for debugging purposes
|
||||
Log3 $name, 2, $name. " : DoorBird_Video_Request - Video-Request ha not been implemented for Windows file system. Contact fhem forum and WIKI.";
|
||||
}
|
||||
|
||||
### Update the history list for images and videos after the video has been taken
|
||||
InternalTimer(gettimeofday()+$duration+3,"DoorBird_History_List", $hash, 0);
|
||||
}
|
||||
### If attribute to video directory has NOT been set
|
||||
else {
|
||||
@@ -4163,6 +4484,22 @@ sub DoorBird_BlockGet($$$$) {
|
||||
}
|
||||
####END####### Blocking Get ####################################################################################END#####
|
||||
|
||||
###START###### Calculate relative path ########################################################################START####
|
||||
sub DoorBird_Rel_Path($$) {
|
||||
my ($start,$target) = @_;
|
||||
$start =~ s:/[^/]+:/:; # remove trailing filename
|
||||
my @spath = grep {$_ ne ''} split(/\//,$start);
|
||||
my @tpath = grep {$_ ne ''} split(/\//,$target);
|
||||
|
||||
# strip common start of the path
|
||||
while ( @spath && @tpath && $spath[0] eq $tpath[0]) {
|
||||
shift @spath;
|
||||
shift @tpath;
|
||||
}
|
||||
|
||||
return ("../"x(@spath)).join('/', @tpath);
|
||||
}
|
||||
####END####### Calculate relative path #########################################################################END#####
|
||||
|
||||
###START###### Processing Change Log ##########################################################################START####
|
||||
# Changelog parser for DoorBird changelog as of 2020-02-22 (or earlier) containing multiple product lines.
|
||||
@@ -4437,6 +4774,12 @@ sub DoorBird_findNewestFWVersion($$$)
|
||||
The default value is <code>""</code> = disabled<BR>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>HistoryFilePath</code> : </td><td>Creates relative datapaths to the last pictures, and videos in order to indicate them directly (e.g. fhem ftui widget "image")<BR>
|
||||
The default value is <code>"0"</code> = disabled<BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</ul>
|
||||
</ul>
|
||||
@@ -4615,6 +4958,12 @@ sub DoorBird_findNewestFWVersion($$$)
|
||||
Der Default Wert ist "" = deaktiviert<BR>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>HistoryFilePath</code> : </td><td>Erstellt Dateipfade zu den letzten Bildern und Videos um sie in den User Interfaces direkt anzuzeigen (e.g. fhem ftui Widget "Image")<BR>
|
||||
Der Default Wert ist <code>"0"</code> = disabled<BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user