2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-15 16:19:11 +00:00

14_Hideki.pm: Fixed wind direction and output as floatingpoint values

git-svn-id: https://svn.fhem.de/fhem/trunk@26983 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
sidey79 2023-01-06 11:58:49 +00:00
parent e2bb20f19b
commit 9c8e93a2de
2 changed files with 157 additions and 38 deletions

View File

@ -1,5 +1,7 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
- change: 14_Hideki.pm: output wind values always as floatingpoint
- bugix: 14_Hideki.pm: fixed wind direction
- feature: 14_SD_WS.pm: new sensor Bresser 7-in-1 Comfort Wetter Center
new set command to allow battery replacement
new sensor SM60020 multi purpose environment sensor
@ -31,8 +33,8 @@
remote control RCnoName20_10
Temola TM 40 support
remote control DC-1961-TG
- bugfix: SD_ProtocolData.pm: bugfix Bresser protocols
prevents Perl warning WS2000
- bugfix: SD_ProtocolData.pm: bugfix Bresser protocols
prevents Perl warning WS2000
- feature: 75_MSG: add new msg schema entry for Matrix and SignalBot
- feature: 75_msgConfig: add commandref
- bugfix: 98_todoist: key in header

View File

@ -15,6 +15,7 @@ package main;
use strict;
use warnings;
use POSIX;
use FHEM::Meta;
#use Data::Dumper;
@ -37,6 +38,7 @@ Hideki_Initialize($)
$hash->{AutoCreate}=
{ "Hideki.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"} };
return FHEM::Meta::InitMod( __FILE__, $hash );
}
@ -79,9 +81,9 @@ Hideki_Parse($$)
my ($iohash,$msg) = @_;
my (undef ,$rawData) = split("#",$msg);
my $name = $iohash->{NAME};
my $ioname = $iohash->{NAME};
my @a = split("", $msg);
Log3 $iohash, 4, "$name Hideki_Parse: incomming $msg";
Log3 $iohash, 4, "$ioname Hideki_Parse: incomming $msg";
my @decodedData;
my $crc1crc2OK = 0;
@ -93,16 +95,16 @@ Hideki_Parse($$)
# decrypt and decodedBytes are now done with decryptAndCheck
my $decodedString = join '', unpack('H*', pack('C*',@decodedData)); # get hex string
Log3 $iohash, 4, "$name Hideki_Parse: raw=$rawData, decoded=$decodedString";
Log3 $iohash, 4, "$ioname Hideki_Parse: raw=$rawData, decoded=$decodedString";
if (!@decodedData) {
Log3 $iohash, 4, "$name Hideki_Parse: decrypt failed";
Log3 $iohash, 4, "$ioname Hideki_Parse: decrypt failed";
return '';
}
Log3 $iohash, 5, "$name Hideki_Parse: getSensorType for ".$decodedData[3];
Log3 $iohash, 5, "$ioname Hideki_Parse: getSensorType for ".$decodedData[3];
my $sensorTyp=($decodedData[3] & 0x1F);
Log3 $iohash, 4, "$name Hideki_Parse: SensorTyp = $sensorTyp decodedString = $decodedString";
Log3 $iohash, 4, "$ioname Hideki_Parse: SensorTyp = $sensorTyp decodedString = $decodedString";
my $id=substr($decodedString,2,2); # get the random id from the data
my $channel=0;
@ -136,75 +138,74 @@ Hideki_Parse($$)
elsif ($comfort == 2) { $comfort = 'Dry. Less than 40% RH' }
elsif ($comfort == 3) { $comfort = 'Temp. and Hum. comfortable' }
$val = "T: $temp H: $hum";
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp, humidity=$hum, comfort=$comfort";
Log3 $iohash, 4, "$ioname decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp, humidity=$hum, comfort=$comfort";
}elsif($sensorTyp==31){
($channel, $temp) = decodeThermo(\@decodedData);
$bat = ($decodedData[2] >> 6 == 3) ? 'ok' : 'low'; # decode battery
$count = $decodedData[3] >> 6; # verifiziert, MSG_Counter
$val = "T: $temp";
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp";
Log3 $iohash, 4, "$ioname decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp";
}elsif($sensorTyp==14){
($channel, $rain) = decodeRain(\@decodedData); # decodeThermoHygro($decodedString);
$bat = ($decodedData[2] >> 6 == 3) ? 'ok' : 'low'; # decode battery
$count = $decodedData[3] >> 6; # UNVERIFIZIERT, MSG_Counter
$val = "R: $rain";
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, rain=$rain, unknown=$unknown";
Log3 $iohash, 4, "$ioname decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, rain=$rain, unknown=$unknown";
}elsif($sensorTyp==12){
($channel, $temp) = decodeThermo(\@decodedData); # decodeThermoHygro($decodedString);
($windchill,$windspeed,$windgust,$winddir,$winddirdeg,$winddirtext) = wind(\@decodedData);
#($windchill,$windspeed,$windgust,$winddir,$winddirdeg,$winddirtext) = wind(\@decodedData); ## nach unten verschoben
$bat = ($decodedData[2] >> 6 == 3) ? 'ok' : 'low'; # decode battery
$count = $decodedData[3] >> 6; # UNVERIFIZIERT, MSG_Counter
$val = "T: $temp Ws: $windspeed Wg: $windgust Wd: $winddirtext";
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp, Wc=$windchill, Ws=$windspeed, Wg=$windgust, Wd=$winddir, WdDeg=$winddirdeg, Wdtxt=$winddirtext";
#$val = "T: $temp Ws: $windspeed Wg: $windgust Wd: $winddirtext"; ## nach unten verschoben
Log3 $iohash, 4, "$ioname decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp";
}elsif($sensorTyp==13){
($channel, $temp) = decodeThermo(\@decodedData); # decodeThermoHygro($decodedString);
$bat = ($decodedData[2] >> 6 == 3) ? 'ok' : 'low'; # decode battery
$count = $decodedData[3] >> 6; # UNVERIFIZIERT, MSG_Counter
$val = "T: $temp";
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp";
Log3 $iohash, 4, "$name Sensor Typ $sensorTyp currently not full supported, please report sensor information!";
Log3 $iohash, 4, "$ioname decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, cnt=$count, bat=$bat, temp=$temp";
Log3 $iohash, 4, "$ioname Sensor Typ $sensorTyp currently not full supported, please report sensor information!";
}
else{
Log3 $iohash, 4, "$name Sensor Typ $sensorTyp not supported, please report sensor information!";
Log3 $iohash, 4, "$ioname Sensor Typ $sensorTyp not supported, please report sensor information!";
return "";
}
my $longids = AttrVal($iohash->{NAME},'longids',0);
if ( ($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
{
$deviceCode=$model . "_" . $id . "." . $channel;
Log3 $iohash,4, "$name Hideki_Parse: using longid: $longids model: $model";
Log3 $iohash,4, "$ioname Hideki_Parse: using longid: $longids model: $model";
} else {
$deviceCode = $model . "_" . $channel;
}
Log3 $iohash, 5, "$name Hideki_Parse deviceCode: $deviceCode";
Log3 $iohash, 5, "$ioname Hideki_Parse deviceCode: $deviceCode";
my $def = $modules{Hideki}{defptr}{$iohash->{NAME} . "." . $deviceCode};
$def = $modules{Hideki}{defptr}{$deviceCode} if(!$def);
if(!$def) {
Log3 $iohash, 1, "$name Hideki: UNDEFINED sensor $deviceCode detected, code $msg";
Log3 $iohash, 1, "$ioname Hideki: UNDEFINED sensor $deviceCode detected, code $msg";
return "UNDEFINED $deviceCode Hideki $deviceCode";
}
my $hash = $def;
$name = $hash->{NAME};
my $name = $hash->{NAME};
return "" if(IsIgnored($name));
#Log3 $name, 4, "Hideki: $name ($msg)";
my $WindSpeedCorr = AttrVal($name,"windSpeedCorr",0);
if ($WindSpeedCorr > 0 && $sensorTyp == 12) {
$windspeed = sprintf("%.2f", $windspeed * $WindSpeedCorr);
$windgust = sprintf("%.2f", $windgust * $WindSpeedCorr);
Log3 $name, 4, "$name Hideki_Parse: WindSpeedCorr=$WindSpeedCorr, WindSpeed=$windspeed, WindGust=$windgust";
if ($sensorTyp == 12) { # Wind
($windchill,$windspeed,$windgust,$winddir,$winddirdeg,$winddirtext) = wind($name, \@decodedData);
$val = "T: $temp Ws: $windspeed Wg: $windgust Wd: $winddirtext";
Log3 $name, 4, "$ioname $name Parse: model=12(wind), T: $temp, Wc=$windchill, Ws=$windspeed, Wg=$windgust, Wd=$winddir, WdDeg=$winddirdeg, Wdtxt=$winddirtext";
}
if (!defined(AttrVal($hash->{NAME},"event-min-interval",undef)))
if (!defined(AttrVal($name,"event-min-interval",undef)))
{
my $minsecs = AttrVal($iohash->{NAME},'minsecs',0);
my $minsecs = AttrVal($ioname,'minsecs',0);
if($hash->{lastReceive} && (time() - $hash->{lastReceive} < $minsecs)) {
Log3 $iohash, 4, "$name Hideki_Parse: $deviceCode Dropped ($decodedString) due to short time. minsecs=$minsecs";
Log3 $name, 4, "$name Hideki_Parse: $deviceCode Dropped ($decodedString) due to short time. minsecs=$minsecs";
return "";
}
}
@ -399,7 +400,9 @@ sub decodeRain {
# P12#758BB244074007400F00001C6E7A01
sub wind {
my $name = shift;
my @Hidekibytes = @{$_[0]};
my @wd=(0, 15, 13, 14, 9, 10, 12, 11, 1, 2, 4, 3, 8, 7, 5, 6);
my @winddir_name=("N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW");
my $windspeed;
my $windchill;
@ -416,7 +419,19 @@ sub wind {
$windchill = $windchill / 10;
$windspeed = ($Hidekibytes[9] & 0x0f ) * 100 + ($Hidekibytes[8] >> 4) * 10 + ($Hidekibytes[8] & 0x0f);
$windgust = ($Hidekibytes[10] >> 4) * 100 + ($Hidekibytes[10] & 0x0f) * 10 + ($Hidekibytes[9] >> 4);
$winddir = ($Hidekibytes[11] >> 4);
my $windSpeedCorr = AttrVal($name,'windSpeedCorr',1); ### -> hierher verschoben
if ($windSpeedCorr > 0) {
$windspeed = sprintf("%.2f", $windspeed * $windSpeedCorr);
$windgust = sprintf("%.2f", $windgust * $windSpeedCorr);
Log3 $name, 5, "$name Hideki_Parse: WindSpeedCorr factor=$windSpeedCorr";
}
$winddir = $wd[$Hidekibytes[11] >> 4];
my $windDirCorr = AttrVal($name,'windDirCorr',0);
if ($windDirCorr > 0) {
$winddir += $windDirCorr;
$winddir &= 15;
Log3 $name, 5, "$name Hideki_Parse: windDirCorr=$windDirCorr";
}
$winddirtext = $winddir_name[$winddir];
$winddirdeg = $winddir * 22.5;
@ -469,7 +484,7 @@ sub wind {
<li>battery & batteryState (ok or low)</li>
<li>channel (The Channelnumber (number if)</li>
<li>humidity (0-100)</li>
<li>state (T:x H:y B:z)</li>
<li>state (T:x.xx H:y B:z)</li>
<li>temperature (&deg;C)</li>
<br><i>- Hideki only -</i>
<li>comfort_level (Status: Humidity OK... , Wet. More than 69% RH, Dry. Less than 40% RH, Temperature and humidity comfortable)</li>
@ -491,8 +506,16 @@ sub wind {
<li><a href="#ignore">ignore</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li><a href="#showtime">showtime</a></li>
<li><a name="windSpeedCorr"></a>windSpeedCorr<br>
correction value of your displayed windSpeed </li>
<li><a name="windDirCorr"></a>windDirCorr<br>
correction value of your displayed wind direction deztimal degree value. The correction value is added to the measured direction in dgrees.<br>
Example value: 5<br>
Default value: 0<br>
</li>
<li><a name="windSpeedCorr"></a>windSpeedCorr<br>
correction value of your displayed wind speed as floatingpoint value. The measured speed is multiplied with the specified value. The value 0 disables the feature.<br>
Example value: 1.25<br>
Default value: 1<br>
</li>
</ul>
<br>
</ul>
@ -540,7 +563,7 @@ sub wind {
<li>battery & batteryState (ok oder low)</li>
<li>channel (Der Sensor Kanal)</li>
<li>humidity (0-100)</li>
<li>state (T:x H:y B:z)</li>
<li>state (T:x.xx H:y B:z)</li>
<li>temperature (&deg;C)</li>
<br><i>- Hideki spezifisch -</i>
@ -561,11 +584,105 @@ sub wind {
<li><a href="#ignore">ignore</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li><a href="#showtime">showtime</a></li>
<li><a name="windSpeedCorr"></a>windSpeedCorr<br>
Korrekturwert Ihrer angezeigten Windgeschwindigkeit</li>
</ul>
<br>
<li><a name="windDirCorr"></a>windDirCorr<br>
Korrekturwert Ihrer angezeigten Windrichtung in Grad. Der Korrekturwert wird zu dem gemessenen Grad Wert Addiert.<br>
Beispielwert: 5<br>
Standardwert: 0<br>
</li>
<li><a name="windSpeedCorr"></a>windSpeedCorr<br>
Korrekturwert Ihrer angezeigten Windgeschwindigkeit als Fließkommezahk. Die gemessene Geschwindigkeit wird mit dem angegeben Wert multiplizuert. Der Wert 0 deaktiviert die Funktion.<br>
Beispielwert: 1.25<br>
Standardwert: 1<br>
</li> <br>
</ul>
</ul>
=end html_DE
=for :application/json;q=META.json 14_Hideki.pm
{
"abstract": "Supports various rf sensors with hideki protocol",
"author": [
"Sidey <>",
"ralf9 <>"
],
"x_fhem_maintainer": [
"Sidey"
],
"x_fhem_maintainer_github": [
"Sidey79",
"HomeAutoUser",
"elektron-bbs"
],
"description": "The Hideki module is a module for decoding weather sensors, which use the hideki protocol. Known brands are Bresser, Cresta, TFA and Hama",
"dynamic_config": 1,
"keywords": [
"fhem-sonstige-systeme",
"fhem-hausautomations-systeme",
"fhem-mod",
"signalduino",
"Hideki",
"Hama",
"TFA",
"Bresser"
],
"license": [
"GPL_2"
],
"meta-spec": {
"url": "https://metacpan.org/pod/CPAN::Meta::Spec",
"version": 2
},
"name": "FHEM::Hideki",
"prereqs": {
"runtime": {
"requires": {
"POSIX": "0"
}
},
"develop": {
"requires": {
"POSIX": "0"
}
}
},
"release_status": "stable",
"resources": {
"bugtracker": {
"web": "https://github.com/RFD-FHEM/RFFHEM/issues/"
},
"x_testData": [
{
"url": "https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master/t/FHEM/14_Hideki/testData.json",
"testname": "Testdata with Hideki protocol sensors"
}
],
"repository": {
"x_master": {
"type": "git",
"url": "https://github.com/RFD-FHEM/RFFHEM.git",
"web": "https://github.com/RFD-FHEM/RFFHEM/tree/master"
},
"type": "svn",
"url": "https://svn.fhem.de/fhem",
"web": "https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/14_Hideki.pm",
"x_branch": "trunk",
"x_filepath": "fhem/FHEM/",
"x_raw": "https://svn.fhem.de/trac/export/latest/trunk/fhem/FHEM/14_Hideki.pm"
},
"x_support_community": {
"board": "Sonstige Systeme",
"boardId": "29",
"cat": "FHEM - Hausautomations-Systeme",
"description": "Sonstige Hausautomations-Systeme",
"forum": "FHEM Forum",
"rss": "https://forum.fhem.de/index.php?action=.xml;type=rss;board=29",
"title": "FHEM Forum: Sonstige Systeme",
"web": "https://forum.fhem.de/index.php/board,29.0.html"
},
"x_wiki": {
"web": "https://wiki.fhem.de/wiki/SIGNALduino"
}
}
}
=end :application/json;q=META.json
=cut