diff --git a/fhem/CHANGED b/fhem/CHANGED index 32dc1dfcc..445dfdf27 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -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 diff --git a/fhem/FHEM/14_Hideki.pm b/fhem/FHEM/14_Hideki.pm index 683c388ca..c7341e5ab 100644 --- a/fhem/FHEM/14_Hideki.pm +++ b/fhem/FHEM/14_Hideki.pm @@ -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 {
  • battery & batteryState (ok or low)
  • channel (The Channelnumber (number if)
  • humidity (0-100)
  • -
  • state (T:x H:y B:z)
  • +
  • state (T:x.xx H:y B:z)
  • temperature (°C)

  • - Hideki only -
  • comfort_level (Status: Humidity OK... , Wet. More than 69% RH, Dry. Less than 40% RH, Temperature and humidity comfortable)
  • @@ -491,8 +506,16 @@ sub wind {
  • ignore
  • readingFnAttributes
  • showtime
  • -
  • windSpeedCorr
    - correction value of your displayed windSpeed
  • +
  • windDirCorr
    + correction value of your displayed wind direction deztimal degree value. The correction value is added to the measured direction in dgrees.
    + Example value: 5
    + Default value: 0
    +
  • +
  • windSpeedCorr
    + 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.
    + Example value: 1.25
    + Default value: 1
    +

  • @@ -540,7 +563,7 @@ sub wind {
  • battery & batteryState (ok oder low)
  • channel (Der Sensor Kanal)
  • humidity (0-100)
  • -
  • state (T:x H:y B:z)
  • +
  • state (T:x.xx H:y B:z)
  • temperature (°C)

  • - Hideki spezifisch - @@ -561,11 +584,105 @@ sub wind {
  • ignore
  • readingFnAttributes
  • showtime
  • -
  • windSpeedCorr
    - Korrekturwert Ihrer angezeigten Windgeschwindigkeit
  • - -
    +
  • windDirCorr
    + Korrekturwert Ihrer angezeigten Windrichtung in Grad. Der Korrekturwert wird zu dem gemessenen Grad Wert Addiert.
    + Beispielwert: 5
    + Standardwert: 0
    +
  • +
  • windSpeedCorr
    + Korrekturwert Ihrer angezeigten Windgeschwindigkeit als Fließkommezahk. Die gemessene Geschwindigkeit wird mit dem angegeben Wert multiplizuert. Der Wert 0 deaktiviert die Funktion.
    + Beispielwert: 1.25
    + Standardwert: 1
    +

  • + =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