mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 11:16:36 +00:00
Bugfixing und Weiterentwicklung, deutsche Doku
git-svn-id: https://svn.fhem.de/fhem/trunk@3847 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
da3d7fcfa0
commit
91a7813008
@ -21,7 +21,7 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
###############################################
|
||||
################################################################
|
||||
package main;
|
||||
###########################
|
||||
# 70_WS3600.pm
|
||||
@ -31,119 +31,139 @@ package main;
|
||||
# Based in part on work for FHEM by other authors ...
|
||||
# $Id$
|
||||
###########################
|
||||
|
||||
# 15.06.2013 Josch (Josch at abwesend dot de) some debugging
|
||||
# 25.06.2013 Josch combined Date/Time-Records supported
|
||||
# 12.07.2013 Josch documentation reworked
|
||||
# 15.07.2013 Josch state handling improved (shows conn problems)
|
||||
# 16.08.2013 Josch Logging improved: Level relative to verbosity level
|
||||
# 27.08.2013 Josch Change to Log3, loglevel removed
|
||||
use strict;
|
||||
use warnings;
|
||||
#use Device::SerialPort;
|
||||
|
||||
my %sets = (
|
||||
"cmd" => "",
|
||||
"freq" => "",
|
||||
);
|
||||
|
||||
# all records except Time- and Date/Time-Records
|
||||
my %TranslatedCodes = (
|
||||
"Date" => "Date",
|
||||
"Time" => "Time",
|
||||
"Ti" => "Temp-inside",
|
||||
"Timin" => "Temp-inside-min",
|
||||
"Timax" => "Temp-inside-max",
|
||||
"TTimin" => "Temp-inside-min-Time",
|
||||
"DTimin" => "Temp-inside-min-Date",
|
||||
"TTimax" => "Temp-inside-max-Time",
|
||||
"DTimax" => "Temp-inside-max-Date",
|
||||
"To" => "Temp-outside",
|
||||
"Tomin" => "Temp-outside-min",
|
||||
"Tomax" => "Temp-outside-max",
|
||||
"TTomin" => "Temp-outside-min-Time",
|
||||
"DTomin" => "Temp-outside-min-Date",
|
||||
"TTomax" => "Temp-outside-max-Time",
|
||||
"DTomax" => "Temp-outside-max-Date",
|
||||
"DP" => "Dew-Point",
|
||||
"DPmin" => "Dew-Point-min",
|
||||
"DPmax" => "Dew-Point-max",
|
||||
"TDPmin" => "Dew-Point-min-Time",
|
||||
"DDPmin" => "Dew-Point-min-Date",
|
||||
"TDPmax" => "Dew-Point-min-Time",
|
||||
"DDPmax" => "Dew-Point-min-Date",
|
||||
"RHi" => "rel-Humidity-inside",
|
||||
"RHimin" => "rel-Humidity-inside-min",
|
||||
"RHimax" => "rel-Humidity-inside-max",
|
||||
"TRHimin" => "rel-Humidity-inside-min-Time",
|
||||
"DRHimin" => "rel-Humidity-inside-min-Date",
|
||||
"TRHimax" => "rel-Humidity-inside-max-Time",
|
||||
"DRHimax" => "rel-Humidity-inside-max-Date",
|
||||
"RHo" => "rel-Humidity-outside",
|
||||
"RHomin" => "rel-Humidity-outside-min",
|
||||
"RHomax" => "rel-Humidity-outside-max",
|
||||
"TRHomin" => "rel-Humidity-outside-min-Time",
|
||||
"DRHomin" => "rel-Humidity-outside-min-Date",
|
||||
"TRHomax" => "rel-Humidity-outside-max-Time",
|
||||
"DRHomax" => "rel-Humidity-outside-max-Date",
|
||||
"WS" => "Wind-Speed",
|
||||
"Date" => "DTime",
|
||||
"Ti" => "Temp-inside",
|
||||
"Timin" => "Temp-inside-min",
|
||||
"Timax" => "Temp-inside-max",
|
||||
"DTimin" => "Temp-inside-min-DTime",
|
||||
"DTimax" => "Temp-inside-max-DTime",
|
||||
"To" => "Temp-outside",
|
||||
"Tomin" => "Temp-outside-min",
|
||||
"Tomax" => "Temp-outside-max",
|
||||
"DTomin" => "Temp-outside-min-DTime",
|
||||
"DTomax" => "Temp-outside-max-DTime",
|
||||
"DP" => "Dew-Point",
|
||||
"DPmin" => "Dew-Point-min",
|
||||
"DPmax" => "Dew-Point-max",
|
||||
"DDPmin" => "Dew-Point-min-DTime",
|
||||
"DDPmax" => "Dew-Point-min-DTime",
|
||||
"RHi" => "rel-Humidity-inside",
|
||||
"RHimin" => "rel-Humidity-inside-min",
|
||||
"RHimax" => "rel-Humidity-inside-max",
|
||||
"DRHimin" => "rel-Humidity-inside-min-DTime",
|
||||
"DRHimax" => "rel-Humidity-inside-max-DTime",
|
||||
"RHo" => "rel-Humidity-outside",
|
||||
"RHomin" => "rel-Humidity-outside-min",
|
||||
"RHomax" => "rel-Humidity-outside-max",
|
||||
"DRHomin" => "rel-Humidity-outside-min-DTime",
|
||||
"DRHomax" => "rel-Humidity-outside-max-DTime",
|
||||
"WS" => "Wind-Speed",
|
||||
"DIRtext" => "Wind-Direction-Text",
|
||||
"DIR0" => "Wind-DIR0",
|
||||
"DIR1" => "Wind-DIR1",
|
||||
"DIR2" => "Wind-DIR2",
|
||||
"DIR3" => "Wind-DIR3",
|
||||
"DIR4" => "Wind-DIR4",
|
||||
"DIR5" => "Wind-DIR5",
|
||||
"WC" => "Wind-Chill",
|
||||
"WCmin" => "Wind-Chill-min",
|
||||
"WCmax" => "Wind-Chill-max",
|
||||
"TWCmin" => "Wind-Chill-min-Time",
|
||||
"DWCmin" => "Wind-Chill-min-Date",
|
||||
"TWCmax" => "Wind-Chill-max-Time",
|
||||
"DWCmax" => "Wind-Chill-max-Date",
|
||||
"WSmin" => "Wind-Speed-min",
|
||||
"WSmax" => "Wind-Speed-max",
|
||||
"TWSmin" => "Wind-Speed-min-Time",
|
||||
"DWSmin" => "Wind-Speed-min-Date",
|
||||
"TWSmax" => "Wind-Speed-max-Time",
|
||||
"DWSmax" => "Wind-Speed-max-Date",
|
||||
"R1h" => "Rain-1h",
|
||||
"R1hmax" => "Rain-1h-hmax",
|
||||
"TR1hmax" => "Rain-1h-hmax-Time",
|
||||
"DR1hmax" => "Rain-1h-hmax-Date",
|
||||
"R24h" => "Rain-24h",
|
||||
"DIR0" => "Wind-DIR0",
|
||||
"DIR1" => "Wind-DIR1",
|
||||
"DIR2" => "Wind-DIR2",
|
||||
"DIR3" => "Wind-DIR3",
|
||||
"DIR4" => "Wind-DIR4",
|
||||
"DIR5" => "Wind-DIR5",
|
||||
"WC" => "Wind-Chill",
|
||||
"WCmin" => "Wind-Chill-min",
|
||||
"WCmax" => "Wind-Chill-max",
|
||||
"DWCmin" => "Wind-Chill-min-DTime",
|
||||
"DWCmax" => "Wind-Chill-max-DTime",
|
||||
"WSmin" => "Wind-Speed-min",
|
||||
"WSmax" => "Wind-Speed-max",
|
||||
"DWSmin" => "Wind-Speed-min-DTime",
|
||||
"DWSmax" => "Wind-Speed-max-DTime",
|
||||
"R1h" => "Rain-1h",
|
||||
"R1hmax" => "Rain-1h-hmax",
|
||||
"DR1hmax" => "Rain-1h-hmax-DTime",
|
||||
"R24h" => "Rain-24h",
|
||||
"R24hmax" => "Rain-24-hmax",
|
||||
"TR24hmax" => "Rain-24h-max-Time",
|
||||
"DR24hmax" => "Rain-24h-max-Date",
|
||||
"R1w" => "Rain-1w",
|
||||
"R1wmax" => "Rain-1w-max",
|
||||
"TR1wmax" => "Rain-1w-max-Time",
|
||||
"DR1wmax" => "Rain-1w-max-Date",
|
||||
"R1m" => "Rain-1M",
|
||||
"R1mmax" => "Rain-1M-max",
|
||||
"TR1mmax" => "Rain-1M-max-Time",
|
||||
"DR1mmax" => "Rain-1M-max-Date",
|
||||
"Rtot" => "Rain-total",
|
||||
"TRtot" => "Rain-total-Time",
|
||||
"DRtot" => "Rain-total-Date",
|
||||
"RP" => "rel-Pressure",
|
||||
"AP" => "abs-Pressure",
|
||||
"RPmin" => "rel-Pressure-min",
|
||||
"RPmax" => "rel-Pressure-max",
|
||||
"TRPmin" => "rel-Pressure-min-Time",
|
||||
"DRPmin" => "rel-Pressure-min-Date",
|
||||
"TRPmax" => "rel-Pressure-max-Time",
|
||||
"DRPmax" => "rel-Pressure-max-Date",
|
||||
"Tendency" => "Tendency",
|
||||
"Forecast" => "Forecast",
|
||||
"DR24hmax"=> "Rain-24h-max-DTime",
|
||||
"R1w" => "Rain-1w",
|
||||
"R1wmax" => "Rain-1w-max",
|
||||
"DR1wmax" => "Rain-1w-max-DTime",
|
||||
"R1m" => "Rain-1M",
|
||||
"R1mmax" => "Rain-1M-max",
|
||||
"DR1mmax" => "Rain-1M-max-DTime",
|
||||
"Rtot" => "Rain-total",
|
||||
"DRtot" => "Rain-total-DTime",
|
||||
"RP" => "rel-Pressure",
|
||||
"AP" => "abs-Pressure",
|
||||
"RPmin" => "rel-Pressure-min",
|
||||
"RPmax" => "rel-Pressure-max",
|
||||
"DRPmin" => "rel-Pressure-min-DTime",
|
||||
"DRPmax" => "rel-Pressure-max-DTime",
|
||||
"Tendency"=> "Tendency",
|
||||
"Forecast"=> "Forecast",
|
||||
#added for WS-0101 / WS-1080
|
||||
"WG" => "Wind-Gust",
|
||||
"DIR" => "Wind-Dir",
|
||||
"state" => "State",
|
||||
);
|
||||
|
||||
my %WantedCodesForStatus = (
|
||||
"Ti" => "Ti:",
|
||||
"To" => "T:",
|
||||
"DP" => "DP:",
|
||||
"RHi" => "Hi:",
|
||||
"RHo" => "H:",
|
||||
"WS" => "W:",
|
||||
"DIRtext" => "Dir:",
|
||||
"WC" => "WC:",
|
||||
"R1h" => "R:",
|
||||
"RP" => "P:",
|
||||
"Tendency" => "Tendency:",
|
||||
"Forecast" => "Forecast:",
|
||||
# Date/Time-Records
|
||||
my %TranslatedDateTimeCodes = (
|
||||
"DTime" => "DTime",
|
||||
"DTTimin" => "Temp-inside-min-DTime",
|
||||
"DTTimax" => "Temp-inside-max-DTime",
|
||||
"DTTomin" => "Temp-outside-min-DTime",
|
||||
"DTTomax" => "Temp-outside-max-DTime",
|
||||
"DTDPmin" => "Dew-Point-min-DTime",
|
||||
"DTDPmax" => "Dew-Point-min-DTime",
|
||||
"DTRHimin" => "rel-Humidity-inside-min-DTime",
|
||||
"DTRHimax" => "rel-Humidity-inside-max-DTime",
|
||||
"DTRHomin" => "rel-Humidity-outside-min-DTime",
|
||||
"DTRHomax" => "rel-Humidity-outside-max-DTime",
|
||||
"DTWCmin" => "Wind-Chill-min-DTime",
|
||||
"DTWCmax" => "Wind-Chill-max-DTime",
|
||||
"DTWSmin" => "Wind-Speed-min-DTime",
|
||||
"DTWSmax" => "Wind-Speed-max-DTime",
|
||||
"DTR1hmax" => "Rain-1h-hmax-DTime",
|
||||
"DTR24hmax"=> "Rain-24h-max-DTime",
|
||||
"DTR1wmax" => "Rain-1w-max-DTime",
|
||||
"DTR1mmax" => "Rain-1M-max-DTime",
|
||||
"DTRtot" => "Rain-total-DTime",
|
||||
"DTRPmin" => "rel-Pressure-min-DTime",
|
||||
"DTRPmax" => "rel-Pressure-max-DTime",
|
||||
);
|
||||
|
||||
# Time-Records (will be appended to Date-Record)
|
||||
my %TranslatedTimeCodes = (
|
||||
"Time" => "DTime",
|
||||
"TTimin" => "Temp-inside-min-DTime",
|
||||
"TTimax" => "Temp-inside-max-DTime",
|
||||
"TTomin" => "Temp-outside-min-DTime",
|
||||
"TTomax" => "Temp-outside-max-DTime",
|
||||
"TDPmin" => "Dew-Point-min-DTime",
|
||||
"TDPmax" => "Dew-Point-min-DTime",
|
||||
"TRHimin" => "rel-Humidity-inside-min-DTime",
|
||||
"TRHimax" => "rel-Humidity-inside-max-DTime",
|
||||
"TRHomin" => "rel-Humidity-outside-min-DTime",
|
||||
"TRHomax" => "rel-Humidity-outside-max-DTime",
|
||||
"TWCmin" => "Wind-Chill-min-DTime",
|
||||
"TWCmax" => "Wind-Chill-max-DTime",
|
||||
"TWSmin" => "Wind-Speed-min-DTime",
|
||||
"TWSmax" => "Wind-Speed-max-DTime",
|
||||
"TR1hmax" => "Rain-1h-hmax-DTime",
|
||||
"TR24hmax"=> "Rain-24h-max-DTime",
|
||||
"TR1wmax" => "Rain-1w-max-DTime",
|
||||
"TR1mmax" => "Rain-1M-max-DTime",
|
||||
"TRtot" => "Rain-total-DTime",
|
||||
"TRPmin" => "rel-Pressure-min-DTime",
|
||||
"TRPmax" => "rel-Pressure-max-DTime",
|
||||
);
|
||||
|
||||
#####################################
|
||||
@ -154,8 +174,8 @@ WS3600_Initialize($)
|
||||
|
||||
# Consumer
|
||||
$hash->{DefFn} = "WS3600_Define";
|
||||
$hash->{AttrList}= "model:WS3600,WS2300 loglevel:0,1,2,3,4,5,6";
|
||||
$hash->{ReadFn} = "WS3600_Read";
|
||||
$hash->{AttrList}= "model:WS3600,WS2300,WS1080";
|
||||
# $hash->{ReadFn} = "WS3600_Read";
|
||||
$hash->{UndefFn} = "WS3600_Undef";
|
||||
}
|
||||
|
||||
@ -164,55 +184,42 @@ sub
|
||||
WS3600_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my @a = split("\"", $def);
|
||||
my $dev;
|
||||
my $Timer = 60; # call every 64 seconds; normal wireless update interval
|
||||
# is 128 sec, on wind >10 m/s 32 sec. 64 sec should ensure
|
||||
# quite current data.
|
||||
|
||||
return "Define the /path/to/fetch3600 as a parameter" if(@a != 3);
|
||||
if(@a==1) {
|
||||
@a = split("[ \t][ \t]*", $def); #compatibility for old syntax
|
||||
return "wrong syntax: define <name> WS3600 \"</path/to/extprog [<options>]>\" [<readinterval in s>]" if(@a!=3);
|
||||
$dev = $a[2];
|
||||
}
|
||||
else {
|
||||
return "wrong syntax: define <name> WS3600 \"</path/to/extprog [<options>]>\" [<readinterval in s>]" if(@a < 2 || @a > 3);
|
||||
$dev = $a[1];
|
||||
$Timer = $a[2] if((@a==3)&&($a[2]>=10));
|
||||
}
|
||||
|
||||
my $FH;
|
||||
my $dev = sprintf("%s |", $a[2]);
|
||||
Log 3, "WS3600 using \"$dev\" as parameter to open(); trying ...";
|
||||
open($FH, $dev);
|
||||
if(!$FH) {
|
||||
return "WS3600 Can't start $dev: $!";
|
||||
}
|
||||
local $_;
|
||||
while (<$FH>) {
|
||||
# my ($reading, $val)=split(/ /, $_);
|
||||
|
||||
if(/^(Date) (.*)/ || /^(Time) (.*)/ || /^(Ti) (.*)/ || /^(To) (.*)/) {
|
||||
Log 3, "WS3600 initial read: $1 $2";
|
||||
}
|
||||
}
|
||||
close($FH);
|
||||
Log 3, "WS3600 initial read done";
|
||||
my $name = $hash->{NAME};
|
||||
my $ret = `$dev`; #call external program
|
||||
Log3 $name, 4, "WS3600(Dbg): $name ret=$ret";
|
||||
|
||||
return "WS3600(Err): Can't start $dev: $!" if(!defined($ret));
|
||||
|
||||
# Log3 $name, 3, "WS3600 $dev started";
|
||||
|
||||
$hash->{DeviceName} = $dev;
|
||||
$hash->{Timer} = 64; # call every 64 seconds; normal wireless update interval
|
||||
# is 128 sec, on wind >10 km/h 32 sec. 64 sec should ensure
|
||||
# quite current data.
|
||||
$hash->{Timer} = $Timer;
|
||||
|
||||
# my $tn = TimeNow();
|
||||
# $hash->{READINGS}{"freq"}{TIME} = $tn;
|
||||
# $hash->{READINGS}{"freq"}{VAL} = $hash->{Timer};
|
||||
# $hash->{CHANGED}[0] = "freq: $hash->{Timer}";
|
||||
my $nt = gettimeofday() + $hash->{Timer};
|
||||
$nt -= $nt % $hash->{Timer}; # round
|
||||
Log3 $name, 3, "WS3600(Msg): $name initialized, setting callback timer to " . FmtTime($nt) . "(+ $Timer s)";
|
||||
|
||||
# InternalTimer blocks if init_done is not true
|
||||
# my $oid = $init_done;
|
||||
# $init_done = 1;
|
||||
# WS3600_GetStatus($hash);
|
||||
# $init_done = $oid;
|
||||
|
||||
Log 3, "WS3600 setting callback timer";
|
||||
|
||||
my $oid = $init_done;
|
||||
$init_done = 1;
|
||||
InternalTimer(gettimeofday()+ $hash->{Timer}, "WS3600_GetStatus", $hash, 1);
|
||||
$init_done = $oid;
|
||||
|
||||
Log 3, "WS3600 initialized";
|
||||
RemoveInternalTimer($hash);
|
||||
InternalTimer($nt, "WS3600_Read", $hash, 0);
|
||||
|
||||
$hash->{STATE} = "initialized";
|
||||
$hash->{TMPSTATE} = "";
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -221,225 +228,87 @@ sub
|
||||
WS3600_Undef($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if(defined($hash->{FD})) {
|
||||
close($hash->{FD});
|
||||
delete $hash->{FD};
|
||||
}
|
||||
delete $selectlist{"$name.pipe"};
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
$hash->{STATE}='undefined';
|
||||
Log GetLogLevel($name,3), "$name shutdown complete";
|
||||
Log3 $name, 3, "WS3600(Msg): $name shutdown complete";
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
WS3600_GetStatus($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $dnr = $hash->{DEVNR};
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $FH;
|
||||
|
||||
# Call us in n seconds again.
|
||||
# InternalTimer(gettimeofday()+ $hash->{Timer}, "WS3600_GetStatus", $hash, 1);
|
||||
|
||||
Log GetLogLevel($name,4), "WS3600 contacting station";
|
||||
|
||||
open($FH, $dev);
|
||||
if(!$FH) {
|
||||
return "WS3600 Can't start $dev: $!";
|
||||
}
|
||||
|
||||
$hash->{FD}=$FH;
|
||||
$selectlist{"$name.pipe"} = $hash;
|
||||
Log GetLogLevel($name,4), "WS3600 pipe opened";
|
||||
# $hash->{STATE} = "running";
|
||||
$hash->{pipeopentime} = time();
|
||||
# InternalTimer(gettimeofday() + 6, "WS3600_Read", $hash, 1);
|
||||
return $hash->{STATE};
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
WS3600_Read($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $dnr = $hash->{DEVNR};
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my $FH;
|
||||
my $inputline;
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $dev = $hash->{DeviceName};
|
||||
my @lines;
|
||||
my $tn = TimeNow();
|
||||
my $reading;
|
||||
my $AnythingRead = 0;
|
||||
|
||||
Log GetLogLevel($name,4), "WS3600 Read entered";
|
||||
$hash->{LastRead} = $tn;
|
||||
if(defined($defs{$name}{READINGS}{"State"})) {
|
||||
$defs{$name}{READINGS}{"State"}{VAL} = 0xFF;
|
||||
$defs{$name}{READINGS}{"State"}{TIME} = $tn;
|
||||
}
|
||||
|
||||
if(!defined($hash->{FD})) {
|
||||
Log GetLogLevel($name,3), "Oops, WS3600 FD undef'd";
|
||||
return undef;
|
||||
# Log 4-GetLogLevel($name,0), "WS3600(Dbg): (4) Info";
|
||||
# Log 3-GetLogLevel($name,0), "WS3600(Msg): (3) Msg";
|
||||
# Log 2-GetLogLevel($name,0), "WS3600(Wng): (2) Warning";
|
||||
# Log 1-GetLogLevel($name,0), "WS3600(Err): (1) Error";
|
||||
|
||||
# Log3 $name, 4, "WS3600(Dbg): $name Read started using \"$dev\"";
|
||||
Log3 $name, 3, "WS3600(Msg): $name Read started";
|
||||
@lines = `$dev`; # call external program
|
||||
|
||||
foreach my $inputline ( @lines ) {
|
||||
$inputline =~ s/\s+$//;
|
||||
my ($rawreading, $val, $val2) = split(/ /, $inputline);
|
||||
Log3 $name, 4, "WS3600(Dbg): $name read $inputline|$rawreading|$val|$val2";
|
||||
if(defined($TranslatedCodes{$rawreading})) {
|
||||
$reading = $TranslatedCodes{$rawreading};
|
||||
$defs{$name}{READINGS}{$reading}{VAL} = $val;
|
||||
$defs{$name}{READINGS}{$reading}{TIME} = $tn;
|
||||
$AnythingRead = 1;
|
||||
}
|
||||
if(!$hash->{FD}) {
|
||||
Log GetLogLevel($name,3), "Oops, WS3600 FD empty";
|
||||
return undef;
|
||||
# write Date/Time-Records
|
||||
elsif(defined($TranslatedDateTimeCodes{$rawreading})) {
|
||||
$reading = $TranslatedDateTimeCodes{$rawreading};
|
||||
$defs{$name}{READINGS}{$reading}{VAL} = $val . " " . $val2;
|
||||
$defs{$name}{READINGS}{$reading}{TIME} = $tn;
|
||||
$AnythingRead = 1;
|
||||
}
|
||||
$FH = $hash->{FD};
|
||||
|
||||
Log GetLogLevel($name,4), "WS3600 reading started";
|
||||
|
||||
my @lines;
|
||||
my $eof;
|
||||
my $i=0;
|
||||
my $tn = TimeNow();
|
||||
my $StateString=$hash->{TMPSTATE};
|
||||
my $HumidString="";
|
||||
my $TempsString="";
|
||||
my $OtherString="";
|
||||
my $reading;
|
||||
my $readingforstatus;
|
||||
|
||||
($eof, @lines) = nonblockGetLines($FH);
|
||||
|
||||
if(!defined($eof)) {
|
||||
Log GetLogLevel($name,4), "WS3600 FIXME: eof undefined?!";
|
||||
$eof=0;
|
||||
# append Time-Record to Date-Record (managed by same Name)
|
||||
elsif(defined($TranslatedTimeCodes{$rawreading})) {
|
||||
$reading = $TranslatedTimeCodes{$rawreading};
|
||||
$defs{$name}{READINGS}{$reading}{VAL} .= " " . $val;
|
||||
$defs{$name}{READINGS}{$reading}{TIME} = $tn;
|
||||
$AnythingRead = 1;
|
||||
}
|
||||
Log GetLogLevel($name,4), "WS3600 reading ended with eof==$eof";
|
||||
}
|
||||
if($AnythingRead) {
|
||||
$hash->{STATE} = "T: " . $defs{$name}{READINGS}{"Temp-outside"}{VAL}
|
||||
. " H: " . $defs{$name}{READINGS}{"rel-Humidity-outside"}{VAL}
|
||||
. " W: " . $defs{$name}{READINGS}{"Wind-Speed"}{VAL}
|
||||
. " R: " . $defs{$name}{READINGS}{"Rain-total"}{VAL}
|
||||
. " Ti: " . $defs{$name}{READINGS}{"Temp-inside"}{VAL}
|
||||
. " Hi: " . $defs{$name}{READINGS}{"rel-Humidity-inside"}{VAL};
|
||||
|
||||
# FIXME! Current observed behaviour is "would block", then read of only EOF.
|
||||
# Not sure if it's always that way; more correct would be checking
|
||||
# for empty $inputline or undef'd $rawreading,$val. -wusel, 2010-01-04
|
||||
if($eof != 1) {
|
||||
foreach my $inputline ( @lines ) {
|
||||
$inputline =~ s/\s+$//;
|
||||
my ($rawreading, $val)=split(/ /, $inputline);
|
||||
Log GetLogLevel($name,5), "WS3600 read $inputline:$rawreading:$val";
|
||||
if(defined($TranslatedCodes{$rawreading})) {
|
||||
|
||||
# delete $defs{$name}{READINGS}{" $rawreading"};
|
||||
|
||||
$reading=$TranslatedCodes{$rawreading};
|
||||
|
||||
$defs{$name}{READINGS}{$reading}{VAL} = $val;
|
||||
$defs{$name}{READINGS}{$reading}{TIME} = $tn;
|
||||
#
|
||||
# -wusel, 2010-01-30: BIG CHANGE: only put into CHANGED[] what will be in
|
||||
# STATE as well; this is done to reduce the burden on
|
||||
# the notification framework (each one currently leads
|
||||
# to a separate notify which will in turn lead a call
|
||||
# of EVERY NotifyFn()) and to improve FHEMs overall
|
||||
# performance.
|
||||
# Every value is still be stored in READINGS though.
|
||||
#
|
||||
# $hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
|
||||
if(defined($WantedCodesForStatus{$rawreading})) {
|
||||
$readingforstatus=$WantedCodesForStatus{$rawreading};
|
||||
$StateString=sprintf("%s %s %s", $StateString, $readingforstatus, $val);
|
||||
$hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
}
|
||||
# if($rawreading =~ m/^(Tendency|Forecast)/) {
|
||||
# $hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
# $StateString=sprintf("%s %s: %s", $StateString, $reading, $val);
|
||||
# }
|
||||
# if($rawreading =~ m/^(Ti$|To$|WC$)/) {
|
||||
# $hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
# $TempsString=sprintf("%s %s: %s °C", $TempsString, $reading, $val);
|
||||
# }
|
||||
# if($rawreading =~ m/^(RHi$|RHo$)/) {
|
||||
# $hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
# $HumidString=sprintf("%s %s: %s %%", $HumidString, $reading, $val);
|
||||
# }
|
||||
# if($rawreading =~ m/^(R1h$|R24h$)/) {
|
||||
# $hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
# $OtherString=sprintf("%s %s: %s mm", $OtherString, $reading, $val);
|
||||
# }
|
||||
# if($rawreading =~ m/^(RP$|AP$)/) {
|
||||
# $hash->{CHANGED}[$i++] = "$reading: $val";
|
||||
# $OtherString=sprintf("%s %s: %s hPa", $OtherString, $reading, $val);
|
||||
# }
|
||||
}
|
||||
}
|
||||
$hash->{TMPSTATE} = $StateString;
|
||||
}
|
||||
|
||||
if($eof) {
|
||||
close($FH);
|
||||
delete $hash->{FD};
|
||||
delete $selectlist{"$name.pipe"};
|
||||
InternalTimer(gettimeofday()+ $hash->{Timer}, "WS3600_GetStatus", $hash, 1);
|
||||
Log GetLogLevel($name,4), "WS3600 done reading pipe";
|
||||
} else {
|
||||
Log GetLogLevel($name,4), "WS3600 (further) reading would block";
|
||||
}
|
||||
|
||||
# $OtherString =~ s/^\s+//;
|
||||
# $HumidString =~ s/^\s+//;
|
||||
# $TempsString =~ s/^\s+//;
|
||||
# $StateString =~ s/^\s+//;
|
||||
#
|
||||
# $defs{$name}{READINGS}{"Humidity"}{VAL} = $HumidString;
|
||||
# $defs{$name}{READINGS}{"Humidity"}{TIME} = $tn;
|
||||
# $hash->{CHANGED}[$i++] = $HumidString;
|
||||
# $defs{$name}{READINGS}{"Temperatures"}{VAL} = $TempsString;
|
||||
# $defs{$name}{READINGS}{"Temperatures"}{TIME} = $tn;
|
||||
# $hash->{CHANGED}[$i++] = $TempsString;
|
||||
# $defs{$name}{READINGS}{"Rain/Pressure"}{VAL} = $OtherString;
|
||||
# $defs{$name}{READINGS}{"Rain/Pressure"}{TIME} = $tn;
|
||||
# $hash->{CHANGED}[$i++] = $OtherString;
|
||||
# $defs{$name}{READINGS}{"Forecast"}{VAL} = $StateString;
|
||||
# $defs{$name}{READINGS}{"Forecast"}{TIME} = $tn;
|
||||
# $hash->{CHANGED}[$i++] = $StateString;
|
||||
|
||||
# -wusel, 2010-01-06: FIXME: does this logic with STATE work?
|
||||
# -wusel, 2010-01-30: Removed setting STATE to "reading".
|
||||
|
||||
if($eof) {
|
||||
# $hash->{CHANGED}[$i++] = "Status: $StateString";
|
||||
$hash->{STATE} = $hash->{TMPSTATE};
|
||||
$hash->{TMPSTATE} = "";
|
||||
DoTrigger($name, undef);
|
||||
# } else {
|
||||
# $hash->{STATE} = "reading";
|
||||
}
|
||||
|
||||
return $hash->{STATE};
|
||||
}
|
||||
|
||||
|
||||
# From http://www.perlmonks.org/?node_id=713384 / http://davesource.com/Solutions/20080924.Perl-Non-blocking-Read-On-Pipes-Or-Files.html
|
||||
#
|
||||
# Used, hopefully, with permission ;)
|
||||
#
|
||||
# An non-blocking filehandle read that returns an array of lines read
|
||||
# Returns: ($eof,@lines)
|
||||
my %nonblockGetLines_last;
|
||||
sub nonblockGetLines {
|
||||
my ($fh,$timeout) = @_;
|
||||
|
||||
$timeout = 0 unless defined $timeout;
|
||||
my $rfd = '';
|
||||
$nonblockGetLines_last{$fh} = ''
|
||||
unless defined $nonblockGetLines_last{$fh};
|
||||
|
||||
vec($rfd,fileno($fh),1) = 1;
|
||||
return unless select($rfd, undef, undef, $timeout)>=0;
|
||||
# I'm not sure the following is necessary?
|
||||
return unless vec($rfd,fileno($fh),1);
|
||||
my $buf = '';
|
||||
my $n = sysread($fh,$buf,1024*1024);
|
||||
# If we're done, make sure to send the last unfinished line
|
||||
return (1,$nonblockGetLines_last{$fh}) unless $n;
|
||||
# Prepend the last unfinished line
|
||||
$buf = $nonblockGetLines_last{$fh}.$buf;
|
||||
# And save any newly unfinished lines
|
||||
$nonblockGetLines_last{$fh} =
|
||||
(substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//)
|
||||
? $1 : '';
|
||||
$buf ? (0,split(/\n/,$buf)) : (0);
|
||||
$hash->{CHANGED}[0] = $hash->{STATE};
|
||||
DoTrigger($name, undef);
|
||||
}
|
||||
else {
|
||||
$hash->{STATE} = "no data received";
|
||||
}
|
||||
# Call us in n seconds again.
|
||||
my $nt = gettimeofday() + $hash->{Timer};
|
||||
$nt -= $nt % $hash->{Timer}; # round
|
||||
RemoveInternalTimer($hash);
|
||||
InternalTimer($nt, "WS3600_Read", $hash, 0);
|
||||
|
||||
return $hash->{STATE};
|
||||
}
|
||||
|
||||
1;
|
||||
@ -450,32 +319,55 @@ sub nonblockGetLines {
|
||||
<a name="WS3600"></a>
|
||||
<h3>WS3600</h3>
|
||||
<ul>
|
||||
Defines a weather station, which is queried by means of an external
|
||||
program. That program is executed by FHEM and is expected to deliver the
|
||||
data at stdout in the format of a WS3600 series weather station (details
|
||||
see below).<br>
|
||||
<br>
|
||||
|
||||
<a name="WS3600define"></a>
|
||||
<b>Define</b>
|
||||
<a name="WS3600define"></a> <b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> WS3600 </path/to/fetch3600></code>
|
||||
<br><br>
|
||||
|
||||
Define a WS3600 series weather station (Europe Supplies, technotrade, etc; refer to
|
||||
<a href="http://www.wetterstationsforum.de/ws3600_master-touch.php">Wetterstationen.info</a>
|
||||
(german) for details on this model); the station is queried by means of an external program,
|
||||
fetch3600. It talks to the attached weather station (several WS do supply an RS323 interface
|
||||
but seem to use some kind of "morse code" on the RTS, CTS wires instead of using propper
|
||||
serial communication (RX, TX); it's no use to recode that crap into FHEM when there is a
|
||||
stable package of tools to talk to the station available: <a href=http://open3600.fast-mail.nl/tiki-index.php>open3600</a>)
|
||||
and delivers the current readings line by line as reading-value-pairs. These are read in
|
||||
and translated into more readable names for FHEM by the module WS3600.pm.<br><br>
|
||||
As the WS3600 is rather similar to the <a href=http://www.wetterstationsforum.de/ws2300_matrix.php>WS2300</a>
|
||||
and open3600 basically is a modified offspring of <a href=http://www.lavrsen.dk/twiki/bin/view/Open2300/WebHome>open2300</a>, by exchanging the /path/to/fetch3600 with /path/to/fetch2300 this module
|
||||
should be able to handle the WS2300 was well.<br><br>
|
||||
Currently, it is expected that the WS is attached to the local computer and fetch3600 is run
|
||||
locally. Basically the executable called needs to supply on stdout an output similar to what
|
||||
fetch3600 returns; how to implement a "networked setup" is left as an excercise to the reader.
|
||||
<code>define <name> WS3600 "<wsreaderprog>
|
||||
[<options>]" [<interval>]</code> <br>
|
||||
<br>
|
||||
For the records, this is an output of fetch3600:<pre>
|
||||
Date 14-Nov-2009
|
||||
<ul>
|
||||
<dl>
|
||||
<dt><wsreaderprog></dt>
|
||||
<dd>full path to the executable which queries the weatherstation
|
||||
(for WS3600 series fetch3600 should be used)</dd>
|
||||
<dt><options></dt>
|
||||
<dd>options for <wsreaderprog>, if necessary</dd>
|
||||
<dt><interval></dt>
|
||||
<dd>this optional parameter is the time between subsequent calls to
|
||||
<wsreaderprog>. It defaults to 60s.</dd>
|
||||
</dl>
|
||||
</ul>
|
||||
<br>
|
||||
Supported Stations are:<br>
|
||||
<ul>
|
||||
<li>WS3600 series weather station (Europe Supplies, technotrade, etc;
|
||||
refer to <a href="http://wiki.wetterstationen.info/index.php?title=LaCrosse_WS3600">Wetterstationen.info</a>
|
||||
(german) for details on this model) with fetch3600 from the
|
||||
toolchain <a href="http://open3600.fast-mail.nl/tiki-index.php">open3600</a>).
|
||||
Fetch3600 delivers the current readings line by line as
|
||||
reading-value-pairs. These are read periodically and translated into
|
||||
more readable names for FHEM by the module WS3600.pm. </li>
|
||||
<li><a href="http://wiki.wetterstationen.info/index.php?title=LaCrosse_WS2300">WS2300</a>
|
||||
with toolchain <a href="http://www.lavrsen.dk/twiki/bin/view/Open2300/WebHome">open2300</a>,
|
||||
because it is rather similar to the WS3600.</li>
|
||||
<li><a href="http://wiki.wetterstationen.info/index.php?title=WS1080">WS1080</a>
|
||||
(and other stations which come with the EasyWeather windows
|
||||
application) with <a href="https://code.google.com/p/fowsr/">fowsr</a>
|
||||
(version 2.0 or above)</li>
|
||||
</ul>
|
||||
<br>
|
||||
Currently, it is expected that the WS is attached to the local computer
|
||||
and <wsreaderprog> is run locally. Basically the executable called
|
||||
needs to supply on stdout an output similar to what fetch3600 returns;
|
||||
how to implement a "networked setup" is left as an excercise to the
|
||||
reader. <br>
|
||||
For the records, this is an output of fetch3600:<br>
|
||||
<div style="height: 120px; width: 215px; border: 1px solid #cccccc; overflow: auto;">
|
||||
<pre>Date 14-Nov-2009
|
||||
Time 10:50:22
|
||||
Ti 22.8
|
||||
Timin 20.8
|
||||
@ -562,51 +454,230 @@ TRPmax 09:19
|
||||
DRPmax 11-09-2009
|
||||
Tendency Falling
|
||||
Forecast Cloudy</pre>
|
||||
|
||||
There is no expectation on the readings received from the fetch3600 binary; so, in
|
||||
essence, if you have a similar setup (unsupported, attached weather station and a
|
||||
means to get it's reading into an output similar to above's), you <em>should be able</em>
|
||||
to use WS3600.pm with a custom written script to interface FHEM with your station
|
||||
as well. WS3600.pm <em>only recognizes the above readings</em> (and translates these
|
||||
into, e. g., <code>Temp-inside</code> for <code>Ti</code> for use within FHEM), other
|
||||
lines are silently dropped on the floor.<br><br>
|
||||
|
||||
fetch3600 is available as binary for the Windows OS as well, <em>but I haven't tested operation
|
||||
under that OS, use it at your own risk and you mileage may vary ...</em>
|
||||
<br>Note: Currently this device does not support a "set" function nor anything to "get". The
|
||||
later would be possible to implement if neccessary, though.
|
||||
<br><br>
|
||||
|
||||
Implementation of WS3600.pm tries to be nice, that is it reads from the pipe only
|
||||
non-blocking (== if there is data), so it should be safe even to use it via ssh or
|
||||
a netcat-pipe over the Internet, but this, as well, has not been tested yet.
|
||||
<br><br>
|
||||
|
||||
Attributes:
|
||||
<ul>
|
||||
<li><code>model</code>: <code>WS3600</code> or <code>WS2300</code> (not used for anything, yet)</li>
|
||||
</ul>
|
||||
</div>
|
||||
There is no expectation on the readings received from the fetch3600
|
||||
binary; so, in essence, if you have a similar setup (unsupported,
|
||||
attached weather station and a means to get it's reading into an output
|
||||
similar to above's), you <em>should be able</em> to use WS3600.pm with
|
||||
a custom written script to interface FHEM with your station as well.
|
||||
WS3600.pm <em>only recognizes the above readings</em> (and translates
|
||||
these into, e. g., <code>Temp-inside</code> for <code>Ti</code> for
|
||||
use within FHEM), other lines are silently dropped on the floor. Note:
|
||||
To step down the number of readings date and time records will now be
|
||||
merged to one reading containing date and time. This now also allows
|
||||
records with merged date / time values delivered from
|
||||
<wsreaderprog> - detected by prefix <code>DT</code> (e.g. <code>Date</code>
|
||||
+ <code>Time</code> --> <code>DTime</code>, <code>DRPmin</code> +
|
||||
<code>TRPmin</code> --> <code>DTRPmin</code> and so on). <br>
|
||||
fetch3600 is available as binary for the Windows OS as well, <em>but
|
||||
operation under that OS isn't tested yet.</em> <br>
|
||||
<br>
|
||||
Example:
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define my3600 W36000 /usr/local/bin/fetch360</code><br>
|
||||
<code>define myWS3600 W3600 /usr/local/bin/fetch360</code><br>
|
||||
<code>define myWS1080 W3600 "/usr/local/bin/fowsr -c" 300</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="WS3600set"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="WS3600get"></a>
|
||||
<b>Get</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="WS3600attr"></a>
|
||||
<b>Attributes</b>
|
||||
<a name="WS3600set"></a> <b>Set</b>
|
||||
<ul>
|
||||
<li><a href="#model">model</a> (WS3600, WS2300)</li>
|
||||
N/A
|
||||
</ul>
|
||||
<br>
|
||||
<a name="WS3600get"></a> <b>Get</b>
|
||||
<ul>
|
||||
N/A
|
||||
</ul>
|
||||
<br>
|
||||
<a name="WS3600attr"></a> <b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#model">model</a> WS3600, WS2300,
|
||||
WS1080 (not used for anything, yet)</li>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
=begin html_DE
|
||||
|
||||
<a name="WS3600"></a>
|
||||
<h3>WS3600</h3>
|
||||
<ul>
|
||||
Definiert eine Wetterstation, die über ein externes Programm ausgelesen
|
||||
wird. Dieses Programm wird zyklisch durch FHEM aufgerufen. Es muss die
|
||||
Daten im gleichen Format wie fetch3600 (Details siehe unten) auf der
|
||||
Standardausgabe liefern.<br>
|
||||
<br>
|
||||
<a name="WS3600define"></a> <b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> WS3600 "<wsreaderprog>
|
||||
[<options>]" [<interval>]</code> <br>
|
||||
<br>
|
||||
<ul>
|
||||
<dl>
|
||||
<dt><wsreaderprog></dt>
|
||||
<dd>kompletter Pfad zum Ausleseprogramm (für Wetterstationen Typ
|
||||
WS3600 fetch3600 verwenden)</dd>
|
||||
<dt><options></dt>
|
||||
<dd>Kommandozeilenparameter für <wsreaderprog>, falls
|
||||
erforderlich</dd>
|
||||
<dt><interval></dt>
|
||||
<dd>optionaler Parameter für das Aufrufintervall [s]. Defaultwert
|
||||
ist 60s.</dd>
|
||||
</dl>
|
||||
</ul>
|
||||
<br>
|
||||
Unterstützte Stationen sind:<br>
|
||||
<ul>
|
||||
<li>WS3600 Serie (Europe Supplies, technotrade, usw.; s.a. <a href="http://wiki.wetterstationen.info/index.php?title=LaCrosse_WS3600">Wetterstationen.info</a>
|
||||
(deutsch) für Details) in Verbindung mit fetch3600 aus dem Paket <a
|
||||
href="http://open3600.fast-mail.nl/tiki-index.php">open3600</a>).
|
||||
Fetch3600 liefert die aktuellen Werte zeilenweise als
|
||||
Name-Wert-Paare. Diese werden durch FHEM zyklisch eingelesen, mit
|
||||
besser lesbaren Bezeichnungen versehen und als Readings zur
|
||||
Verfügung gestellt. </li>
|
||||
<li><a href="http://wiki.wetterstationen.info/index.php?title=LaCrosse_WS2300">WS2300</a>
|
||||
Serie in Verbindung mit dem Paket <a href="http://www.lavrsen.dk/twiki/bin/view/Open2300/WebHome">open2300</a>
|
||||
(ähnlich zu open3600).</li>
|
||||
<li><a href="http://wiki.wetterstationen.info/index.php?title=WS1080">WS1080</a>
|
||||
(und andere Stationen, die mit der Windows-Software "Easy Weather"
|
||||
ausgeliefert werden) in Verbindung mit <a href="https://code.google.com/p/fowsr/">fowsr</a>
|
||||
(ab Version 2.0)</li>
|
||||
</ul>
|
||||
<br>
|
||||
Es wird vorausgesetzt, dass die Wetterstation am lokalen Computer
|
||||
angeschlossen ist und <wsreaderprog> deshalb lokal läuft.
|
||||
<wsreaderprog> muss grundsätzlich eine zu fetch3600 vergleichbare
|
||||
Ausgabe auf der Standardausgabe liefern. <br>
|
||||
Als Beispiel für das erwartete Format hier die Ausgabe von fetch3600:<br>
|
||||
<div style="height: 120px; width: 215px; border: 1px solid #cccccc; overflow: auto;">
|
||||
<pre>Date 14-Nov-2009
|
||||
Time 10:50:22
|
||||
Ti 22.8
|
||||
Timin 20.8
|
||||
Timax 27.9
|
||||
TTimin 10:27
|
||||
DTimin 15-10-2009
|
||||
TTimax 23:31
|
||||
DTimax 20-08-2009
|
||||
To 14.2
|
||||
Tomin -0.4
|
||||
Tomax 35.6
|
||||
TTomin 07:03
|
||||
DTomin 15-10-2009
|
||||
TTomax 16:52
|
||||
DTomax 20-08-2009
|
||||
DP 9.2
|
||||
DPmin -2.2
|
||||
DPmax 20.3
|
||||
TDPmin 07:03
|
||||
DDPmin 15-10-2009
|
||||
TDPmax 11:58
|
||||
DDPmax 20-08-2009
|
||||
RHi 48
|
||||
RHimin 32
|
||||
RHimax 57
|
||||
TRHimin 17:03
|
||||
DRHimin 21-10-2009
|
||||
TRHimax 22:24
|
||||
DRHimax 07-10-2009
|
||||
RHo 72
|
||||
RHomin 27
|
||||
RHomax 96
|
||||
TRHomin 16:41
|
||||
DRHomin 20-08-2009
|
||||
TRHomax 06:28
|
||||
DRHomax 02-11-2009
|
||||
WS 0.0
|
||||
DIRtext WSW
|
||||
DIR0 247.5
|
||||
DIR1 247.5
|
||||
DIR2 247.5
|
||||
DIR3 247.5
|
||||
DIR4 247.5
|
||||
DIR5 247.5
|
||||
WC 14.2
|
||||
WCmin -0.4
|
||||
WCmax 35.6
|
||||
TWCmin 07:03
|
||||
DWCmin 15-10-2009
|
||||
TWCmax 16:52
|
||||
DWCmax 20-08-2009
|
||||
WSmin 0.0
|
||||
WSmax 25.6
|
||||
TWSmin 10:44
|
||||
DWSmin 14-11-2009
|
||||
TWSmax 19:08
|
||||
DWSmax 24-09-2009
|
||||
R1h 0.00
|
||||
R1hmax 24.34
|
||||
TR1hmax 22:34
|
||||
DR1hmax 07-10-2009
|
||||
R24h 0.00
|
||||
R24hmax 55.42
|
||||
TR24hmax 07:11
|
||||
DR24hmax 08-10-2009
|
||||
R1w 29.00
|
||||
R1wmax 95.83
|
||||
TR1wmax 00:00
|
||||
DR1wmax 12-10-2009
|
||||
R1m 117.58
|
||||
R1mmax 117.58
|
||||
TR1mmax 00:00
|
||||
DR1mmax 01-11-2009
|
||||
Rtot 3028.70
|
||||
TRtot 03:29
|
||||
DRtot 18-09-2005
|
||||
RP 992.200
|
||||
AP 995.900
|
||||
RPmin 970.300
|
||||
RPmax 1020.000
|
||||
TRPmin 05:25
|
||||
DRPmin 04-11-2009
|
||||
TRPmax 09:19
|
||||
DRPmax 11-09-2009
|
||||
Tendency Falling
|
||||
Forecast Cloudy</pre>
|
||||
</div>
|
||||
Welche der vorgenannten Wertepaare durch <wsreaderprog>
|
||||
geliefert werden, ist egal. Jedes bekannte wird übersetzt (z.B. <code>Ti</code>
|
||||
nach <code>Temp-inside</code>) und als Reading angezeigt, alle
|
||||
unbekannten werden kommentarlos verworfen. Mittels geeignetem Programm
|
||||
oder Script sollte sich also jede beliebige Wetterstation anschließen
|
||||
lassen. <br>
|
||||
Anmerkung: Um die Anzahl Readings zu reduzieren, werden jetzt Date- und
|
||||
Time-Wertepaare zusammengefasst. Es ist jetzt auch zulässig, dass
|
||||
<wsreaderprog> schon kombinierte Wertepaare liefert. Diese sind
|
||||
mit dem Prefix <code>DT</code> zu kennzeichnen, also z.B. <code>Date</code>
|
||||
+ <code>Time</code> --> <code>DTime</code>, <code>DRPmin</code> +
|
||||
<code>TRPmin</code> --> <code>DTRPmin</code> usw.).<br>
|
||||
<em>Fetch3600 ist auch unter Windows verfügbar, ob das Zusammenspiel mit
|
||||
FHEM dort auch funktioniert, wurde noch nicht getestet.</em> <br>
|
||||
<br>
|
||||
Beispiele:
|
||||
<ul>
|
||||
<code>define myWS3600 W3600 /usr/local/bin/fetch360</code><br>
|
||||
<code>define myWS1080 W3600 "/usr/local/bin/fowsr -c" 300</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
<a name="WS3600set"></a> <b>Set</b>
|
||||
<ul>
|
||||
N/A
|
||||
</ul>
|
||||
<br>
|
||||
<a name="WS3600get"></a> <b>Get</b>
|
||||
<ul>
|
||||
N/A
|
||||
</ul>
|
||||
<br>
|
||||
<a name="WS3600attr"></a> <b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#model">model</a> WS3600, WS2300,
|
||||
WS1080 (z.Zt (noch) ohne Wirkung)</li>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
=end html_DE
|
||||
=cut
|
||||
|
@ -124,7 +124,7 @@ FHEM/70_STV.pm bentele http://forum.fhem.de Sonstiges
|
||||
FHEM/70_TellStick.pm real-wusel http://forum.fhem.de Sonstiges
|
||||
FHEM/70_USBWX.pm wherzig http://forum.fhem.de Sonstiges
|
||||
FHEM/70_VIERA.pm teevau http://forum.fhem.de Sonstiges
|
||||
FHEM/70_WS3600.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/70_WS3600.pm Josch http://forum.fhem.de Sonstiges
|
||||
FHEM/71_LISTENLIVE.pm betateilchen http://forum.fhem.de Multimedia
|
||||
FHEM/71_YAMAHA_AVR.pm markusbloch http://forum.fhem.de Multimedia
|
||||
FHEM/72_FB_CALLMONITOR.pm markusbloch http://forum.fhem.de Unterstützende Dienste
|
||||
|
Loading…
x
Reference in New Issue
Block a user