Poolthermometer WT0122 mit TRX auslesen (UNDECODED FineOffset)

Begonnen von aloz77, 20 August 2014, 22:02:42

Vorheriges Thema - Nächstes Thema

aloz77

Mein günstiger Poolthermometer trägt auf der Basisstation hinten die Aufschrift Model: WT0122 und sieht so aus:

(http://img2.everychina.com/img/92/4f/aff89c9dc0259323d83070516b13-249x163c1-6f86/wt0122_wireless_swimming_pool_thermometer.jpg)

Im RFXmngr kann ich die Sensordaten sehr stabil alle 10 Sekunden mit eingeschaltetem Undec empfangen:

20.08.2014 19:50:48= 0903120628555A43FFA1
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A43FFA1


Die Kodierung scheint der Kodierung von Fineoffset WH2 und früheren Kodierung von Fineoffset WH1081 ähnlich zu sein. 0x28555 könnte eine Device-ID sein. Der letzte Byte 0xA1 könnte die Checksumme sein. Fineoffset nutzt sonst oft CRC8 mit 0x131 als Polynom (C-Quelltext z.B. hier). Hier haut die Checksumme nach CRC8 jedoch nicht hin.

Die Temperatur scheint sich jedenfalls so berechnen zu lassen:

$temp = ((0xA43 & 0x3FF)-0x190)/10 = 17,9 °C

Gibt es irgendwelche Möglichkeit, den Sensor in FHEM/TRX einzubinden? Oder geht das erst, wenn RFXtrx es selbst (ohne Undec) erkennen kann? Es wäre klasse, wenn das irgendwie ginge. Denn es gibt anscheinend noch nicht viele Poolthermometer, die mit FHEM gehen.

Hier noch ein paar Beispiele der Telegramme mit verschiedenen Temperaturen:

------------------------------------------------ 22,3°C
18.08.2014 20:58:47= 0903129728555A6FFF5A
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A6FFF5A
------------------------------------------------ 22,5°C
18.08.2014 21:00:07= 090312A228555A71FF06
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A71FF06
------------------------------------------------ 22,6°C
18.08.2014 21:01:37= 090312B228555A72FF55
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A72FF55
------------------------------------------------ 22,7°C
18.08.2014 21:05:07= 090312D628555A73FF64
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A73FF64
------------------------------------------------ 23,2°C
18.08.2014 21:10:37= 0903121728555A78FF8E
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A78FF8E
------------------------------------------------ 23,1°C
18.08.2014 21:12:57= 0903123028555A77FFA0
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A77FFA0
------------------------------------------------ 22,9°C
18.08.2014 21:15:27= 0903124F28555A75FFC2
Packettype        = UNDECODED RF Message
UNDECODED FineOffset:28555A75FFC2 

Willi

#1
Oregon Scientific hat einen Sensor, der von der RFXCOM-Firmware und meinem Treiber unterstützt wird.

Alle unbekannten Nachrichten landen generell im Modul 46_TRX_ELSE.pm. Schau mal in der Weboverfläche, ob dort TRX_ELSE erscheint. dann müßten auch die entsprechenden Filelogs da sein.

Diese unbekannten Nachrichten werden als TRX.UNKOWN_hexcode (also in Deinem Fall Filelog TRX.UNKOWN.09) weggeschrieben. Diese könntest Du dort per notify abgreifen und per Skript interpretieren.

Ich bin mir allerdings nicht sicher, ob man die Konfiguration in RFXmngr zur Erkennung von UNKOWN-Nachrichten überhaupt permanent abspeichern kann, damit diese nach ausstecken und einstecken des RFXtrx433 überhaupt noch da ist und damit auf in FHEM nutzbar ist).
Das kannst Du probieren, wenn Du den RFXtrx433 aussteckt und in RFXmngr nutzt ohne vorher unknown einzuschalten. Wenn das nicht funktioniert kommen diese Nachrichten auch nicht in meinem FHEM-Treiber an.

Ich habe derzeit nicht vor UNKNOWN-Nachrichten in meinen Treibern zusätzlich zu implementieren. Du kannst dies aber gerne tun. Wenn es funktioniert, kann ich es dann gerne auch ins Versionemanagement von FHEM schreiben.

FHEM@Q600(debian) mit DS9490R (1Wire) | FHEM@Sheevaplug(debian) mit RFXCOM-Receiver(80002), CULv3 & USB-WDE1 | FHEM@odroid mit CULv2 & RFXtrx433

aloz77

Danke, ich habe so gut wie keine Perl-Kenntnisse, aber ich kann etwas C/PHP. Ich habe mich durch die betroffenen Module durchgearbeteit und folgende minimalinvasive Lösung gemacht, die auch gut zu funktionieren scheint. Ich skizziere hier die Lösung erstmal, später kann ich diff-Dateien machen. Für Hinweise zur Verbesserung wäre ich dankbar!

1. Aufgabe: Undec-Modus über TRX dauerhaft einschalten. Ich habe dafür ein neues Attribut set_mode eingeführt. Beim Setzen oder wenn schon gesetzt wird TRX neu initialisiert und zusätzlich der Wert von set_mode als Kommando gesendet.

# 45_TRX.pm

sub TRX_Attr(@);

# TRX_Initialize($)
$hash->{AttrFn} = "TRX_Attr";
$hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 do_not_init:1,0 addvaltrigger:1,0 longids rssi:1,0 set_mode";

#####################################
sub
TRX_Attr(@)
{
  my ($cmd,$name,$aName,$aVal) = @_;
  if($aName eq "set_mode") {
    my $hash = $defs{$name};
  Log3 $name, 3, "TRX: Set mode attr $aVal.";
  $attr{$name}{"set_mode"}=$aVal;
  TRX_DoInit($hash);
  }
 
  return undef;
}

# TRX_DoInit($)

  # Set Mode
  if(defined($attr{$name}) && defined($attr{$name}{"set_mode"})) {
  $init = pack('H*', $attr{$name}{"set_mode"});
  DevIo_SimpleWrite($hash, $init, 0);
  $buf = DevIo_TimeoutRead($hash, 0.1);

  if (! $buf) {
      Log3 $name, 1, "TRX: Set Mode Error: No character read";
  return "TRX: Set Mode Error $name: no char read";
  }
  else {
      my $hexline = unpack('H*', $buf);
      Log3 $name,1, "TRX: Set Mode OK Status: $hexline";
    }
  }


Die fhem.cfg sieht bei mir dafür wie folgt aus:

define RFXTRXUSB TRX /dev/RFXtrx433@38400
attr RFXTRXUSB longids TS15C,PT2262,WT0122
attr RFXTRXUSB set_mode 0D0000020353008C042500000000


Dabei kommt das raus:

2014.08.22 18:34:13 3: Opening RFXTRXUSB device /dev/RFXtrx433
2014.08.22 18:34:13 3: Setting RFXTRXUSB baudrate to 38400
2014.08.22 18:34:13 3: RFXTRXUSB device opened
2014.08.22 18:34:14 1: TRX: Init OK
2014.08.22 18:34:14 1: TRX: Init status: '433.92MHz transceiver, firmware=229, protocols enabled: Lighting4 FineOffset/Viking Hideki OREGON AC X10 '
2014.08.22 18:34:14 3: TRX: Set mode attr 0D0000020353008C042500000000.
2014.08.22 18:34:14 1: TRX: Init OK
2014.08.22 18:34:14 1: TRX: Set Mode OK Status: 0d0100020353e58c042501020000
2014.08.22 18:34:14 1: TRX: Init status: '433.92MHz transceiver, firmware=229, protocols enabled: undecoded Lighting4 FineOffset/Viking Hideki OREGON AC X10 '


2. Aufgabe: Wenn sich mein Poolsensor meldet soll er von TRX_WEATHER behandelt werden und nicht von TRX_ELSE. Dafür habe ich in den Regex eine Ausnahme eingefügt und die Temperatur-Berechnung für WT0122 in TRX_WEATHER eingerichtet.

# 45_TRX.pm

  my %mc = (
    "1:TRX_WEATHER"    => "^..(0312..2855|50|51|52|54|55|56|57|58|5a|5b|5d).*",
    "2:TRX_SECURITY" => "^..(20).*",
    "3:TRX_LIGHT" => "^..(10|11|12|13|14).*",
    "4:TRX_ELSE"    => "(?!^..0312..2855)^..(0[0-f]|0[4-f]|1[5-f]|2[1-f]|3[0-f]|4[0-f]|53|59|5c|5e|5f|[6-f][0-f]).*",
  );

# 46_TRX_ELSE.pm

# TRX_ELSE_Initialize($)
$hash->{Match}     = "(?!^..0312..2855)^..(0[0-f]|1[5-f]|2[1-f]|3[0-f]|4[0-f]|53|59|5c|5e|5f|[6-f][0-f]).*";

# 46_TRX_WEATHER.pm

# TRX_WEATHER_Initialize($)
  $hash->{Match}     = "^..(0312..2855|50|51|52|54|55|56|57|58|5a|5d).*";

# sensor types
   0x0309 => { part => 'TEMP', method => \&TRX_WEATHER_common_temp, },

sub TRX_WEATHER_temperature_WT0122 {
  my ($bytes, $dev, $res, $off) = @_;

  my $temp =
    (
       (($bytes->[$off] & 0x03)*256 + $bytes->[$off+1] - 400)
    )/10;

  push @$res, {
        device => $dev,
        type => 'temp',
        current => $temp,
units => 'Grad Celsius'
  }

}

# TRX_WEATHER_common_temp

0x12 => "WT0122", # WT0122

  if ($dev_type eq "WT0122") {
  TRX_WEATHER_temperature_WT0122($bytes, $dev_str, \@res, 5);
  }
  else
  {
    TRX_WEATHER_temperature($bytes, $dev_str, \@res, 5);
    TRX_WEATHER_simple_battery($bytes, $dev_str, \@res, 7);
  }


Nicht alles elegant, aber scheint zu laufen.

aloz77

Eine Sache klappt bei mir noch nicht. Wenn RFXTRX abgezogen wird, soll beim Reconnect die TRX_DoInit() laufen, damit Undec wieder eingeschaltet wird. Da blicke ich nicht ganz durch, wie ich das korrekt einrichten kann. Erreiche ich das ohne Seiteneffekte, wenn ich in TRX_Ready() den Aufruf von DevIo_OpenDev() so abändere?

  return DevIo_OpenDev($hash, 1, "TRX_DoInit")
                if($hash->{STATE} eq "disconnected");


aloz77

Hier sind die Diff-Dateien zur aktuellen Version aus svn, falls jemand dieses oder anderes Undec-Gerät betreiben will.

45_TRX.pm
--- 45_TRX.pm.orig2
+++ 45_TRX.pm
@@ -35,6 +35,7 @@
my $last_time = 1;
my $trx_rssi = 0;

+sub TRX_Attr(@);
sub TRX_Clear($);
sub TRX_Read($);
sub TRX_Ready($);
@@ -54,10 +55,10 @@
   $hash->{Clients} =
         ":TRX_WEATHER:TRX_SECURITY:TRX_LIGHT:TRX_ELSE:";
   my %mc = (
-    "1:TRX_WEATHER"    => "^..(50|51|52|54|55|56|57|58|5a|5b|5c|5d).*",
+    "1:TRX_WEATHER"    => "^..(0312..2855|50|51|52|54|55|56|57|58|5a|5b|5d).*",
     "2:TRX_SECURITY" => "^..(20).*",
     "3:TRX_LIGHT" => "^..(10|11|12|13|14|15|16|17|18|19).*",
-    "4:TRX_ELSE"    => "^..(0[0-f]|1[a-f]|2[1-f]|3[0-f]|4[0-f]|53|59|5e|5f|[6-f][0-f]).*",
+    "4:TRX_ELSE"    => "(?!^..0312..2855)^..(0[0-f]|0[4-f]|1[5-f]|2[1-f]|3[0-f]|4[0-f]|53|59|5c|5e|5f|[6-f][0-f]).*",
   );
   $hash->{MatchList} = \%mc;

@@ -68,7 +69,8 @@
   $hash->{UndefFn} = "TRX_Undef";
   $hash->{GetFn}   = "TRX_Get";
   $hash->{StateFn} = "TRX_SetState";
-  $hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 do_not_init:1,0 addvaltrigger:1,0 longids rssi:1,0";
+  $hash->{AttrFn} = "TRX_Attr";
+  $hash->{AttrList}= "do_not_notify:1,0 dummy:1,0 do_not_init:1,0 addvaltrigger:1,0 longids rssi:1,0 set_mode";
   $hash->{ShutdownFn} = "TRX_Shutdown";
}

@@ -201,6 +203,21 @@
   }
}

+sub
+TRX_Attr(@)
+{
+  my ($cmd,$name,$aName,$aVal) = @_;
+  if($aName eq "set_mode") {
+    my $hash = $defs{$name};
+   Log3 $name, 3, "TRX: Set mode attr $aVal.";
+   $attr{$name}{"set_mode"}=$aVal;
+   TRX_DoInit($hash);
+  }

+  return undef;
+}
+
+
#####################################
sub
TRX_DoInit($)
@@ -246,6 +263,22 @@
   } else {
      Log3 $name,1, "TRX: Init OK";
    $hash->{STATE} = "Initialized";
+
# Set Mode
+   if(defined($attr{$name}) && defined($attr{$name}{"set_mode"})) {
+   $init = pack('H*', $attr{$name}{"set_mode"});
+   DevIo_SimpleWrite($hash, $init, 0);
+      $buf = unpack('H*',DevIo_TimeoutRead($hash, 0.1));
+
+   if (! $buf) {
+      Log3 $name, 1, "TRX: Set Mode Error: No character read";
+   return "TRX: Set Mode Error $name: no char read";
+   }
+   else {
+      Log3 $name,5, "TRX: Set Mode OK. Result: $buf";
+    }
+   }
+
# Analyse result and display it:
if ($buf =~ m/0d0100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/) {
my $status = "";
@@ -391,7 +424,7 @@
{
   my ($hash) = @_;

-  return DevIo_OpenDev($hash, 1, "TRX_Ready")
+  return DevIo_OpenDev($hash, 1, "TRX_DoInit")
                 if($hash->{STATE} eq "disconnected");

   # This is relevant for windows/USB only


46_TRX_WEATHER.pm
--- 46_TRX_WEATHER.pm.orig2
+++ 46_TRX_WEATHER.pm
@@ -17,6 +17,7 @@
# * "WS2300"    is La Crosse WS2300
# * "RUBICSON"  is RUBiCSON
# * "TFA_303133" is TFA 30.3133
+# * "WT0122" is WT0122
#
# humidity sensors (HYDRO):
# * "TX3" is LaCrosse TX3
@@ -116,7 +117,7 @@
{
   my ($hash) = @_;

-  $hash->{Match}     = "^..(50|51|52|54|55|56|57|58|5a|5c|5d).*";
+  $hash->{Match}     = "^..(0312..2855|50|51|52|54|55|56|57|58|5a|5d).*"; 
   $hash->{DefFn}     = "TRX_WEATHER_Define";
   $hash->{UndefFn}   = "TRX_WEATHER_Undef";
   $hash->{ParseFn}   = "TRX_WEATHER_Parse";
@@ -173,6 +174,7 @@
   (
    # TEMP
    0x5008 => { part => 'TEMP', method => \&TRX_WEATHER_common_temp, },
+   0x0309 => { part => 'TEMP', method => \&TRX_WEATHER_common_temp, },
    # HYDRO
    0x5108 => { part => 'HYDRO', method => \&TRX_WEATHER_common_hydro, },
    # TEMP HYDRO
@@ -227,6 +229,23 @@

}

+sub TRX_WEATHER_temperature_WT0122 {
+  my ($bytes, $dev, $res, $off) = @_;
+
+  my $temp =
+    (
+       (($bytes->[$off] & 0x03)*256 + $bytes->[$off+1] - 400)
+    )/10;
+
+  push @$res, {
+        device => $dev,
+        type => 'temp',
+        current => $temp,
+ units => 'Grad Celsius'
}
+}
+
+
sub TRX_WEATHER_chill_temperature {
   my ($bytes, $dev, $res, $off) = @_;

@@ -459,7 +478,7 @@
0x0f => "RES_TEMP5", # Reserved for future use
0x10 => "RES_TEMP6", # Reserved for future use
0x11 => "RES_TEMP7", # Reserved for future use
- 0x12 => "RES_TEMP8", # Reserved for future use
+ 0x12 => "WT0122", # WT0122
   );

   if (exists $devname{$bytes->[1]}) {
@@ -488,8 +507,15 @@
     push @res, { device => $dev_str, type => 'hexline', current => $hexline, units => 'hex', };
   }

+  if ($dev_type eq "WT0122") {
+   TRX_WEATHER_temperature_WT0122($bytes, $dev_str, \@res, 5);
+  }
+  else
+  {
   TRX_WEATHER_temperature($bytes, $dev_str, \@res, 5);
   TRX_WEATHER_simple_battery($bytes, $dev_str, \@res, 7);
+  }
+
   return @res;
}



46_TRX_ELSE.pm
--- 46_TRX_ELSE.pm.orig2
+++ 46_TRX_ELSE.pm
@@ -41,7 +41,7 @@
{
   my ($hash) = @_;

-  $hash->{Match}     = "^..(0[0-f]|1[a-f]|2[1-f]|3[0-f]|4[0-f]|53|59|5e|5f|[6-f][0-f]).*";
+  $hash->{Match}     = "(?!^..0312..2855)^..(0[0-f]|1[5-f]|2[1-f]|3[0-f]|4[0-f]|53|59|5c|5e|5f|[6-f][0-f]).*"; 
   $hash->{DefFn}     = "TRX_ELSE_Define";
   $hash->{UndefFn}   = "TRX_ELSE_Undef";
   $hash->{ParseFn}   = "TRX_ELSE_Parse";


Wenn man undec-Modus einschalten will, muss man mit Rfxmgr schauen, welchen Config-Wert man hinschicken soll und diesen als Attribut set_mode setzen. Ich mache das so:

define RFXTRXUSB TRX /dev/RFXtrx433@38400
attr RFXTRXUSB longids TS15C,PT2262,WT0122
attr RFXTRXUSB set_mode 0D0000020353008C040000000000


Das kommt dabei im Log:

2014.08.31 16:40:23 1: TRX: Init status: '433.92MHz transceiver, firmware=229, protocols enabled: undecoded Lighting4 FineOffset/Viking Hideki '

aloz77

Dank den Entwicklern von Rfxtrx wird dieser Pooltermometer in der letzten Firmware-Version (ich habe mit Rfxtrx433E ver. 230 getestet) unterstützt. Der FHEM-Code braucht dann nur eine kleine Änderung. Vielleicht kann das Willi irgendwann einfügen.

--- 46_TRX_WEATHER.pm.orig2
+++ 46_TRX_WEATHER.pm
@@ -452,7 +452,7 @@
        0x08 => "WS2300", # La Crosse WS2300
        0x09 => "RUBICSON", # RUBiCSON
        0x0a => "TFA_303133", # TFA 30.3133
-       0x0b => "RES_TEMP1", # Reserved for future use
+       0x0b => "WT0122", # WT0122
        0x0c => "RES_TEMP2", # Reserved for future use
        0x0d => "RES_TEMP3", # Reserved for future use
        0x0e => "RES_TEMP4", # Reserved for future use

Willi

Zitat von: aloz77 am 20 September 2014, 14:44:27
Der FHEM-Code braucht dann nur eine kleine Änderung. Vielleicht kann das Willi irgendwann einfügen.
OK. Was lange währt. Ist in den nächsten tagen im SVN.
FHEM@Q600(debian) mit DS9490R (1Wire) | FHEM@Sheevaplug(debian) mit RFXCOM-Receiver(80002), CULv3 & USB-WDE1 | FHEM@odroid mit CULv2 & RFXtrx433


aloz77

Sei gewarnt: Ich hatte einige WT0122-Schwimmsensoren auf dem Tisch, wo das Gehäuse und sogar die Platine identisch aussahen. Dennoch wollten sie nicht mehr von RFXTRX verstanden werden. (Die eigene Basisstation hat den Wert aber angezeigt.)  :(

Ansonsten: Ein gutes Gerät für den Preis. Bei mir seit zwei Jahren im Pool und immer noch dicht.

Willi

Zitat von: aloz77 am 09 Februar 2016, 09:41:46
Sei gewarnt: Ich hatte einige WT0122-Schwimmsensoren auf dem Tisch, wo das Gehäuse und sogar die Platine identisch aussahen. Dennoch wollten sie nicht mehr von RFXTRX verstanden werden. (Die eigene Basisstation hat den Wert aber angezeigt.)  :(
Falls Du die noch hast: Normalerweise ist RFXCOM bereit, bei Problemen sich die Funktsender anzusehen und das Empfangsprotokoll anzupassen. Schreib einfach eine E-Mail an RFXCOM.
FHEM@Q600(debian) mit DS9490R (1Wire) | FHEM@Sheevaplug(debian) mit RFXCOM-Receiver(80002), CULv3 & USB-WDE1 | FHEM@odroid mit CULv2 & RFXtrx433

Mikerick

Hi,
denke das Teil ist eins von Deinem Tisch :-) Tuts nicht und eine Basisstation habe ich erst garnicht dazu gekauft :-)
Sooo....dann mal den von Willi beschriebenen Weg anstreben. Machen die das wirklich? Einfach mit dem Support Kontakt aufnehmen?
Beste Grüße
Michael