mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
98_ModbusElsnerWS: wind observation readings added
git-svn-id: https://svn.fhem.de/fhem/trunk@20252 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1cc5f7e272
commit
11f4e76955
@ -173,6 +173,20 @@ sub ModbusElsnerWS_Eval($$$) {
|
||||
my $name = $hash->{NAME};
|
||||
my $ctrl = 1;
|
||||
my ($temperature, $sunSouth, $sunWest, $sunEast, $brightness, $windSpeed, $gps, $isRaining, $date, $time, $sunAzimuth, $sunElevation, $latitude, $longitude) = split(' ', $readingVal);
|
||||
my ($windAvg2min, $windGust10min, $windGustCurrent, $windPeak10min);
|
||||
if ($hash->{INTERVAL} =~ m/^1$/) {
|
||||
$hash->{helper}{wind}{windSpeedNumArrayElements} = ModubusElsnerWS_updateArrayElement($hash, 'windSpeed', $windSpeed, 'wind', 600);
|
||||
my ($windAvg10min, $windSpeedMin10min, $windSpeedMax10min) = ModubusElsnerWS_SMA($hash, 'windSpeed', $windSpeed, 'windAvg10min', 'windSpeedMax10min', 'windSpeedMin10min', 'wind', 600);
|
||||
($windAvg2min, undef, undef) = ModubusElsnerWS_SMA($hash, 'windSpeed', $windSpeed, 'windAvg2min', undef, undef, 'wind', 120);
|
||||
my ($windAvg20s, $windSpeedMin20s, $windSpeedMax20s) = ModubusElsnerWS_SMA($hash, 'windSpeed', $windSpeed, 'windAvg20s', 'windSpeedMax20s', 'windSpeedMin20s', 'wind', 20);
|
||||
($windGustCurrent, undef, undef) = ModubusElsnerWS_SMA($hash, 'windSpeed', $windSpeed, 'windGustCurrent', undef, undef, 'wind', 3);
|
||||
$windPeak10min = $windSpeedMax10min >= 12.86 ? $windSpeedMax10min : $windAvg2min;
|
||||
my $windGust20s = $windGustCurrent >= $windSpeedMin20s + 5.144 ? $windGustCurrent : 0;
|
||||
$windGustCurrent = $windGustCurrent >= $windSpeedMin20s + 5.144 ? $windGustCurrent : $windAvg2min;
|
||||
$hash->{helper}{wind}{windGustNumArrayElements} = ModubusElsnerWS_updateArrayElement($hash, 'windGust', $windGust20s, 'wind', 600);
|
||||
my ($windGustAvg10min, $windGustMin10min, $windGustMax10min) = ModubusElsnerWS_SMA($hash, 'windGust', $windGust20s, 'windGustAvg10min', 'windGustMax10min', 'windGustMin10min', 'wind', 600);
|
||||
$windGust10min = $windGustMax10min >= 5.144 ? $windGustMax10min : $windAvg2min;
|
||||
}
|
||||
my @sunlight = ($sunSouth, $sunWest, $sunEast);
|
||||
my ($sunMin, $sunMax) = (sort {$a <=> $b} @sunlight)[0,-1];
|
||||
$sunSouth = $sunSouth == 0 ? $brightness : $sunSouth;
|
||||
@ -191,6 +205,14 @@ sub ModbusElsnerWS_Eval($$$) {
|
||||
while($windSpeed > $windStrength[$windStrength] && $windStrength <= @windStrength + 1) {
|
||||
$windStrength ++;
|
||||
}
|
||||
if ($hash->{INTERVAL} =~ m/^1$/ && (!exists($hash->{helper}{timer}{lastUpdate}) || $hash->{helper}{timer}{lastUpdate} < gettimeofday() - 60)) {
|
||||
# update every 60 sec
|
||||
readingsBulkUpdateIfChanged($hash, "windAvg2min", sprintf("%0.1f", $windAvg2min));
|
||||
readingsBulkUpdateIfChanged($hash, "windGust10min", sprintf("%0.1f", $windGust10min));
|
||||
readingsBulkUpdateIfChanged($hash, "windGustCurrent", sprintf("%0.1f", $windGustCurrent));
|
||||
readingsBulkUpdateIfChanged($hash, "windPeak10min", sprintf("%0.1f", $windPeak10min));
|
||||
$hash->{helper}{timer}{lastUpdate} = gettimeofday();
|
||||
}
|
||||
if (exists $hash->{helper}{timer}{heartbeat}) {
|
||||
readingsBulkUpdateIfChanged($hash, "isRaining", $isRaining);
|
||||
readingsBulkUpdateIfChanged($hash, "windStrength", $windStrength);
|
||||
@ -356,25 +378,42 @@ sub ModbusElsnerWS_Notify(@) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub ModbusElsnerWS_SMA($$$$) {
|
||||
# simple moving average (SMA)
|
||||
my ($hash, $readingName, $readingVal, $averageOrder) = @_;
|
||||
my $average = exists($hash->{helper}{sma}{$readingName}{average}) ? $hash->{helper}{sma}{$readingName}{average} : $readingVal;
|
||||
my $numArrayElements = $#{$hash->{helper}{sma}{$readingName}{val}};
|
||||
if (defined($numArrayElements) && $numArrayElements >= 0) {
|
||||
if ($numArrayElements < $averageOrder - 1) {
|
||||
$average = $average + $readingVal / ($numArrayElements + 1)
|
||||
- $hash->{helper}{sma}{$readingName}{val}[$numArrayElements] / ($numArrayElements + 1);
|
||||
} else {
|
||||
$average = $average + $readingVal / ($numArrayElements + 1)
|
||||
- pop(@{$hash->{helper}{sma}{$readingName}{val}}) / ($numArrayElements + 1);
|
||||
}
|
||||
sub ModubusElsnerWS_updateArrayElement($$$$$) {
|
||||
# read und update values to array
|
||||
my ($hash, $readingName, $readingVal, $arrayName, $numArrayElementsMax) = @_;
|
||||
my $numArrayElements = $#{$hash->{helper}{$arrayName}{$readingName}{val}};
|
||||
if (!defined $numArrayElements) {
|
||||
$numArrayElements = 1;
|
||||
} elsif ($numArrayElements + 1 >= $numArrayElementsMax) {
|
||||
$numArrayElements = $numArrayElementsMax;
|
||||
pop(@{$hash->{helper}{$arrayName}{$readingName}{val}});
|
||||
} else {
|
||||
$average = $readingVal;
|
||||
$numArrayElements ++;
|
||||
}
|
||||
unshift(@{$hash->{helper}{sma}{$readingName}{val}}, $readingVal);
|
||||
$hash->{helper}{sma}{$readingName}{average} = $average;
|
||||
return $average;
|
||||
unshift(@{$hash->{helper}{$arrayName}{$readingName}{val}}, $readingVal);
|
||||
return $numArrayElements;
|
||||
}
|
||||
|
||||
sub ModubusElsnerWS_SMA($$$$$$$$) {
|
||||
# simple moving average (SMA)
|
||||
my ($hash, $readingName, $readingVal, $averageName, $valMaxName, $valMinName, $arrayName, $numArrayElementsCalc) = @_;
|
||||
my $average = exists($hash->{helper}{$arrayName}{$readingName}{average}) ? $hash->{helper}{$arrayName}{$readingName}{average} : $readingVal;
|
||||
my ($valMin, $valMax) = ($readingVal, $readingVal);
|
||||
my $numArrayElements = $#{$hash->{helper}{$arrayName}{$readingName}{val}};
|
||||
if (!defined $numArrayElements) {
|
||||
$average = $readingVal;
|
||||
} else {
|
||||
$numArrayElements = $numArrayElementsCalc - 1 if ($numArrayElements + 1 >= $numArrayElementsCalc);
|
||||
$average = $average + $readingVal / ($numArrayElements + 1)
|
||||
- $hash->{helper}{$arrayName}{$readingName}{val}[$numArrayElements] / ($numArrayElements + 1);
|
||||
}
|
||||
if (defined($valMaxName) && defined($valMinName)) {
|
||||
($valMin, $valMax) = (sort {$a <=> $b} @{$hash->{helper}{$arrayName}{$readingName}{val}})[0, $numArrayElements];
|
||||
$hash->{helper}{$arrayName}{$readingName}{$valMaxName} = $valMax;
|
||||
$hash->{helper}{$arrayName}{$readingName}{$valMinName} = $valMin;
|
||||
}
|
||||
$hash->{helper}{$arrayName}{$readingName}{$averageName} = $average;
|
||||
return ($average, $valMin, $valMax);
|
||||
}
|
||||
|
||||
sub ModbusElsnerWS_LWMA($$$$) {
|
||||
@ -596,6 +635,7 @@ sub ModbusElsnerWS_Delete($$) {
|
||||
<ul>
|
||||
<li>Evaluation modul for the weather sensors P03/3-Modbus and P03/3-Modbus GPS</li>
|
||||
<li>Processing weather raw data and creates graphic representation</li>
|
||||
<li>For wind observations, average speeds, gusts and peak values are calculated.</li>
|
||||
<li>Alarm signal in case of failure of the weather sensor</li>
|
||||
<li>Up/down readings for blinds according to wind, rain and sun</li>
|
||||
<li>Adjustable switching thresholds and delay times</li>
|
||||
@ -630,7 +670,9 @@ sub ModbusElsnerWS_Delete($$) {
|
||||
<ul>
|
||||
<code>define <name> ModbusElsnerWS id=<ID> interval=<Interval>|passive</code><br><br>
|
||||
The module connects to the Elsner Weather Station with the Modbus Id <ID> through an already defined Modbus device
|
||||
and actively requests data from the system every <Interval> seconds. The query interval should be set to 1 second.<br>
|
||||
and actively requests data from the system every <Interval> seconds. The query interval should be set to 1 second.
|
||||
The readings windAvg2min, windGust10min, windGustCurrent and windPeak10min required for wind observation are calculated
|
||||
only at a query interval of 1 second.<br>
|
||||
The following parameters apply to the default factory settings and an RS485 transceiver to USB.
|
||||
<br><br>
|
||||
Example:<br>
|
||||
@ -756,6 +798,10 @@ sub ModbusElsnerWS_Delete($$) {
|
||||
<li>time: hh:mm:ss</li>
|
||||
<li>timeZone: CET|CEST|UTC</li>
|
||||
<li>twilight: T/% (Sensor Range: T = 0 % ... 100 %)</li>
|
||||
<li>windAvg2min: v/m/s (Sensor Range: v = 0 m/s ... 70 m/s)</li>
|
||||
<li>windGust10min: v/m/s (Sensor Range: v = 0 m/s ... 70 m/s)</li>
|
||||
<li>windGustCurrent: v/m/s (Sensor Range: v = 0 m/s ... 70 m/s)</li>
|
||||
<li>windPeak10min: v/m/s (Sensor Range: v = 0 m/s ... 70 m/s)</li>
|
||||
<li>windSpeed: v/m/s (Sensor Range: v = 0 m/s ... 70 m/s)</li>
|
||||
<li>windStrength: B (Sensor Range: B = 0 Beaufort ... 12 Beaufort)</li>
|
||||
<li>state: T: t/°C B: E/lx W: v/m/s IR: no|yes</li>
|
||||
|
Loading…
Reference in New Issue
Block a user