mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-16 10:46:03 +00:00
98_HTTPMOD: new attr followGet to allow chaining of get commands
git-svn-id: https://svn.fhem.de/fhem/trunk@23641 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
b5e1929d4c
commit
6f5c922f36
@ -21,7 +21,6 @@
|
|||||||
# First version: 25.12.2013
|
# First version: 25.12.2013
|
||||||
#
|
#
|
||||||
# Todo:
|
# Todo:
|
||||||
# Attribute für Regex und LogLevel zum verstecken bestimmter Fehlermedungen von HttpUtils im ReadCallback
|
|
||||||
# setXYHintExpression zum dynamischen Ändern / Erweitern der Hints
|
# setXYHintExpression zum dynamischen Ändern / Erweitern der Hints
|
||||||
# extractAllReadings mit Filter / Prefix
|
# extractAllReadings mit Filter / Prefix
|
||||||
# get after set um readings zu aktualisieren
|
# get after set um readings zu aktualisieren
|
||||||
@ -142,7 +141,7 @@ BEGIN {
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
my $Module_Version = '4.0.17 - 31.12.2020';
|
my $Module_Version = '4.1.01 - 18.1.2021';
|
||||||
|
|
||||||
my $AttrList = join (' ',
|
my $AttrList = join (' ',
|
||||||
'(reading|get|set)[0-9]+(-[0-9]+)?Name',
|
'(reading|get|set)[0-9]+(-[0-9]+)?Name',
|
||||||
@ -212,6 +211,8 @@ my $AttrList = join (' ',
|
|||||||
'[gs]et[0-9]*TextArg:0,1', # just pass on a raw text value without validation / further conversion
|
'[gs]et[0-9]*TextArg:0,1', # just pass on a raw text value without validation / further conversion
|
||||||
'set[0-9]*ParseResponse:0,1', # parse response to set as if it was a get
|
'set[0-9]*ParseResponse:0,1', # parse response to set as if it was a get
|
||||||
'set[0-9]*Method:GET,POST,PUT', # select HTTP method for the set
|
'set[0-9]*Method:GET,POST,PUT', # select HTTP method for the set
|
||||||
|
'[gs]et[0-9]*FollowGet', # do a get after the set/get to update readings / create chains
|
||||||
|
'maxGetChain', # max length of chains
|
||||||
|
|
||||||
'reAuthRegex',
|
'reAuthRegex',
|
||||||
'reAuthAlways:0,1',
|
'reAuthAlways:0,1',
|
||||||
@ -972,11 +973,11 @@ sub DoAuth {
|
|||||||
Log3 $name, 4, "$name: DoAuth called with Steps: " . join (" ", sort keys %steps);
|
Log3 $name, 4, "$name: DoAuth called with Steps: " . join (" ", sort keys %steps);
|
||||||
|
|
||||||
$hash->{sid} = '' if AttrVal($name, "clearSIdBeforeAuth", 0);
|
$hash->{sid} = '' if AttrVal($name, "clearSIdBeforeAuth", 0);
|
||||||
foreach my $step (sort {$b cmp $a} keys %steps) { # reverse sort
|
foreach my $step (sort {$b cmp $a} keys %steps) { # reverse sort because requests are prepended
|
||||||
my $request = PrepareRequest($hash, "sid", $step);
|
my $request = PrepareRequest($hash, "sid", $step);
|
||||||
if ($request->{'url'}) {
|
if ($request->{'url'}) {
|
||||||
$request->{'ignoreRedirects'} = AttrVal($name, "sid${step}IgnoreRedirects", 0);
|
$request->{'ignoreRedirects'} = AttrVal($name, "sid${step}IgnoreRedirects", 0);
|
||||||
$request->{'priority'} = 1;
|
$request->{'priority'} = 1; # prepend at front of queue
|
||||||
AddToSendQueue($hash, $request);
|
AddToSendQueue($hash, $request);
|
||||||
# todo: http method for sid steps?
|
# todo: http method for sid steps?
|
||||||
} else {
|
} else {
|
||||||
@ -1266,6 +1267,7 @@ sub SetFn {
|
|||||||
} else {
|
} else {
|
||||||
readingsSingleUpdate($hash, makeReadingName($setName), $rawVal, 0);
|
readingsSingleUpdate($hash, makeReadingName($setName), $rawVal, 0);
|
||||||
}
|
}
|
||||||
|
ChainGet($hash, 'set', $setNum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,10 +1317,35 @@ sub GetFn {
|
|||||||
} else {
|
} else {
|
||||||
Log3 $name, 3, "$name: no URL for Get $getNum";
|
Log3 $name, 3, "$name: no URL for Get $getNum";
|
||||||
}
|
}
|
||||||
|
ChainGet($hash, 'get', $getNum);
|
||||||
return "$getName requested, watch readings";
|
return "$getName requested, watch readings";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# chain a get after a set or another get
|
||||||
|
# if specified by attr
|
||||||
|
sub ChainGet {
|
||||||
|
my $hash = shift;
|
||||||
|
my $type = shift;
|
||||||
|
my $num = shift;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $get = AttrVal($name, "${type}${num}FollowGet", '');
|
||||||
|
if (!$get) {
|
||||||
|
delete $hash->{GetChainLength};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$hash->{GetChainLength} = ($hash->{GetChainLength} // 0) + 1;
|
||||||
|
if ($hash->{GetChainLength} > AttrVal($name, "maxGetChain", 10)) {
|
||||||
|
Log3 $name, 4, "$name: chaining to get $get due to attr ${type}${num}FollowGet suppressed because chain would get longer than maxGetChain";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log3 $name, 4, "$name: chaining to get $get due to attr ${type}${num}FollowGet, Level $hash->{GetChainLength}";
|
||||||
|
GetFn($hash, $name, $get);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
# request new data from device
|
# request new data from device
|
||||||
# calltype can be update and reread
|
# calltype can be update and reread
|
||||||
@ -1331,10 +1358,9 @@ sub GetUpdate {
|
|||||||
|
|
||||||
Log3 $name, 4, "$name: GetUpdate called ($calltype)";
|
Log3 $name, 4, "$name: GetUpdate called ($calltype)";
|
||||||
|
|
||||||
$hash->{'.LastUpdate'} = $now;
|
$hash->{'.LastUpdate'} = $now; # note the we were called - even when not as 'update' and UpdateTimer is not called afterwards
|
||||||
if ($calltype eq 'update') {
|
UpdateTimer($hash, \&HTTPMOD::GetUpdate, 'next') if ($calltype eq 'update'); # set update timer for next round
|
||||||
UpdateTimer($hash, \&HTTPMOD::GetUpdate, 'next'); # set update timer for next round
|
|
||||||
}
|
|
||||||
if (IsDisabled($name)) {
|
if (IsDisabled($name)) {
|
||||||
Log3 $name, 5, "$name: GetUpdate called but device is disabled";
|
Log3 $name, 5, "$name: GetUpdate called but device is disabled";
|
||||||
return;
|
return;
|
||||||
@ -1454,9 +1480,10 @@ sub FormatReading {
|
|||||||
$expr = GetFAttr($name, $context, $num, "OExpr", $expr); # new syntax
|
$expr = GetFAttr($name, $context, $num, "OExpr", $expr); # new syntax
|
||||||
|
|
||||||
# if no encode is specified and bodyDecode did decode automatically, then encode as utf8 by default
|
# if no encode is specified and bodyDecode did decode automatically, then encode as utf8 by default
|
||||||
my $fDefault = ($featurelevel > 5.9 ? 'auto' : '');
|
#my $fDefault = ($featurelevel > 5.9 ? 'auto' : '');
|
||||||
my $bodyDecode = AttrVal($name, 'bodyDecode', $fDefault);
|
#my $fDefault = 'none';
|
||||||
$encode = 'utf8' if (!$encode && $bodyDecode eq 'auto');
|
#my $bodyDecode = AttrVal($name, 'bodyDecode', $fDefault);
|
||||||
|
#$encode = 'utf8' if (!$encode && $bodyDecode eq 'auto');
|
||||||
|
|
||||||
$val = decode($decode, $val) if ($decode && $decode ne 'none');
|
$val = decode($decode, $val) if ($decode && $decode ne 'none');
|
||||||
$val = encode($encode, $val) if ($encode && $encode ne 'none');
|
$val = encode($encode, $val) if ($encode && $encode ne 'none');
|
||||||
@ -2005,8 +2032,8 @@ sub ExtractSid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
###################################
|
###############################################################
|
||||||
# Check if Auth is necessary
|
# Check if Auth is necessary and queue auth steps if needed
|
||||||
# called from _Read
|
# called from _Read
|
||||||
sub CheckAuth {
|
sub CheckAuth {
|
||||||
my $hash = shift; # hash reference passed to HttpUtils_NonblockingGet (our device)
|
my $hash = shift; # hash reference passed to HttpUtils_NonblockingGet (our device)
|
||||||
@ -2070,11 +2097,11 @@ sub CheckAuth {
|
|||||||
if ($doAuth) {
|
if ($doAuth) {
|
||||||
Log3 $name, 4, "$name: CheckAuth decided new authentication required";
|
Log3 $name, 4, "$name: CheckAuth decided new authentication required";
|
||||||
if ($request->{retryCount} < AttrVal($name, "authRetries", 1)) {
|
if ($request->{retryCount} < AttrVal($name, "authRetries", 1)) {
|
||||||
DoAuth $hash;
|
|
||||||
if (!AttrVal($name, "dontRequeueAfterAuth", 0)) {
|
if (!AttrVal($name, "dontRequeueAfterAuth", 0)) {
|
||||||
AddToSendQueue ($hash, { %{$request}, 'retryCount' => $request->{retryCount}+1, 'value' => $request->{value} } );
|
AddToSendQueue ($hash, { %{$request}, 'priority' => 1, 'retryCount' => $request->{retryCount}+1, 'value' => $request->{value} } );
|
||||||
Log3 $name, 4, "$name: CheckAuth requeued request $request->{type} after auth, retryCount $request->{retryCount} ...";
|
Log3 $name, 4, "$name: CheckAuth prepended request $request->{type} again before auth, retryCount $request->{retryCount} ...";
|
||||||
}
|
}
|
||||||
|
DoAuth $hash;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
Log3 $name, 4, "$name: Authentication still required but no retries left - did last authentication fail?";
|
Log3 $name, 4, "$name: Authentication still required but no retries left - did last authentication fail?";
|
||||||
@ -3366,12 +3393,12 @@ sub AddToSendQueue {
|
|||||||
If your reading values contain Umlauts and they are shown as strange looking icons then you probably need to modidify this attribute.
|
If your reading values contain Umlauts and they are shown as strange looking icons then you probably need to modidify this attribute.
|
||||||
Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.<br>
|
Using this attribute for a set command only makes sense if you want to parse the HTTP response to the HTTP request that the set command sent by defining the attribute setXXParseResponse.<br>
|
||||||
<li><b>bodyDecode</b></li>
|
<li><b>bodyDecode</b></li>
|
||||||
defines an encoding to be used in a call to the perl function decode to convert the raw http response body data string read from the device before further processing / matching<br>
|
defines an encoding to be used in a call to the perl function decode to convert the raw http response body data string
|
||||||
|
read from the device before further processing / matching<br>
|
||||||
If you have trouble matching special characters or if your reading values contain Umlauts
|
If you have trouble matching special characters or if your reading values contain Umlauts
|
||||||
and they are shown as strange looking icons then might need to use this feature.<br>
|
and they are shown as strange looking icons then you might need to use this feature.<br>
|
||||||
This attribute defaults to auto since Fhem featurelevel > 5.9. HTTPMOD automatically looks for a charset header and decodes the body acordingly.
|
If this attribute is set to 'auto' then HTTPMOD automatically looks for a charset header and decodes the body acordingly.
|
||||||
If no charset headr is found, the body will remain undecoded.
|
If no charset header is found, the body will remain undecoded.
|
||||||
So you don't want this behavior, you can disable it by setting this attribute to 'none'.
|
|
||||||
<br>
|
<br>
|
||||||
<li><b>regexDecode</b></li>
|
<li><b>regexDecode</b></li>
|
||||||
defines an encoding to be used in a call to the perl function decode to convert the raw data string from regex attributes before further processing / matching<br>
|
defines an encoding to be used in a call to the perl function decode to convert the raw data string from regex attributes before further processing / matching<br>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user