From ddfc3ccf3e2c867384fa0435fa91bda96c7e6ca7 Mon Sep 17 00:00:00 2001 From: Sailor <> Date: Mon, 24 Feb 2020 13:06:38 +0000 Subject: [PATCH] 73_DoorBird: Improved changelog readout Contribution by: enrikm git-svn-id: https://svn.fhem.de/fhem/trunk@21267 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/73_DoorBird.pm | 138 +++++++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 40 deletions(-) diff --git a/fhem/FHEM/73_DoorBird.pm b/fhem/FHEM/73_DoorBird.pm index bea230013..351cf3709 100644 --- a/fhem/FHEM/73_DoorBird.pm +++ b/fhem/FHEM/73_DoorBird.pm @@ -48,11 +48,13 @@ use utf8; use JSON; use HttpUtils; use Encode; +use FHEM::Meta; use Cwd; use MIME::Base64; use Crypt::NaCl::Sodium qw( :utils ); use Crypt::Argon2 qw/argon2i_raw/; use IO::Socket; +use IO::String; use LWP::UserAgent; use constant false => 0; use constant true => 1; @@ -94,6 +96,7 @@ sub DoorBird_Initialize($) "disable:1,0 " . "loglevel:slider,0,1,5 " . $readingFnAttributes; + return FHEM::Meta::InitMod( __FILE__, $hash ); } ####END####### Initialize module ###############################################################################END##### @@ -1985,7 +1988,6 @@ sub DoorBird_FW_detailFn($$$$) { ' . $ImageHtmlCode . ' - ' . $VideoHtmlCode . '
@@ -2014,7 +2016,6 @@ sub DoorBird_FW_detailFn($$$$) { History of events - Last download: ' . $hash->{helper}{HistoryTime} . ' - Doorbell @@ -2253,16 +2254,15 @@ sub DoorBird_FirmwareStatus($) { ### Log Entry for debugging purposes Log3 $name, 5, $name. " : DoorBird_FirmwareStatus - Checking firmware status on doorbird page"; - my $FirmwareVersionUnit = ReadingsVal($name, "FIRMWARE", 0); + my $FirmwareVersionUnit = ReadingsVal($name, "FIRMWARE" , 0 ); + my $FirmwareDevice = ReadingsVal($name, "DEVICE-TYPE", "unknown"); ### Download website of changelocks my $html = GetFileFromURL("https://www.doorbird.com/changelog"); - ### Get the latest firmware number - my $result; - if ($html =~ /(?<=Firmware version )(.*)(?=\n=====)/) { - $result = $1; - } + ### Get the latest firmware number for this product + my $versions = DoorBird_parseChangelog($hash, $html); + my $result = DoorBird_findNewestFWVersion($hash, $versions, $FirmwareDevice); ### Log Entry for debugging purposes Log3 $name, 5, $name. " : DoorBird_FirmwareStatus - result : " . $result; @@ -4061,6 +4061,95 @@ sub DoorBird_BlockGet($$$$) { return($err, $data); } ####END####### Blocking Get ####################################################################################END##### + + +###START###### Processing Change Log ##########################################################################START#### +# Changelog parser for DoorBird changelog as of 2020-02-22 (or earlier) containing multiple product lines. +# Returns a hash ref containing the newest version number for each product name or prefix found. +# +# Prefixes are denoted by a trailing 'x', as in the original changelog. Note: +# this means that still multiple versions matching a single product could be in the hash, +# e. g. for different prefixes all matching the final product name. + +sub DoorBird_parseChangelog($$) +{ + my ($hash, $data) = @_; + my $name = $hash->{NAME}; + + my $lines = IO::String->new($data); + my $all_versions; + my $version; + + ### For all lines do + while(my $line = <$lines>) { + + ### If the line contains the keywords "Firmware version " followed by a number then obtain it + if ($line =~ /^Firmware version (\d{6})$/) { + $version = $1; + } + + ### If the line contains the keywords "Products affected: " then obtain it + elsif ($line =~ /^Products affected: (.*)$/) { + + ### If version is already obtained from the changelog + if (defined($version)) { + + ### Split the product names into an array + my @products = split(/,\s*/, $1); + + ### For each product name mentioned in the changelog + foreach my $product (@products) { + ### Apparently the line of the "Products affected" in current changelog file is not closed with an \r so we ignore this array - entry + next if $product =~ /Preceding version: /; + + ### If the Product version for the firmware ha snot yet been defined or the already obtaine version number is older than the current value + if (!defined($all_versions->{$product}) or 0 + $all_versions->{$product} < 0 + $version) { + + ### Log Entry for debugging purposes + Log3 $name, 5, $name. " : DoorBird_parseChangelog - found firmware version : " . $version . " for " . $product; + + ### Save latest firmware version + $all_versions->{$product} = $version; + } + } + undef $version; + } + ### If version cannot be found + else + { + ### Log Entry for debugging purposes + Log3 $name, 3, $name. " : DoorBird_parseChangelog - Products without version found in changelog, ignored."; + } + } + } + return $all_versions; +} + +# Find newest firmware version for this device by name or prefix. +# The versions hash ref expected as second argument should match the format returned from DoorBird_parseChangelog(). +sub DoorBird_findNewestFWVersion($$$) +{ + my ($hash, $versions, $product_name) = @_; + my $name = $hash->{NAME}; + my $newest = 0; + + ### For all version entries + foreach my $product (sort keys %$versions) + { + ### Optional prefix matching + my $prefix = $product; + $prefix =~ s/x$//; + + ### If the installed product name is (partial) identical with the product name given in the changelog file entry + if (length($prefix) <= length($product_name) and $prefix eq substr($product_name, 0, length($prefix)) and 0 + $newest < 0 + $versions->{$product}) { + $newest = $versions->{$product}; + } + } + + return $newest; +} +####END####### Processing Change Log ###########################################################################END##### + 1; ###START###### Description for fhem commandref ################################################################START#### @@ -4068,7 +4157,6 @@ sub DoorBird_BlockGet($$$$) { =item device =item summary Connects fhem to the DoorBird IP door station =item summary_DE Verbindet fhem mit der DoorBird IP Türstation - =begin html @@ -4094,7 +4182,6 @@ sub DoorBird_BlockGet($$$$) {
-
@@ -4102,7 +4189,6 @@ sub DoorBird_BlockGet($$$$) {
-
@@ -4112,7 +4198,6 @@ sub DoorBird_BlockGet($$$$) {
- -
-
Set
    The set function is able to change or activate the following features as follows:
- - @@ -4140,8 +4221,6 @@ sub DoorBird_BlockGet($$$$) {
    set Light_On
: Activates the IR lights of the DoorBird unit. The IR - light deactivates automatically by the default time within the Doorbird unit
    set Live_Audio <on:off>
: Activate/Deactivate the Live Audio Stream of the DoorBird on or off and toggles the direct link in the hidden Reading .AudioURL
    set Restart
: Sends the command to restart (reboot) the Doorbird unit
    set Transmit_Audio <Path>
: Converts a given audio file and transmits the stream to the DoorBird speaker. Requires a datapath to audio file to be converted and send. The user "fhem" needs to have write access to this directory.
- -
Get
@@ -4155,8 +4234,6 @@ sub DoorBird_BlockGet($$$$) {
    get Image_Request
: Downloads the current Image of the camera of DoorBird unit.
    get Info_Request
: Downloads the current internal setup such as relay configuration, firmware version etc. of the DoorBird unit. The obtained relay adresses will be used as options for the Open_Door command.
- -
Attributes
@@ -4165,7 +4242,6 @@ sub DoorBird_BlockGet($$$$) {
-