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($$$$) {
|
-
@@ -4123,15 +4208,11 @@ sub DoorBird_BlockGet($$$$) {
-
-
Set |
The set function is able to change or activate the following features as follows: |
-
-
| : Activates the IR lights of the DoorBird unit. The IR - light deactivates automatically by the default time within the Doorbird unit |
| : Activate/Deactivate the Live Audio Stream of the DoorBird on or off and toggles the direct link in the hidden Reading .AudioURL |
@@ -4140,8 +4221,6 @@ sub DoorBird_BlockGet($$$$) {
| : 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($$$$) {
|
| : Downloads the current Image of the camera of DoorBird unit. |
| : 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($$$$) {
|
-
@@ -4190,21 +4266,18 @@ sub DoorBird_BlockGet($$$$) {
PollingTimeout : | Timeout in seconds before download requests are terminated in cause of no reaction by DoorBird unit. Might be required to be adjusted due to network speed.
The default value is 10s.
-
|
UdpPort : | Port number to be used to receice UDP datagrams. Ports are pre-defined by firmware.
The default value is port 6524
-
|
SessionIdSec : | Time in seconds for how long the session Id shall be valid, which is required for secure Video and Audio transmission. The DoorBird kills the session Id after 10min = 600s automatically. In case of use with CCTV recording units, this function must be disabled by setting to 0.
The default value is 540s = 9min.
-
|
@@ -4265,8 +4338,6 @@ sub DoorBird_BlockGet($$$$) {
=end html
-
-
=begin html_DE
@@ -4292,7 +4363,6 @@ sub DoorBird_BlockGet($$$$) {
-
@@ -4300,7 +4370,6 @@ sub DoorBird_BlockGet($$$$) {
|
-
@@ -4310,7 +4379,6 @@ sub DoorBird_BlockGet($$$$) {
|
-
@@ -4321,14 +4389,11 @@ sub DoorBird_BlockGet($$$$) {
-
-
Set |
Die Set - Funktion ist in der lage auf der DoorBird - Anlage die folgenden Einstellungen vorzunehmen bzw. zu de-/aktivieren:
|
-
| : Schaltet das IR lichht der DoorBird Anlage ein. Das IR Licht schaltet sich automatisch nach der in der DoorBird - Anlage vorgegebenen Default Zeit wieder aus. |
| : Aktiviert/Deaktiviert den Live Audio Stream der DoorBird - Anlage Ein oder Aus und wechselt den direkten link in dem versteckten Reading .AudioURL. |
@@ -4337,8 +4402,6 @@ sub DoorBird_BlockGet($$$$) {
| : Sendet das Kommando zum rebooten der DoorBird - Anlage. |
set Transmit_Audio <Path>
| : Konvertiert die angegebene Audio-Datei und sendet diese zur Ausgabe an die DoorBird - Anlage. Es benötigt einen Dateipfad zu der Audio-Datei zu dem der User "fhem" Schreibrechte braucht (z.B.: /opt/fhem/audio). |
-
-
Get |
Die Get - Funktion ist in der lage von der DoorBird - Anlage die folgenden Informationen und Daten zu laden:
|
@@ -4348,8 +4411,6 @@ sub DoorBird_BlockGet($$$$) {
| : Lädt das gegenwärtige Bild der DoorBird - Kamera herunter. |
| : Lädt das interne Setup (Firmware Version, Relais Konfiguration etc.) herunter. Die übermittelten Relais-Adressen werden als Option für das Kommando Open_Door verwendet. |
-
-
Attributes |
@@ -4358,7 +4419,6 @@ sub DoorBird_BlockGet($$$$) {
|
-
@@ -4454,9 +4514,7 @@ sub DoorBird_BlockGet($$$$) {
=end html_DE
-
=encoding utf8
-
=for :application/json;q=META.json 73_DoorBird.pm
{
"abstract": "Connects fhem to the DoorBird IP door station",
@@ -4487,6 +4545,7 @@ sub DoorBird_BlockGet($$$$) {
"Alien::Sodium": 0,
"Crypt::Argon2": 0,
"Crypt::NaCl::Sodium": 0,
+ "IO::String": 0,
"Cwd": 0,
"Data::Dumper": 0,
"Encode": 0,
@@ -4522,5 +4581,4 @@ sub DoorBird_BlockGet($$$$) {
}
}
=end :application/json;q=META.json
-
=cut
\ No newline at end of file