2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00

02_HTTPAPI: mew function readinternal, prototypes removed, code optimizations

git-svn-id: https://svn.fhem.de/fhem/trunk@28909 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klaus.schauer 2024-05-25 17:45:29 +00:00
parent a132bffdb8
commit 8cf8b08b1f

View File

@ -27,7 +27,7 @@ my $linkPattern = "^\/?(([^\/]*(\/[^\/]+)*)\/?)\$";
my $tcpServAdr = 'global'; my $tcpServAdr = 'global';
my $tcpServPort = 8087; my $tcpServPort = 8087;
sub HTTPAPI_Initialize($) { sub HTTPAPI_Initialize {
my ($hash) = @_; my ($hash) = @_;
$hash->{AttrFn} = "HTTPAPI_Attr"; $hash->{AttrFn} = "HTTPAPI_Attr";
$hash->{DefFn} = "HTTPAPI_Define"; $hash->{DefFn} = "HTTPAPI_Define";
@ -38,7 +38,7 @@ sub HTTPAPI_Initialize($) {
return undef; return undef;
} }
sub HTTPAPI_Define($$) { sub HTTPAPI_Define {
my ($hash, $a, $h) = @_; my ($hash, $a, $h) = @_;
my $name = $a->[0]; my $name = $a->[0];
if (defined $a->[2]) { if (defined $a->[2]) {
@ -84,7 +84,7 @@ sub HTTPAPI_Define($$) {
return $ret; return $ret;
} }
sub HTTPAPI_Attr(@) { sub HTTPAPI_Attr {
my ($cmd, $name, $aName, $aVal) = @_; my ($cmd, $name, $aName, $aVal) = @_;
if ($cmd eq "set") { if ($cmd eq "set") {
if ($aName =~ "devicesCtrl") { if ($aName =~ "devicesCtrl") {
@ -98,7 +98,7 @@ sub HTTPAPI_Attr(@) {
return undef; return undef;
} }
sub HTTPAPI_CGI($$$) { sub HTTPAPI_CGI {
# execute request to http://<host>:<port>/$infix?<cmd string> # execute request to http://<host>:<port>/$infix?<cmd string>
my ($hash, $name, $request) = @_; my ($hash, $name, $request) = @_;
my $apiCmd; my $apiCmd;
@ -107,14 +107,14 @@ sub HTTPAPI_CGI($$$) {
my $link; my $link;
return($hash, 503, 'close', "text/plain; charset=utf-8", encode($encoding, "error=503 Service Unavailable")) if(IsDisabled($name)); return($hash, 503, 'close', "text/plain; charset=utf-8", encode($encoding, "error=503 Service Unavailable")) if(IsDisabled($name));
if($request =~ m/^(\/$infix)\/(set|get|read|readtimestamp|write)\?(.*)$/) { if($request =~ m/^(\/$infix)\/(set|get|read|readtimestamp|readinternal|write)\?(.*)$/) {
$link = $1; $link = $1;
$apiCmd = $2; $apiCmd = $2;
$apiCmdString = $3; $apiCmdString = $3;
# url decoding # url decoding
$request =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; $request =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
#readingsSingleUpdate($defs{$name}, 'request', $request, 0); readingsSingleUpdate($defs{$name}, 'request', $request, 0);
if ($apiCmdString =~ /&device(\=[^&]*)?(?=&|$)|^device(\=[^&]*)?(&|$)/) { if ($apiCmdString =~ /&device(\=[^&]*)?(?=&|$)|^device(\=[^&]*)?(&|$)/) {
$fhemDevName = substr(($1 // $2), 1); $fhemDevName = substr(($1 // $2), 1);
@ -148,23 +148,24 @@ sub HTTPAPI_CGI($$$) {
} else { } else {
return($hash, 400, 'close', "text/plain; charset=utf-8", encode($encoding, "error=400 Bad Request, $request > attribute action is missing")) return($hash, 400, 'close', "text/plain; charset=utf-8", encode($encoding, "error=400 Bad Request, $request > attribute action is missing"))
} }
} elsif ($apiCmd =~ /^read|readtimestamp$/) { } elsif ($apiCmd =~ /^read|readtimestamp|readinternal$/) {
my $readingName; my $valName;
if ($apiCmdString =~ /&reading(\=[^&]*)?(?=&|$)|^reading(\=[^&]*)?(&|$)/) { if ($apiCmdString =~ /&reading(\=[^&]*)?(?=&|$)|^reading(\=[^&]*)?(&|$)|&internal(\=[^&]*)?(&|$)/) {
$readingName = substr(($1 // $2), 1); $valName = substr(($1 // $2 // $3 // $4), 1);
# url decoding # url decoding
$readingName =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; $valName =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
my $readingVal = $apiCmd eq 'readtimestamp' ? ReadingsTimestamp($fhemDevName, $readingName, undef) : ReadingsVal($fhemDevName, $readingName, undef); my $val = $apiCmd eq 'readtimestamp' ? ReadingsTimestamp($fhemDevName, $valName, undef) :
#readingsSingleUpdate($defs{$name}, 'reponse', "$readingName=$readingVal", 1); $apiCmd eq 'readinternal' ? InternalVal($fhemDevName, $valName, undef) :
if (defined $readingVal) { ReadingsVal($fhemDevName, $valName, undef);
return($hash, 200, 'close', "text/plain; charset=utf-8", encode($encoding, "$readingName=$readingVal")); #readingsSingleUpdate($defs{$name}, 'reponse', "$valName=$val", 1);
if (defined $val) {
return($hash, 200, 'close', "text/plain; charset=utf-8", encode($encoding, "$valName=$val"));
} else { } else {
return($hash, 400, 'close', "text/plain; charset=utf-8", encode($encoding, "error=400 Bad Request, $request > reading $readingName unknown")) return($hash, 400, 'close', "text/plain; charset=utf-8", encode($encoding, "error=400 Bad Request, $request > reading or internal $valName unknown"))
} }
} else { } else {
return($hash, 400, 'close', "text/plain; charset=utf-8", encode($encoding, "error=400 Bad Request, $request > attribute reading is missing")) return($hash, 400, 'close', "text/plain; charset=utf-8", encode($encoding, "error=400 Bad Request, $request > attribute reading or internal is missing"))
} }
} elsif ($apiCmd eq 'set') { } elsif ($apiCmd eq 'set') {
my $setCmd; my $setCmd;
if ($apiCmdString =~ /&action(\=[^&]*)?(?=&|$)|^action(\=[^&]*)?(&|$)/) { if ($apiCmdString =~ /&action(\=[^&]*)?(?=&|$)|^action(\=[^&]*)?(&|$)/) {
@ -231,7 +232,7 @@ sub HTTPAPI_CGI($$$) {
return; return;
} }
sub HTTPAPI_CommandRef($) { sub HTTPAPI_CommandRef {
my ($hash) = @_; my ($hash) = @_;
my $fileName = $gPath . '/02_HTTPAPI.pm'; my $fileName = $gPath . '/02_HTTPAPI.pm';
my ($err, @contents) = FileRead({FileName => $fileName, ForceType => 'file'}); my ($err, @contents) = FileRead({FileName => $fileName, ForceType => 'file'});
@ -241,7 +242,7 @@ sub HTTPAPI_CommandRef($) {
return ($hash, 200, 'close', "text/html; charset=utf-8", encode($encoding, $1)); return ($hash, 200, 'close', "text/html; charset=utf-8", encode($encoding, $1));
} }
sub HTTPAPI_Read($) { sub HTTPAPI_Read {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -250,10 +251,14 @@ sub HTTPAPI_Read($) {
my $chash = TcpServer_Accept($hash, "HTTPAPI"); my $chash = TcpServer_Accept($hash, "HTTPAPI");
return if (!$chash); return if (!$chash);
$chash->{encoding} = $encoding; $chash->{encoding} = $encoding;
$chash->{cname} = $name;
$chash->{infix} = $hash->{INFIX};
$chash->{CD}->blocking(0); $chash->{CD}->blocking(0);
return; return;
} }
$infix = $hash->{infix};
# read data # read data
my $buf; my $buf;
my $ret = sysread($hash->{CD}, $buf, 2048); my $ret = sysread($hash->{CD}, $buf, 2048);
@ -305,14 +310,14 @@ sub HTTPAPI_Read($) {
delete $hash->{CONTENT_LENGTH}; delete $hash->{CONTENT_LENGTH};
next; next;
} elsif ($url !~ m/\/$infix\//i) { } elsif ($url !~ m/\/$infix\//i) {
$ret = HTTPAPI_TcpServerWrite($hash, 400, 'close', "text/plain; charset=utf-8", "error=400 Bad Request"); $ret = HTTPAPI_TcpServerWrite($hash, 400, 'close', "text/plain; charset=utf-8", "error=400 Bad Request, wrong infix");
delete $hash->{CONTENT_LENGTH}; delete $hash->{CONTENT_LENGTH};
next; next;
} else { } else {
$url =~ m/\/$infix\/(.*)\?(.*)$/i; $url =~ m/\/$infix\/(.*)\?(.*)$/i;
my ($requestCmd, $cmdString) = ($1, $2); my ($requestCmd, $cmdString) = ($1, $2);
# CGI Aufruf # CGI Aufruf
$ret = HTTPAPI_TcpServerWrite(HTTPAPI_CGI($hash, $name, $url)); $ret = HTTPAPI_TcpServerWrite(HTTPAPI_CGI($hash, $hash->{cname}, $url));
delete $hash->{CONTENT_LENGTH}; delete $hash->{CONTENT_LENGTH};
next: next:
} }
@ -323,7 +328,7 @@ sub HTTPAPI_Read($) {
return; return;
} }
sub HTTPAPI_TcpServerWrite($$$$$) { sub HTTPAPI_TcpServerWrite {
my ($hash, $httpState, $connection, $contentType, $content) = @_; my ($hash, $httpState, $connection, $contentType, $content) = @_;
my ($contentLength, $header) = (0, "HTTP/1.1 "); my ($contentLength, $header) = (0, "HTTP/1.1 ");
my %httpState = ( my %httpState = (
@ -344,7 +349,7 @@ sub HTTPAPI_TcpServerWrite($$$$$) {
return TcpServer_WriteBlocking($hash, $header . $content); return TcpServer_WriteBlocking($hash, $header . $content);
} }
sub HTTPAPI_Undef($) { sub HTTPAPI_Undef {
my ($hash) = @_; my ($hash) = @_;
return TcpServer_Close($hash, 1); return TcpServer_Close($hash, 1);
} }
@ -474,6 +479,16 @@ sub HTTPAPI_Undef($) {
<code>&lt;reading name&gt;=|error=&lt;error message&gt;</code><br> <code>&lt;reading name&gt;=|error=&lt;error message&gt;</code><br>
</ul> </ul>
</li> </li>
<li>API command line for querying a internal<br>
Request:
<ul>
<code>http://&lt;ip-addr&gt;:&lt;port&gt;/&lt;apiName&gt;/readinternal?device=&lt;devname&gt;&internal=&lt;name&gt;</code><br>
</ul>
Response:
<ul>
<code>&lt;internal name&gt;=&lt;val&gt;|error=&lt;error message&gt;</code><br>
</ul>
</li>
</ul> </ul>
<br><br> <br><br>