mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
36_LaCrosseGateway: analog, new timeout
git-svn-id: https://svn.fhem.de/fhem/trunk@12881 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
f222ba0fab
commit
a3e56048f5
@ -36,7 +36,9 @@ sub LaCrosseGateway_Initialize($) {
|
|||||||
." dummy"
|
." dummy"
|
||||||
." initCommands"
|
." initCommands"
|
||||||
." timeout"
|
." timeout"
|
||||||
|
." watchdog"
|
||||||
." disable:0,1"
|
." disable:0,1"
|
||||||
|
." tftFile"
|
||||||
." kvp:dispatch,readings,both"
|
." kvp:dispatch,readings,both"
|
||||||
." ownSensors:dispatch,readings,both"
|
." ownSensors:dispatch,readings,both"
|
||||||
." mode:USB,WiFi,Cable"
|
." mode:USB,WiFi,Cable"
|
||||||
@ -111,7 +113,7 @@ sub LaCrosseGateway_Set($@) {
|
|||||||
my $cmd = shift @a;
|
my $cmd = shift @a;
|
||||||
my $arg = join(" ", @a);
|
my $arg = join(" ", @a);
|
||||||
|
|
||||||
my $list = "raw connect LaCrossePairForSec flash parse reboot";
|
my $list = "raw connect LaCrossePairForSec flash nextionUpload parse reboot";
|
||||||
return $list if( $cmd eq '?' || $cmd eq '');
|
return $list if( $cmd eq '?' || $cmd eq '');
|
||||||
|
|
||||||
if ($cmd eq "raw") {
|
if ($cmd eq "raw") {
|
||||||
@ -164,6 +166,43 @@ sub LaCrosseGateway_Set($@) {
|
|||||||
|
|
||||||
return $log;
|
return $log;
|
||||||
}
|
}
|
||||||
|
elsif ($cmd eq "nextionUpload") {
|
||||||
|
my $log = "";
|
||||||
|
my @deviceName = split('@', $hash->{DeviceName});
|
||||||
|
my $port = $deviceName[0];
|
||||||
|
my $logFile = AttrVal("global", "logdir", "./log") . "/NextionUpload.log";
|
||||||
|
my $tftFile = AttrVal($name, "tftFile", "./FHEM/firmware/nextion.tft");
|
||||||
|
|
||||||
|
return "The file '$tftFile' does not exist" if(!-e $tftFile);
|
||||||
|
|
||||||
|
$log .= "upload Nextion firmware to $name\n";
|
||||||
|
$log .= "tft file: $tftFile\n";
|
||||||
|
|
||||||
|
eval "use LWP::UserAgent";
|
||||||
|
return "\nERROR: Please install LWP::UserAgent" if($@);
|
||||||
|
|
||||||
|
eval "use HTTP::Request::Common";
|
||||||
|
return "\nERROR: Please install HTTP::Request::Common" if($@);
|
||||||
|
|
||||||
|
my @spl = split(':', $hash->{DeviceName});
|
||||||
|
my $targetIP = $spl[0];
|
||||||
|
my $targetURL = "http://" . $targetIP . "/ota/nextion";
|
||||||
|
$log .= "target: $targetURL\n";
|
||||||
|
|
||||||
|
my $request = POST($targetURL, Content_Type => 'multipart/form-data', Content => [ file => [$tftFile, "nextion.tft"] ]);
|
||||||
|
my $userAgent = LWP::UserAgent->new;
|
||||||
|
$userAgent->timeout(300);
|
||||||
|
my $response = $userAgent->request($request);
|
||||||
|
if ($response->is_success) {
|
||||||
|
$log .= "\n\nLGW reports:\n";
|
||||||
|
$log .= $response->decoded_content;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$log .= "\nERROR: " . $response->code . " " . $response->decoded_content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $log;
|
||||||
|
}
|
||||||
elsif ($cmd eq "LaCrossePairForSec") {
|
elsif ($cmd eq "LaCrossePairForSec") {
|
||||||
my @args = split(' ', $arg);
|
my @args = split(' ', $arg);
|
||||||
|
|
||||||
@ -333,16 +372,51 @@ sub LaCrosseGateway_HandleOwnSensors($$) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#=======================================================================================
|
||||||
|
sub LaCrosseGateway_HandleAnalogData($$) {
|
||||||
|
my ($hash, $data) = @_;
|
||||||
|
|
||||||
|
if ($data =~ m/^LGW ANALOG /) {
|
||||||
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
|
my @bytes = split( ' ', substr($data, 10) );
|
||||||
|
return "" if(@bytes < 2);
|
||||||
|
|
||||||
|
my $value = $bytes[0]*256 + $bytes[1];
|
||||||
|
readingsBulkUpdate($hash, "analog", $value);
|
||||||
|
|
||||||
|
readingsEndUpdate($hash, 1);
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
#=======================================================================================
|
#=======================================================================================
|
||||||
sub LaCrosseGateway_Parse($$$$) {
|
sub LaCrosseGateway_Parse($$$$) {
|
||||||
my ($hash, $iohash, $name, $msg) = @_;
|
my ($hash, $iohash, $name, $msg) = @_;
|
||||||
|
|
||||||
next if(!$msg || length($msg) < 1);
|
next if (!$msg || length($msg) < 1);
|
||||||
return if ($msg =~ m/^\*\*\*CLEARLOG/);
|
return if ($msg =~ m/^\*\*\*CLEARLOG/);
|
||||||
|
|
||||||
|
if ($msg =~ m/^LGW/) {
|
||||||
|
if ($msg =~ /ALIVE/) {
|
||||||
|
$hash->{Alive} = TimeNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
LaCrosseGateway_HandleAnalogData($hash, $msg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if($msg =~ m/^\[LaCrosseITPlusReader.Gateway/ ) {
|
if($msg =~ m/^\[LaCrosseITPlusReader.Gateway/ ) {
|
||||||
$hash->{model} = $msg;
|
$hash->{model} = $msg;
|
||||||
|
|
||||||
|
my $attrVal = AttrVal($name, "timeout", undef);
|
||||||
|
if(defined($attrVal)) {
|
||||||
|
my ($timeout, $interval) = split(',', $attrVal);
|
||||||
|
if (!$interval) {
|
||||||
|
$hash->{Alive} = TimeNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ReadingsVal($name, "state", "") eq "opened") {
|
if (ReadingsVal($name, "state", "") eq "opened") {
|
||||||
if (my $initCommandsString = AttrVal($name, "initCommands", undef)) {
|
if (my $initCommandsString = AttrVal($name, "initCommands", undef)) {
|
||||||
my @initCommands = split(' ', $initCommandsString);
|
my @initCommands = split(' ', $initCommandsString);
|
||||||
@ -428,6 +502,22 @@ sub LaCrosseGateway_Connect($;$) {
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#=======================================================================================
|
||||||
|
sub LaCrosseGateway_TriggerWatchdog($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $watchDog = "";
|
||||||
|
|
||||||
|
my $watchDogAttribute = AttrVal($name, "watchdog", undef);
|
||||||
|
if($watchDogAttribute) {
|
||||||
|
$watchDog = "=$watchDogAttribute"
|
||||||
|
}
|
||||||
|
|
||||||
|
my $command = "\"WATCHDOG Ping$watchDog\"";
|
||||||
|
|
||||||
|
LaCrosseGateway_SimpleWrite($hash, $command);
|
||||||
|
}
|
||||||
|
|
||||||
#=======================================================================================
|
#=======================================================================================
|
||||||
sub LaCrosseGateway_OnConnectTimer($) {
|
sub LaCrosseGateway_OnConnectTimer($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -438,19 +528,35 @@ sub LaCrosseGateway_OnConnectTimer($) {
|
|||||||
my $attrVal = AttrVal($name, "timeout", undef);
|
my $attrVal = AttrVal($name, "timeout", undef);
|
||||||
if(defined($attrVal)) {
|
if(defined($attrVal)) {
|
||||||
my ($timeout, $interval) = split(',', $attrVal);
|
my ($timeout, $interval) = split(',', $attrVal);
|
||||||
my $LaCrosseGatewayTime = InternalVal($name, "${name}_TIME", "2000-01-01 00:00:00");
|
my $useOldMethod = $interval;
|
||||||
my ($date, $time, $year, $month, $day, $hour, $min, $sec, $timestamp);
|
$interval = $timeout if !$interval;
|
||||||
($date, $time) = split( ' ', $LaCrosseGatewayTime);
|
|
||||||
($year, $month, $day) = split( '-', $date);
|
|
||||||
($hour, $min, $sec) = split( ':', $time);
|
|
||||||
$month -= 01;
|
|
||||||
$timestamp = timelocal($sec, $min, $hour, $day, $month, $year);
|
|
||||||
|
|
||||||
InternalTimer(gettimeofday() + $interval, "LaCrosseGateway_OnConnectTimer", $hash, 0);
|
InternalTimer(gettimeofday() + $interval, "LaCrosseGateway_OnConnectTimer", $hash, 0);
|
||||||
|
|
||||||
if (gettimeofday() - $timestamp > $timeout) {
|
if(AttrVal($name, "disable", "0") != "1") {
|
||||||
return LaCrosseGateway_Connect($hash, 1);
|
my ($date, $time, $year, $month, $day, $hour, $min, $sec, $timestamp, $alive);
|
||||||
|
if($useOldMethod) {
|
||||||
|
$alive = InternalVal($name, "${name}_TIME", "2000-01-01 00:00:00");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LaCrosseGateway_TriggerWatchdog($hash);
|
||||||
|
$timeout += 5;
|
||||||
|
$alive = $hash->{Alive};
|
||||||
|
$alive = "2000-01-01 00:00:00" if !$alive;
|
||||||
|
}
|
||||||
|
|
||||||
|
($date, $time) = split( ' ', $alive);
|
||||||
|
($year, $month, $day) = split( '-', $date);
|
||||||
|
($hour, $min, $sec) = split( ':', $time);
|
||||||
|
$month -= 01;
|
||||||
|
$timestamp = timelocal($sec, $min, $hour, $day, $month, $year);
|
||||||
|
|
||||||
|
if (gettimeofday() - $timestamp > $timeout) {
|
||||||
|
return LaCrosseGateway_Connect($hash, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,11 +570,14 @@ sub LaCrosseGateway_Attr(@) {
|
|||||||
$hash->{Clients} = $clients if( !$hash->{Clients});
|
$hash->{Clients} = $clients if( !$hash->{Clients});
|
||||||
}
|
}
|
||||||
elsif ($aName eq "timeout") {
|
elsif ($aName eq "timeout") {
|
||||||
return "Usage: attr $name $aName <timeout,checkInterval>" if($aVal && $aVal !~ m/^[0-9]{1,6},[0-9]{1,6}$/);
|
return "Usage: attr $name $aName <checkInterval>" if($aVal && $aVal !~ m/^[0-9]{1,6}(,[0-9]{1,6})*/);
|
||||||
|
|
||||||
RemoveInternalTimer($hash, "LaCrosseGateway_OnConnectTimer");
|
RemoveInternalTimer($hash, "LaCrosseGateway_OnConnectTimer");
|
||||||
if($aVal) {
|
if($aVal) {
|
||||||
|
LaCrosseGateway_TriggerWatchdog($hash);
|
||||||
|
|
||||||
my ($timeout, $interval) = split(',', $aVal);
|
my ($timeout, $interval) = split(',', $aVal);
|
||||||
|
$interval = $timeout if !$interval;
|
||||||
InternalTimer(gettimeofday()+$interval, "LaCrosseGateway_OnConnectTimer", $hash, 0);
|
InternalTimer(gettimeofday()+$interval, "LaCrosseGateway_OnConnectTimer", $hash, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,9 +681,16 @@ sub LaCrosseGateway_Attr(@) {
|
|||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<li>flash<br>
|
<li>flash<br>
|
||||||
The LaCrosseGateway needs the right firmware to be able to receive and deliver the sensor data to fhem.
|
The LaCrosseGateway needs the right firmware to be able to receive and deliver the sensor data to fhem.<br>
|
||||||
This provides a way to flash it directly from FHEM.<br><br>
|
This provides a way to flash it directly from FHEM.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
<li>nextionUpload<br>
|
||||||
|
Requires LaCrosseGateway V1.24 or newer.<br>
|
||||||
|
Sends a Nextion firmware file (.tft) to the LaCrosseGateway. The LaCrosseGateway then distributes it to a connected Nextion display.<br>
|
||||||
|
You can define the .tft file that shall be uploaded in the tftFile attribute. If this attribute does not exists, it will try to use FHEM/firmware/nextion.tft
|
||||||
|
</li><br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<a name="LaCrosseGateway_Get"></a>
|
<a name="LaCrosseGateway_Get"></a>
|
||||||
@ -594,32 +710,45 @@ sub LaCrosseGateway_Attr(@) {
|
|||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<li>MatchList<br>
|
<li>MatchList<br>
|
||||||
Can be set to a perl expression that returns a hash that is used as the MatchList<br>
|
Can be set to a perl expression that returns a hash that is used as the MatchList
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<li>initCommands<br>
|
<li>initCommands<br>
|
||||||
Space separated list of commands to send for device initialization.<br>
|
Space separated list of commands to send for device initialization.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<li>timeout<br>
|
<li>timeout<br>
|
||||||
format: <timeout, checkInterval>
|
format: <timeout><br>
|
||||||
Checks every 'checkInterval' seconds if the last data reception is longer than 'timout' seconds ago.<br>
|
Asks the LaCrosseGateway every timeout seconds if it is still alive. If there is no response it reconnects to the LaCrosseGateway.<br>
|
||||||
|
Can be combined with the watchdog attribute. If the watchdog attribute is set, the LaCrosseGateway also will check if it gets
|
||||||
|
a request within watchdog seconds and if not, it will reboot.
|
||||||
|
watchdog must be longer than timeout and does only work in combination with timeout.<br>
|
||||||
|
Both should not be too short because the LaCrosseGateway needs enough time to boot before the next check.<br>
|
||||||
|
Good values are: timeout 60 and watchdog 300<br>
|
||||||
|
This mode needs LaCrosseGateway V1.24 or newer.
|
||||||
|
<br><br><u>Old version (still working):</u><br>
|
||||||
|
format: <timeout, checkInterval><br>
|
||||||
|
Checks every 'checkInterval' seconds if the last data reception is longer than 'timeout' seconds ago.<br>
|
||||||
If this is the case, a new connect will be tried.
|
If this is the case, a new connect will be tried.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
<li>watchdog<br>
|
||||||
|
see timeout attribute.
|
||||||
|
</li><br>
|
||||||
|
|
||||||
<li>disable<br>
|
<li>disable<br>
|
||||||
if disabled, it does not try to connect and does not dispatch data
|
if disabled, it does not try to connect and does not dispatch data
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<li>kvp<br>
|
<li>kvp<br>
|
||||||
defines how the incoming KVP-data of the LGW is handled<br>
|
defines how the incoming KVP-data of the LaCrosseGateway is handled<br>
|
||||||
dispatch: (default) dispatch it to a KVP device<br>
|
dispatch: (default) dispatch it to a KVP device<br>
|
||||||
readings: create readings (e.g. RSSI, ...) in this device<br>
|
readings: create readings (e.g. RSSI, ...) in this device<br>
|
||||||
both: dispatch and create readings
|
both: dispatch and create readings
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<li>ownSensors<br>
|
<li>ownSensors<br>
|
||||||
defines how the incoming data of the internal LGW sensors is handled<br>
|
defines how the incoming data of the internal LaCrosseGateway sensors is handled<br>
|
||||||
dispatch: (default) dispatch it to a LaCrosse device<br>
|
dispatch: (default) dispatch it to a LaCrosse device<br>
|
||||||
readings: create readings (e.g. temperature, humidity, ...) in this device<br>
|
readings: create readings (e.g. temperature, humidity, ...) in this device<br>
|
||||||
both: dispatch and create readings
|
both: dispatch and create readings
|
||||||
@ -627,7 +756,11 @@ sub LaCrosseGateway_Attr(@) {
|
|||||||
|
|
||||||
<li>mode<br>
|
<li>mode<br>
|
||||||
USB, WiFi or Cable<br>
|
USB, WiFi or Cable<br>
|
||||||
Depending on how the LGW ist connected, it must be handled differently (init, ...)
|
Depending on how the LaCrosseGateway is connected, it must be handled differently (init, ...)
|
||||||
|
</li><br>
|
||||||
|
|
||||||
|
<li>tftFile<br>
|
||||||
|
defines the .tft file that shall be used by the Nextion firmware upload (set nextionUpload)
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user