mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-07 23:09:26 +00:00
70_PylonLowVoltage: contrib V0.1.4
git-svn-id: https://svn.fhem.de/fhem/trunk@27897 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
3ece1298d9
commit
39b8dc220c
@ -57,11 +57,15 @@ use IO::Socket::INET;
|
|||||||
use Errno qw(ETIMEDOUT EWOULDBLOCK);
|
use Errno qw(ETIMEDOUT EWOULDBLOCK);
|
||||||
use Scalar::Util qw(looks_like_number);
|
use Scalar::Util qw(looks_like_number);
|
||||||
use Carp qw(croak carp);
|
use Carp qw(croak carp);
|
||||||
|
use Blocking;
|
||||||
|
use MIME::Base64;
|
||||||
|
|
||||||
eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; ## no critic 'eval'
|
eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; ## no critic 'eval'
|
||||||
eval "use IO::Socket::Timeout;1" or my $iostAbsent = 1; ## no critic 'eval'
|
eval "use IO::Socket::Timeout;1" or my $iostAbsent = 'IO::Socket::Timeout'; ## no critic 'eval'
|
||||||
|
eval "use Storable qw(freeze thaw);1;" or my $storabs = 'Storable'; ## no critic 'eval'
|
||||||
|
|
||||||
use FHEM::SynoModules::SMUtils qw(moduleVersion); # Hilfsroutinen Modul
|
use FHEM::SynoModules::SMUtils qw(moduleVersion); # Hilfsroutinen Modul
|
||||||
|
#use Data::Dumper;
|
||||||
|
|
||||||
no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
||||||
|
|
||||||
@ -72,6 +76,8 @@ BEGIN {
|
|||||||
qw(
|
qw(
|
||||||
AttrVal
|
AttrVal
|
||||||
AttrNum
|
AttrNum
|
||||||
|
BlockingCall
|
||||||
|
BlockingKill
|
||||||
data
|
data
|
||||||
defs
|
defs
|
||||||
fhemTimeLocal
|
fhemTimeLocal
|
||||||
@ -116,6 +122,7 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern (Versions history by Heiko Maaz)
|
# Versions History intern (Versions history by Heiko Maaz)
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"0.1.4" => "24.08.2023 Serialize and deserialize data for update entry, usage of BlockingCall in case of long timeout ",
|
||||||
"0.1.3" => "22.08.2023 improve responseCheck and others ",
|
"0.1.3" => "22.08.2023 improve responseCheck and others ",
|
||||||
"0.1.2" => "20.08.2023 commandref revised, analogValue -> use 'user defined items', refactoring according PBP ",
|
"0.1.2" => "20.08.2023 commandref revised, analogValue -> use 'user defined items', refactoring according PBP ",
|
||||||
"0.1.1" => "16.08.2023 integrate US3000C, add print request command in HEX to Logfile, attr timeout ".
|
"0.1.1" => "16.08.2023 integrate US3000C, add print request command in HEX to Logfile, attr timeout ".
|
||||||
@ -313,6 +320,12 @@ sub Define {
|
|||||||
return "Error: $err";
|
return "Error: $err";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($storabs) {
|
||||||
|
my $err = "Perl module >$storabs< is missing. You have to install this perl module.";
|
||||||
|
Log3 ($name, 1, "$name - ERROR - $err");
|
||||||
|
return "Error: $err";
|
||||||
|
}
|
||||||
|
|
||||||
$hash->{HELPER}{MODMETAABSENT} = 1 if($modMetaAbsent); # Modul Meta.pm nicht vorhanden
|
$hash->{HELPER}{MODMETAABSENT} = 1 if($modMetaAbsent); # Modul Meta.pm nicht vorhanden
|
||||||
($hash->{HOST}, $hash->{PORT}) = split ":", $args[2];
|
($hash->{HOST}, $hash->{PORT}) = split ":", $args[2];
|
||||||
$hash->{BATADDRESS} = $args[3] // 1;
|
$hash->{BATADDRESS} = $args[3] // 1;
|
||||||
@ -332,7 +345,7 @@ sub Define {
|
|||||||
use version 0.77; our $VERSION = moduleVersion ($params); # Versionsinformationen setzen
|
use version 0.77; our $VERSION = moduleVersion ($params); # Versionsinformationen setzen
|
||||||
|
|
||||||
_closeSocket ($hash);
|
_closeSocket ($hash);
|
||||||
Update ($hash);
|
manageUpdate ($hash);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -354,7 +367,7 @@ sub Get {
|
|||||||
return if(IsDisabled($name));
|
return if(IsDisabled($name));
|
||||||
|
|
||||||
if ($opt eq 'data') {
|
if ($opt eq 'data') {
|
||||||
Update ($hash);
|
manageUpdate ($hash);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +375,7 @@ return $getlist;
|
|||||||
}
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# PylonLowVoltage Update
|
# PylonLowVoltage Attr
|
||||||
###############################################################
|
###############################################################
|
||||||
sub Attr {
|
sub Attr {
|
||||||
my $cmd = shift;
|
my $cmd = shift;
|
||||||
@ -388,7 +401,7 @@ sub Attr {
|
|||||||
readingsSingleUpdate ($hash, 'state', $val, 1);
|
readingsSingleUpdate ($hash, 'state', $val, 1);
|
||||||
|
|
||||||
if ($do == 0) {
|
if ($do == 0) {
|
||||||
InternalTimer(gettimeofday() + 2.0, "FHEM::PylonLowVoltage::Update", $hash, 0);
|
InternalTimer(gettimeofday() + 2.0, "FHEM::PylonLowVoltage::manageUpdate", $hash, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
deleteReadingspec ($hash);
|
deleteReadingspec ($hash);
|
||||||
@ -402,7 +415,7 @@ sub Attr {
|
|||||||
return qq{The value for $aName is invalid, it must be numeric!};
|
return qq{The value for $aName is invalid, it must be numeric!};
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalTimer(gettimeofday()+1.0, "FHEM::PylonLowVoltage::Update", $hash, 0);
|
InternalTimer(gettimeofday()+1.0, "FHEM::PylonLowVoltage::manageUpdate", $hash, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($aName eq "timeout") {
|
if ($aName eq "timeout") {
|
||||||
@ -415,93 +428,231 @@ return;
|
|||||||
}
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# PylonLowVoltage Update
|
# Eintritt in den Update-Prozess
|
||||||
###############################################################
|
###############################################################
|
||||||
sub Update {
|
sub manageUpdate {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
RemoveInternalTimer ($hash);
|
RemoveInternalTimer ($hash);
|
||||||
|
|
||||||
if(!$init_done) {
|
if(!$init_done) {
|
||||||
InternalTimer(gettimeofday() + 2, "FHEM::PylonLowVoltage::Update", $hash, 0);
|
InternalTimer(gettimeofday() + 2, "FHEM::PylonLowVoltage::manageUpdate", $hash, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return if(IsDisabled ($name));
|
return if(IsDisabled ($name));
|
||||||
|
|
||||||
my $interval = AttrVal ($name, 'interval', $definterval); # 0 -> manuell gesteuert
|
my $interval = AttrVal ($name, 'interval', $definterval); # 0 -> manuell gesteuert
|
||||||
my $timeout = AttrVal ($name, 'timeout', $defto);
|
my $timeout = AttrVal ($name, 'timeout', $defto);
|
||||||
my %readings = ();
|
my $readings;
|
||||||
|
|
||||||
my ($socket, $success);
|
if(!$interval) {
|
||||||
|
$hash->{OPMODE} = 'Manual';
|
||||||
|
$readings->{nextCycletime} = 'Manual';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my $new = gettimeofday() + $interval;
|
||||||
|
InternalTimer ($new, "FHEM::PylonLowVoltage::manageUpdate", $hash, 0); # Wiederholungsintervall
|
||||||
|
|
||||||
if(!$interval) {
|
$hash->{OPMODE} = 'Automatic';
|
||||||
$hash->{OPMODE} = 'Manual';
|
$readings->{nextCycletime} = FmtTime($new);
|
||||||
$readings{nextCycletime} = 'Manual';
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
my $new = gettimeofday() + $interval;
|
|
||||||
InternalTimer ($new, "FHEM::PylonLowVoltage::Update", $hash, 0); # Wiederholungsintervall
|
|
||||||
|
|
||||||
$hash->{OPMODE} = 'Automatic';
|
Log3 ($name, 4, "$name - start request cycle to battery number >$hash->{BATADDRESS}< at host:port $hash->{HOST}:$hash->{PORT}");
|
||||||
$readings{nextCycletime} = FmtTime($new);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log3 ($name, 4, "$name - start request cycle to battery number >$hash->{BATADDRESS}< at host:port $hash->{HOST}:$hash->{PORT}");
|
my $serial = Serialize ({ name => $name, timeout => $timeout, readings => $readings});
|
||||||
|
|
||||||
eval { ## no critic 'eval'
|
if ($timeout < 1.0) {
|
||||||
local $SIG{ALRM} = sub { croak 'gatewaytimeout' };
|
BlockingKill ($hash->{HELPER}{BKRUNNING}) if(defined $hash->{HELPER}{BKRUNNING});
|
||||||
ualarm ($timeout * 1000000); # ualarm in Mikrosekunden
|
startUpdate (Serialize ( { name => $name, timeout => $timeout, readings => $readings} ));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete $hash->{HELPER}{BKRUNNING} if(defined $hash->{HELPER}{BKRUNNING} && $hash->{HELPER}{BKRUNNING}{pid} =~ /DEAD/xs);
|
||||||
|
|
||||||
$socket = _openSocket ($hash, $timeout, \%readings);
|
if (defined $hash->{HELPER}{BKRUNNING}) {
|
||||||
return if(!$socket);
|
Log3 ($name, 3, qq{$name - another BlockingCall PID "$hash->{HELPER}{BKRUNNING}{pid}" is already running ... start Update aborted});
|
||||||
|
|
||||||
if (ReadingsAge ($name, "serialNumber", 601) >= 60) { # relativ statische Werte abrufen
|
return;
|
||||||
return if(_callSerialNumber ($hash, $socket, \%readings)); # Abruf serialNumber
|
}
|
||||||
return if(_callManufacturerInfo ($hash, $socket, \%readings)); # Abruf manufacturerInfo
|
|
||||||
return if(_callProtocolVersion ($hash, $socket, \%readings)); # Abruf protocolVersion
|
|
||||||
return if(_callSoftwareVersion ($hash, $socket, \%readings)); # Abruf softwareVersion
|
|
||||||
return if(_callSystemParameters ($hash, $socket, \%readings)); # Abruf systemParameters
|
|
||||||
}
|
|
||||||
|
|
||||||
return if(_callAlarmInfo ($hash, $socket, \%readings)); # Abruf alarmInfo
|
my $blto = sprintf "%0d", ($timeout + 10);
|
||||||
return if(_callChargeManagmentInfo ($hash, $socket, \%readings)); # Abruf chargeManagmentInfo
|
|
||||||
return if(_callAnalogValue ($hash, $socket, \%readings)); # Abruf analogValue
|
|
||||||
|
|
||||||
$success = 1;
|
$hash->{HELPER}{BKRUNNING} = BlockingCall ( "FHEM::PylonLowVoltage::startUpdate",
|
||||||
}; # eval
|
Serialize ( { block => 1, name => $name, timeout => $timeout, readings => $readings} ),
|
||||||
|
"FHEM::PylonLowVoltage::finishUpdate",
|
||||||
|
$blto, # Blocking Timeout höher als INET-Timeout!
|
||||||
|
"FHEM::PylonLowVoltage::abortUpdate",
|
||||||
|
$hash
|
||||||
|
);
|
||||||
|
|
||||||
if ($@) {
|
|
||||||
my $errtxt;
|
|
||||||
if ($@ =~ /gatewaytimeout/xs) {
|
|
||||||
$errtxt = 'Timeout in communication to RS485 gateway';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$errtxt = $@;
|
|
||||||
}
|
|
||||||
|
|
||||||
doOnError ({ hash => $hash,
|
if (defined $hash->{HELPER}{BKRUNNING}) {
|
||||||
readings => \%readings,
|
$hash->{HELPER}{BKRUNNING}{loglevel} = 3; # Forum https://forum.fhem.de/index.php/topic,77057.msg689918.html#msg689918
|
||||||
sock => $socket,
|
|
||||||
state => $errtxt,
|
|
||||||
verbose => 3
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ualarm(0);
|
Log3 ($name, 4, qq{$name - BlockingCall PID "$hash->{HELPER}{BKRUNNING}{pid}" with Blocking Timeout "$blto" started});
|
||||||
_closeSocket ($hash);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($success) {
|
return;
|
||||||
Log3 ($name, 4, "$name - got data from battery number >$hash->{BATADDRESS}< successfully");
|
}
|
||||||
|
|
||||||
additionalReadings (\%readings); # zusätzliche eigene Readings erstellen
|
###############################################################
|
||||||
$readings{state} = 'connected';
|
# PylonLowVoltage startUpdate
|
||||||
}
|
###############################################################
|
||||||
|
sub startUpdate {
|
||||||
|
my $serial = shift;
|
||||||
|
|
||||||
createReadings ($hash, \%readings); # Readings erstellen
|
my $paref = eval { thaw ($serial) }; # Deserialisierung
|
||||||
|
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $timeout = $paref->{timeout};
|
||||||
|
my $readings = $paref->{readings};
|
||||||
|
my $block = $paref->{block} // 0;
|
||||||
|
|
||||||
|
my $hash = $defs{$name};
|
||||||
|
my $success = 0;
|
||||||
|
|
||||||
|
my ($socket);
|
||||||
|
|
||||||
|
eval { ## no critic 'eval'
|
||||||
|
local $SIG{ALRM} = sub { croak 'gatewaytimeout' };
|
||||||
|
ualarm ($timeout * 1000000); # ualarm in Mikrosekunden
|
||||||
|
|
||||||
|
$socket = _openSocket ($hash, $timeout, $readings);
|
||||||
|
if (!$socket) { $block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadingsAge ($name, "serialNumber", 601) >= 60) { # statische Werte abrufen
|
||||||
|
if (_callSerialNumber ($hash, $socket, $readings)) { # Abruf serialNumber
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callManufacturerInfo ($hash, $socket, $readings)) { # Abruf manufacturerInfo
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callProtocolVersion ($hash, $socket, $readings)) { # Abruf protocolVersion
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callSoftwareVersion ($hash, $socket, $readings)) { # Abruf softwareVersion
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callSystemParameters ($hash, $socket, $readings)) { # Abruf systemParameters
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callAlarmInfo ($hash, $socket, $readings)) { # Abruf alarmInfo
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callChargeManagmentInfo ($hash, $socket, $readings)) { # Abruf chargeManagmentInfo
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_callAnalogValue ($hash, $socket, $readings)) { # Abruf analogValue
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
$success = 1;
|
||||||
|
}; # eval
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
my $errtxt;
|
||||||
|
if ($@ =~ /gatewaytimeout/xs) {
|
||||||
|
$errtxt = 'Timeout in communication to RS485 gateway';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$errtxt = $@;
|
||||||
|
}
|
||||||
|
|
||||||
|
doOnError ({ hash => $hash,
|
||||||
|
readings => $readings,
|
||||||
|
sock => $socket,
|
||||||
|
state => $errtxt,
|
||||||
|
verbose => 3
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$block ?
|
||||||
|
return ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), "")) :
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ( {name => $name, readings => $readings} ), ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
ualarm(0);
|
||||||
|
_closeSocket ($hash);
|
||||||
|
|
||||||
|
if ($block) {
|
||||||
|
return ( encode_base64 (Serialize ({name => $name, success => $success, readings => $readings}), "") );
|
||||||
|
}
|
||||||
|
|
||||||
|
return \&finishUpdate ( encode_base64 (Serialize ({name => $name, success => $success, readings => $readings}), "") );
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
# Restaufgaben nach Update
|
||||||
|
###############################################################
|
||||||
|
sub finishUpdate {
|
||||||
|
my $serial = decode_base64 (shift);
|
||||||
|
|
||||||
|
my $paref = eval { thaw ($serial) }; # Deserialisierung
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $success = $paref->{success} // 0;
|
||||||
|
my $readings = $paref->{readings};
|
||||||
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
|
delete($hash->{HELPER}{BKRUNNING}) if(defined $hash->{HELPER}{BKRUNNING});
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
Log3 ($name, 4, "$name - got data from battery number >$hash->{BATADDRESS}< successfully");
|
||||||
|
|
||||||
|
additionalReadings ($readings); # zusätzliche eigene Readings erstellen
|
||||||
|
$readings->{state} = 'connected';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deleteReadingspec ($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
createReadings ($hash, $readings); # Readings erstellen
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Abbruchroutine BlockingCall Timeout
|
||||||
|
####################################################################################################
|
||||||
|
sub abortUpdate {
|
||||||
|
my $hash = shift;
|
||||||
|
my $cause = shift // "Timeout: process terminated";
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
delete($hash->{HELPER}{BKRUNNING});
|
||||||
|
|
||||||
|
Log3 ($name, 1, "$name -> BlockingCall $hash->{HELPER}{BKRUNNING}{fn} pid:$hash->{HELPER}{BKRUNNING}{pid} aborted: $cause");
|
||||||
|
|
||||||
|
deleteReadingspec ($hash);
|
||||||
|
readingsSingleUpdate ($hash, 'state', 'Update (Child) process timed out', 1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -536,17 +687,17 @@ sub _openSocket {
|
|||||||
)
|
)
|
||||||
or do { doOnError ({ hash => $hash,
|
or do { doOnError ({ hash => $hash,
|
||||||
readings => $readings,
|
readings => $readings,
|
||||||
state => 'no connection is established to RS485 gateway',
|
state => 'no connection to RS485 gateway established',
|
||||||
verbose => 3
|
verbose => 3
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
IO::Socket::Timeout->enable_timeouts_on ($socket); # nur notwendig für read or write timeout
|
IO::Socket::Timeout->enable_timeouts_on ($socket); # nur notwendig für read or write timeout
|
||||||
my $rwto = $timeout - 0.05;
|
my $rwto = $timeout - 0.1;
|
||||||
$rwto = $rwto <= 0 ? 0.005 : $rwto;
|
$rwto = $rwto <= 0 ? 0.05 : $rwto;
|
||||||
|
|
||||||
$socket->read_timeout ($rwto); # Read/Writetimeout immer kleiner als Sockettimeout
|
$socket->read_timeout ($rwto); # Read/Writetimeout immer kleiner als Sockettimeout
|
||||||
$socket->write_timeout ($rwto);
|
$socket->write_timeout ($rwto);
|
||||||
@ -570,7 +721,7 @@ sub _closeSocket {
|
|||||||
close ($socket);
|
close ($socket);
|
||||||
delete $hash->{SOCKET};
|
delete $hash->{SOCKET};
|
||||||
|
|
||||||
Log3 ($name, 4, "$name - Socket/Connection to the RS485 gateway was closed as scheduled");
|
Log3 ($name, 4, "$name - Socket/Connection to the RS485 gateway was closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -953,6 +1104,23 @@ sub __resultLog {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
# Daten Serialisieren
|
||||||
|
###############################################################
|
||||||
|
sub Serialize {
|
||||||
|
my $data = shift;
|
||||||
|
my $name = $data->{name};
|
||||||
|
|
||||||
|
my $serial = eval { freeze ($data)
|
||||||
|
}
|
||||||
|
or do { my $err = $@;
|
||||||
|
Log3 ($name, 2, "$name - Serialization ERROR: $err");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
return $serial;
|
||||||
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# PylonLowVoltage Request
|
# PylonLowVoltage Request
|
||||||
###############################################################
|
###############################################################
|
||||||
@ -1007,6 +1175,7 @@ sub Shutdown {
|
|||||||
|
|
||||||
RemoveInternalTimer ($hash);
|
RemoveInternalTimer ($hash);
|
||||||
_closeSocket ($hash);
|
_closeSocket ($hash);
|
||||||
|
BlockingKill ($hash->{HELPER}{BKRUNNING}) if(defined $hash->{HELPER}{BKRUNNING});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1085,9 +1254,7 @@ sub doOnError {
|
|||||||
|
|
||||||
Log3 ($name, $verbose, "$name - ".$readings->{state});
|
Log3 ($name, $verbose, "$name - ".$readings->{state});
|
||||||
|
|
||||||
_closeSocket ($hash);
|
_closeSocket ($hash);
|
||||||
deleteReadingspec ($hash);
|
|
||||||
createReadings ($hash, $readings);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1133,7 +1300,7 @@ sub createReadings {
|
|||||||
|
|
||||||
for my $spec (keys %{$readings}) {
|
for my $spec (keys %{$readings}) {
|
||||||
next if(!defined $readings->{$spec});
|
next if(!defined $readings->{$spec});
|
||||||
readingsBulkUpdate ($hash, $spec, $readings->{$spec});
|
readingsBulkUpdate ($hash, $spec, $readings->{$spec}) if(defined $readings->{$spec});
|
||||||
}
|
}
|
||||||
|
|
||||||
readingsEndUpdate ($hash, 1);
|
readingsEndUpdate ($hash, 1);
|
||||||
@ -1264,6 +1431,10 @@ management system via the RS485 interface.
|
|||||||
<li><b>timeout <seconds></b><br>
|
<li><b>timeout <seconds></b><br>
|
||||||
Timeout for establishing the connection to the RS485 gateway. <br>
|
Timeout for establishing the connection to the RS485 gateway. <br>
|
||||||
(default: 0.5)
|
(default: 0.5)
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Note</b>: If a timeout >= 1 second is set, the module switches internally to the use of a parallel process
|
||||||
|
(BlockingCall) so that write or read delays on the RS485 interface do not lead to blocking states in FHEM.
|
||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1425,6 +1596,11 @@ Batteriemanagementsystem über die RS485-Schnittstelle zur Verfügung stellt.
|
|||||||
<li><b>timeout <Sekunden></b><br>
|
<li><b>timeout <Sekunden></b><br>
|
||||||
Timeout für den Verbindungsaufbau zum RS485 Gateway. <br>
|
Timeout für den Verbindungsaufbau zum RS485 Gateway. <br>
|
||||||
(default: 0.5)
|
(default: 0.5)
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Hinweis</b>: Wird ein Timeout >= 1 Sekunde eingestellt, schaltet das Modul intern auf die Verwendung eines
|
||||||
|
Parallelprozesses (BlockingCall) um damit Schreib- bzw. Leseverzögerungen auf dem RS485 Interface nicht zu
|
||||||
|
blockierenden Zuständen in FHEM führen.
|
||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1531,6 +1707,10 @@ Batteriemanagementsystem über die RS485-Schnittstelle zur Verfügung stellt.
|
|||||||
"Errno": 0,
|
"Errno": 0,
|
||||||
"FHEM::SynoModules::SMUtils": 1.0220,
|
"FHEM::SynoModules::SMUtils": 1.0220,
|
||||||
"Time::HiRes": 0,
|
"Time::HiRes": 0,
|
||||||
|
"Carp": 0,
|
||||||
|
"Blocking": 0,
|
||||||
|
"Storable": 0,
|
||||||
|
"MIME::Base64": 0,
|
||||||
"Scalar::Util": 0
|
"Scalar::Util": 0
|
||||||
},
|
},
|
||||||
"recommends": {
|
"recommends": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user