mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
98_Arducounter.pm: Bugfixes
git-svn-id: https://svn.fhem.de/fhem/trunk@13487 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
76f874b3d2
commit
2f90ffa189
@ -41,8 +41,11 @@
|
||||
# 2017-01-02 modification for sketch 1.7, monitor clock drift difference between ardino and Fhem
|
||||
# 2017-01-04 some more beatification in logging
|
||||
# 2017-01-06 avoid reopening when disable=0 is set during startup
|
||||
# 2017-02-06 Doku korrigiert
|
||||
# 2017-02-18 fixed a bug that caused a missing open when the device is defined while fhem is already initialized
|
||||
|
||||
# ideas / todo:
|
||||
#
|
||||
|
||||
|
||||
|
||||
@ -62,7 +65,7 @@ my %ArduCounter_gets = (
|
||||
"info" => ""
|
||||
);
|
||||
|
||||
my $ArduCounter_Version = '4.5 - 6.1.2017';
|
||||
my $ArduCounter_Version = '4.7 - 18.2.2017';
|
||||
|
||||
#
|
||||
# FHEM module intitialisation
|
||||
@ -114,7 +117,12 @@ sub ArduCounter_Define($$)
|
||||
my $name = $a[0];
|
||||
my $dev = $a[2];
|
||||
|
||||
$dev .= '@38400' if ($dev !~ /.+@[0-9]+/);
|
||||
if ($dev !~ /.+@([0-9]+)/) {
|
||||
$dev .= '@38400';
|
||||
} else {
|
||||
Log3 $name, 3, "$name: Warning: connection speed $1 is not the default for the ArduCounter firmware"
|
||||
if ($1 != 38400);
|
||||
}
|
||||
$hash->{buffer} = "";
|
||||
$hash->{DeviceName} = $dev;
|
||||
$hash->{VersionModule} = $ArduCounter_Version;
|
||||
@ -127,6 +135,10 @@ sub ArduCounter_Define($$)
|
||||
#$attr{$name}{'flashCommand'} = 'avrdude -p atmega328P -b 57600 -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]';
|
||||
$attr{$name}{'flashCommand'} = 'avrdude -p atmega328P -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]';
|
||||
}
|
||||
|
||||
if ($init_done) {
|
||||
ArduCounter_Open($hash);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -161,7 +173,26 @@ sub ArduCounter_Undef($$)
|
||||
|
||||
|
||||
########################################################
|
||||
# Notify for INITIALIZED
|
||||
# Open Device
|
||||
sub ArduCounter_Open($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
DevIo_OpenDev($hash, 0, 0);
|
||||
if ($hash->{FD}) {
|
||||
my $now = gettimeofday();
|
||||
my $hdl = AttrVal($name, "helloSendDelay", 3);
|
||||
# send hello if device doesn't say "Started" withing $hdl seconds
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
InternalTimer($now+$hdl, "ArduCounter_SendHello", "sendHello:$name", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
########################################################
|
||||
# Notify for INITIALIZED or Modified
|
||||
# -> Open connection to device
|
||||
sub ArduCounter_Notify($$)
|
||||
{
|
||||
my ($hash, $source) = @_;
|
||||
@ -181,12 +212,7 @@ sub ArduCounter_Notify($$)
|
||||
}
|
||||
|
||||
Log3 $name, 5, "$name: Notify called with events: @{$events}, open device and set timer to send hello to device";
|
||||
DevIo_OpenDev( $hash, 0, 0);
|
||||
|
||||
my $now = gettimeofday();
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
my $helloDelay = AttrVal($name, "helloSendDelay", 3);
|
||||
InternalTimer($now+$helloDelay, "ArduCounter_SendHello", "sendHello:$name", 0);
|
||||
ArduCounter_Open($hash);
|
||||
}
|
||||
|
||||
|
||||
@ -211,20 +237,21 @@ sub ArduCounter_Write ($$)
|
||||
|
||||
#######################################
|
||||
# Aufruf aus InternalTimer
|
||||
# send "h" to ask for "Hello" since device didn't say "Started" so fae - maybe it's still counting ...
|
||||
sub ArduCounter_SendHello($)
|
||||
{
|
||||
my $param = shift;
|
||||
my (undef,$name) = split(':',$param);
|
||||
my $hash = $defs{$name};
|
||||
my $now = gettimeofday();
|
||||
|
||||
Log3 $name, 3, "$name: sending h(ello) to device to ask for version";
|
||||
return if (!ArduCounter_Write( $hash, "h"));
|
||||
|
||||
$hash->{WaitForHello} = 1;
|
||||
my $now = gettimeofday();
|
||||
my $hwt = AttrVal($name, "helloWaitTime ", 3);
|
||||
RemoveInternalTimer ("hwait:$name");
|
||||
my $helloWait= AttrVal($name, "helloWaitTime ", 3);
|
||||
InternalTimer($now+$helloWait, "ArduCounter_HelloTimeout", "hwait:$name", 0);
|
||||
InternalTimer($now+$hwt, "ArduCounter_HelloTimeout", "hwait:$name", 0);
|
||||
$hash->{WaitForHello} = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -235,7 +262,7 @@ sub ArduCounter_HelloTimeout($)
|
||||
my $param = shift;
|
||||
my (undef,$name) = split(':',$param);
|
||||
my $hash = $defs{$name};
|
||||
Log3 $name, 3, "$name: device didn't reply to h(ello). Is the right sketch flashed?";
|
||||
Log3 $name, 3, "$name: device didn't reply to h(ello). Is the right sketch flashed? Is speed set to 38400?";
|
||||
delete $hash->{WaitForHello};
|
||||
}
|
||||
|
||||
@ -313,11 +340,7 @@ sub ArduCounter_Attr(@)
|
||||
return;
|
||||
} else {
|
||||
Log3 $name, 3, "$name: disable attribute cleared";
|
||||
DevIo_OpenDev( $hash, 0, 0) if ($hash->{Initialized});
|
||||
my $now = gettimeofday();
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
my $helloDelay = AttrVal($name, "helloSendDelay", 1);
|
||||
InternalTimer($now+$helloDelay, "ArduCounter_SendHello", "sendHello:$name", 0);
|
||||
ArduCounter_Open($hash) if ($init_done); # only if fhem is initialized
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,16 +386,17 @@ sub ArduCounter_Attr(@)
|
||||
return "Invalid pin name $aName";
|
||||
}
|
||||
my $pin = $1;
|
||||
# this cannot come from fhem.cfg and waiting for initialized doesnt help so send it
|
||||
|
||||
if ($hash->{Initialized}) { # did device already report its version?
|
||||
ArduCounter_Write( $hash, "${pin}d");
|
||||
} else {
|
||||
Log3 $name, 5, "$name: pin config can not be deleted since device is not initialized yet";
|
||||
return "device is not initialized yet";
|
||||
}
|
||||
|
||||
} elsif ($aName eq 'disable') {
|
||||
Log3 $name, 3, "$name: disable attribute removed";
|
||||
DevIo_OpenDev( $hash, 0, 0) if ($hash->{Initialized});
|
||||
my $now = gettimeofday();
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
my $helloDelay = AttrVal($name, "helloSendDelay", 1);
|
||||
InternalTimer($now+$helloDelay, "ArduCounter_SendHello", "sendHello:$name", 0);
|
||||
ArduCounter_Open($hash) if ($hash->{$init_done}); # if fhem is initialized
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
@ -471,6 +495,7 @@ sub ArduCounter_Set($@)
|
||||
}
|
||||
DevIo_OpenDev($hash, 0, 0);
|
||||
$log .= "$name opened\n";
|
||||
delete $hash->{Initialized};
|
||||
}
|
||||
return $log;
|
||||
}
|
||||
@ -525,6 +550,9 @@ sub ArduCounter_HandleVersion($$)
|
||||
if ($version < "1.7") {
|
||||
$version .= " - not compatible with this Module version - please flash new sketch";
|
||||
Log3 $name, 3, "$name: device reported outdated Arducounter Firmware - please update!";
|
||||
delete $hash->{Initialized};
|
||||
} else {
|
||||
$hash->{Initialized} = 1; # now device is initialized
|
||||
}
|
||||
$hash->{VersionFirmware} = $version;
|
||||
Log3 $name, 4, "$name: device reported firmware $version";
|
||||
@ -647,21 +675,20 @@ sub ArduCounter_Parse($)
|
||||
"s in " . sprintf("%.3f", $drTime) . "s" .
|
||||
($drTime > 0 ? ", " . sprintf("%.2f", $hash->{'.Drift2'} / $drTime * 100) . "%" : "");
|
||||
|
||||
if (!$hash->{Initialized}) {
|
||||
Log3 $name, 3, "$name: device reported count";
|
||||
if (!$hash->{WaitForHello}) {
|
||||
if (!$hash->{Initialized}) { # device has not sent Started / hello yet
|
||||
Log3 $name, 3, "$name: device is still counting";
|
||||
if (!$hash->{WaitForHello}) { # if hello has not already been sent, send it now
|
||||
ArduCounter_SendHello("direct:$name");
|
||||
}
|
||||
$hash->{Initialized} = 1;
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
RemoveInternalTimer ("sendHello:$name"); # don't send hello again
|
||||
}
|
||||
|
||||
} elsif ($line =~ /ArduCounter V([\d\.]+).?Hello/) { # response to h(ello)
|
||||
Log3 $name, 3, "$name: device replied to hello, V$1";
|
||||
ArduCounter_HandleVersion($hash, $line);
|
||||
$hash->{Initialized} = 1;
|
||||
ArduCounter_ConfigureDevice($hash) if ($hash->{WaitForHello});
|
||||
|
||||
if ($hash->{Initialized}) {
|
||||
ArduCounter_ConfigureDevice($hash) # send pin configuration
|
||||
}
|
||||
delete $hash->{WaitForHello};
|
||||
RemoveInternalTimer ("hwait:$name");
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
@ -671,7 +698,6 @@ sub ArduCounter_Parse($)
|
||||
$retStr .= $line;
|
||||
ArduCounter_HandleVersion($hash, $line);
|
||||
|
||||
#todo: remove here?
|
||||
delete $hash->{WaitForHello};
|
||||
RemoveInternalTimer ("hwait:$name"); # dont wait for hello reply if already sent
|
||||
RemoveInternalTimer ("sendHello:$name"); # Hello not needed anymore if not sent yet
|
||||
@ -680,8 +706,9 @@ sub ArduCounter_Parse($)
|
||||
} elsif ($line =~ /ArduCounter V([\d\.]+).?Started/) { # setup message
|
||||
Log3 $name, 3, "$name: device sent setup message, V$1";
|
||||
ArduCounter_HandleVersion($hash, $line);
|
||||
$hash->{Initialized} = 1;
|
||||
ArduCounter_ConfigureDevice($hash);
|
||||
if ($hash->{Initialized}) {
|
||||
ArduCounter_ConfigureDevice($hash) # send pin configuration
|
||||
}
|
||||
|
||||
delete $hash->{WaitForHello};
|
||||
RemoveInternalTimer ("hwait:$name"); # dont wait for hello reply if already sent
|
||||
@ -821,13 +848,14 @@ sub ArduCounter_Ready($)
|
||||
# try to reopen if state is disconnected
|
||||
if ( $hash->{STATE} eq "disconnected" ) {
|
||||
#Log3 $name, 3, "$name: ReadyFN tries to open"; # debug
|
||||
delete $hash->{Initialized};
|
||||
DevIo_OpenDev( $hash, 1, undef );
|
||||
if ($hash->{FD} && !$hash->{Initialized}) {
|
||||
Log3 $name, 3, "$name: device not initialized yet, set timer to send h(ello";
|
||||
if ($hash->{FD}) {
|
||||
Log3 $name, 3, "$name: device maybe not initialized yet, set timer to send h(ello";
|
||||
my $now = gettimeofday();
|
||||
my $hdl = AttrVal($name, "helloSendDelay", 3);
|
||||
RemoveInternalTimer ("sendHello:$name");
|
||||
my $helloDelay = AttrVal($name, "helloSendDelay", 3);
|
||||
InternalTimer($now+$helloDelay, "ArduCounter_SendHello", "sendHello:$name", 0);
|
||||
InternalTimer($now+$hdl, "ArduCounter_SendHello", "sendHello:$name", 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -862,7 +890,8 @@ sub ArduCounter_Ready($)
|
||||
<ul>
|
||||
<br>
|
||||
<li>
|
||||
This module requires an Arduino uno, nano, Jeenode or similar device running the ArduCounter sketch provided with this module
|
||||
This module requires an Arduino uno, nano, Jeenode or similar device running the ArduCounter sketch provided with this module<br>
|
||||
In order to flash an arduino board with the corresponding ArduCounter firmware, avrdude needs to be installed.
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
Loading…
x
Reference in New Issue
Block a user