RFD-FHEM / RFFHEM

Counterpart of SIGNALDuino, it's the code for FHEM to work with the data received from the uC
GNU General Public License v3.0
44 stars 33 forks source link

Protokoll für FS10 Fernbedienung, Schaltsteckdosen #138

Closed elektron-bbs closed 5 years ago

elektron-bbs commented 7 years ago

Hallo, ich verwende aktuell einen Arduino Nano mit CC1101. Die Firmware-Version auf dem AVR ist: V 3.3.1-dev SIGNALduino cc1101 - compiled at Jan 12 2017 23:04:38

Da ich bereits in dem nebenan laufenden Projekt mit dem WS7000 beteiligt bin, habe ich in der 00_SIGNALduino.pm schon mal ein Gerät angelegt, da die Puls- und Pausenzeiten ähnlich sind:

"61" => ##  FS10 #############################################################################
# MU;P0=32001;P1=-419;P2=367;P3=-810;D=0121212121212121212121212321212321232121212323212121232323212121232121212323232321232;CP=2;R=53;
# MU;P0=15244;P1=-419;P2=368;P3=-819;D=0121212121212121212121212321212321232321232323212121232323212121232121212323232123232;CP=2;R=65;
# das erste und letzte Bit ist nicht komplett
{
  name                      => 'FS10', 
      id                            => '61',
      one                   => [2,-3],            
      zero                  => [2,-1],          
      clockabs              => 200,                
      preamble                  => 'F',                # prepend to converted message
      postamble                 => '',                  # Append to converted message       
      clientmodule              => 'FS10',      
      length_min                => '44',            # 45, das letzte Bit 1 fehlt immer
      length_max            => '80',            # 81, das letzte Bit 1 fehlt immer
  postDemodulation      => \&SIGNALduino_postDemo_FS10,
}, 

Leider werden aber die empfangenen Daten nicht zuverlässig erkannt. Hier ein Auszug dazu aus dem Log:

2017.02.25 16:57:51 4: sduino/msg READ: MU;P0=32001;P1=-419;P2=382;P3=-809;D=0121212121212121212121212323212121232121212323212121232323212121232121212323212323232;CP=2;R=71; 2017.02.25 16:57:52 4: sduino/msg READ: MU;P0=32001;P1=-412;P2=371;P3=-819;D=0121212121212121212121212321212321232121212323212121232323212121232121212323232321232;CP=2;R=71; 2017.02.25 16:57:53 4: sduino/msg READ: MU;P0=18868;P1=-416;P2=369;P3=-812;D=0121212121212121212121212323212121232121232123212121232323212121232121212323232323212;CP=2;R=73; 2017.02.25 16:57:53 4: sduino/msg READ: MU;P0=5872;P1=-413;P2=368;P3=-815;D=0121212121212121212121212321212321232121232123212121232323212121232121212323212321212;CP=2;R=73; 2017.02.25 16:57:54 4: sduino/msg READ: MU;P0=32001;P1=-407;P2=373;P3=-816;D=0121212121212121212121212323212121232321232323212121232323212121232121212323232321232;CP=2;R=73; 2017.02.25 16:57:54 4: sduino: Fingerprint for MU Protocol id 61 -> FS10 matches, trying to demodulate 2017.02.25 16:57:54 4: sduino/msg READ: MU;P0=32001;P1=-415;P2=379;P3=-804;D=0121212121212121212121212321212321232321232323212121232323212121232121212323232123232;CP=2;R=73;

MfG

Ralf9 commented 7 years ago

versuch mal

      one                       => [1,-2],            
      zero                  => [1,-1],          
      clockabs              => 390,  
elektron-bbs commented 7 years ago

Danke, Das funktioniert wunderprächtig :-) Ich habe jetzt in die Protokollliste mit aufgenommen:

    "61" => ## ELV
    {
        # tested remote control:    FS10-S8
        # not tested:
        # das letzte Bit 1 und 1 x 0 Preambel fehlt immer
        #  ____          ____
        # |    |____        |    |________
        #      0               1
        # 400µS 400µS   400µS   800µS - Sollzeiten 
        name                    => 'FS10',
        id                          => '61',
        one                     => [1,-2],            
        zero                    => [1,-1],
        #zero                   => [1,-3],
        clockabs                => 390,  
        preamble                => 'FS10',        # prepend to converted message
        postamble               => '',         # Append to converted message
        clientmodule            => 'FS10',
        length_min              => '40',            # eigentlich 46
        length_max              => '48',            # eigentlich 46
        postDemodulation        => \&SIGNALduino_postDemo_FS10,
    }, 

Gibt es eine Möglichkeit, die "id" aus der Protokollliste im Clientmodul abzufragen? Ich möchte eigentlich vermeiden, die ID beim Senden mittels Aufruf von:

IOWrite($hash, 'sendMsg', $newmsg);

fest einzutragen, da diese sich im Verlauf der Programmentwicklung ja mal ändern könnte. Ich generiere "$newmsg" im Moment so:

my $newmsg = "P61#0000000000001"; # 12 Bit Praeambel, 1 Pruefbit

Das gefällt mir aber eigentlich nicht.

sidey79 commented 7 years ago

Hmm, Aktuell gibt es da keine Möglichkeit.... Die IDs ändern sich bislang auch eher nicht... ausschließen kann ich es natürlich nicht, dass es mal passieren kann.

Was passiert inSIGNALduino_postDemo_FS10 ?

Ralf9 commented 7 years ago

Ich habe auch eine FS10 S8 Dies erhalte ich wenn ich eine Taste drücke. Habt ihr eine Protokollbeschreibung gefunden?

Taste1 off P61#00094638C78 P61#000C4638C60 Taste1 on P61#000DC638C74 P61#0008C638C5C

Taste2 off P61#000C4A38C5C P61#00094A38C74 Taste2 on P61#0008CA38C78 P61#000DCA38C50

Taste3 off P61#00096E38C50 P61#000C6E38C78 Taste3 on P61#0008EE38C74 P61#000DEE38C6C

Taste4 off P61#00095238C6C P61#000C5238C74 Taste4 on P61#000DD238C48 P61#0008D238C50

elektron-bbs commented 7 years ago

Das Protokoll habe ich mir selbst erarbeitet. Der Ausbau ist ähnlich denen der WS2000-Serie. Die Protokolldefinition sieht jetzt bei mir so aus:

    "61" => ## ELV
    {
        # tested transmitter:   FS10-S8, FS10-S4, FS10-ZE
        # tested receiver:      FS10-ST, WS3000-TV, PC-Wettersensor-Empfänger
        # das letzte Bit 1 und 1 x 0 Preambel fehlt immer
        #  ____          ____
        # |    |____        |    |________
        #      0               1
        # 400µS 400µS   400µS   800µS - Sollzeiten 
        name                    => 'FS10',
        id                          => '61',
        one                     => [1,-2],            
        zero                    => [1,-1],
        clockabs                => 390,  
        preamble                => 'FS10',     # prepend to converted message
        postamble               => '',         # Append to converted message
        clientmodule            => 'FS10',
        length_min              => '40',            # eigentlich 46
        length_max              => '48',            # eigentlich 46
        postDemodulation        => \&SIGNALduino_postDemo_FS10,
    }, 

Die Vorverarbeitung sieht im Moment noch so aus (wird noch verbessert)

sub SIGNALduino_postDemo_FS10($@) { my ($name, @bitmsg) = @; my $debug = AttrVal($name,"debug",0); my @new_bit_msg = ""; my $protolength = scalar @bit_msg; my $subname = "FS10"; my $datastart = 0; my $data = 0; my $dataindex = 0; my $index = 0; my $parity = 0; my $error = 0; my $sum = 0; my $nul = 0;

Debug "$name: $subname ########## Beginn SIGNALduino_postDemo_FS10 ##########" if ($debug); while ($bit_msg[$datastart] == 0) { $datastart++; } # Start bei erstem Bit mit Wert 1 suchen my $datalength = $protolength - $datastart; my $datalength1 = $datalength - ($datalength % 5); # modulo 5 Debug "$name: $subname protolength: $protolength, datastart: $datastart, datalength $datalength" if ($debug); Log3 $name, 3, "$name: $subname @bit_msg"; Log3 $name, 3, "$name: $subname protolength: $protolength, datastart: $datastart, datalength $datalength, datalength1 $datalength1";

if ($datalength1 < 30 || $datalength1 > 35) {                                               # check lenght of message
    Log3 $name, 3, "$name: $subname - ERROR lenght of message $datalength1";
    $error ++;
    return (0);
}

if ($datastart <= 12) {     # max 12 Bit preamble
    do {
        $error += !$bit_msg[$index + $datastart];           # jedes 5. Bit muss 1 sein
        $dataindex = $index + $datastart + 1;                
        $data = oct( "0b".(join "", @bit_msg[$dataindex .. $dataindex + 3]));
        if ($index == 15) {
            $nul = $data & 0x07;                                    # Nibble muss 0 sein
        }
        if ($index < 30) {
            my $temp = $data;       
            my $temp1 = 1;                                      # Paritaet ungerade
            while ($temp != 0) {
                if ($temp & 1) { $temp1 = 1 - $temp1; } # Paritaet ungerade
                $temp >>= 1;                                        # shift right
            }
            if ($temp1 != 0) { $parity += 1 }
            $sum = $sum + ($data & 0x07);
        }
        my $temp2 = $data & 0x07;
        $index += 5;
    } until ($index >= $datalength);
    if ($error != 0) {
        Log3 $name, 3, "$name: $subname - ERROR examination bit";
        return (0);
    }
    if ($parity != 0) {
        Log3 $name, 3, "$name: $subname - ERROR parity bit";
        $error ++;
        return (0);
    }
    if ($nul != 0) {
        Log3 $name, 3, "$name: $subname - ERROR Zero";
        return (0);
    }
    if ($sum != 10 && $sum != 18) {
        Log3 $name, 3, "$name: $subname - ERROR sum";
        $error ++;
        return (0);
    }

    if ($error == 0) {
        #Log3 $name, 4, "$name: $subname Sensortyp $typ Adr $adr - $sensors[$typ]";
        #$datastart += 1;

my $command = (oct( "0b".(join "", @bit_msg[$datastart + 1.. $datastart + 4]))) & 0x07;
my $ebenel = (oct( "0b".(join "", @bit_msg[$datastart + 6.. $datastart + 9]))) & 0x07;
my $ebeneh = (oct( "0b".(join "", @bit_msg[$datastart + 11.. $datastart + 14]))) & 0x07;
my $u = (oct( "0b".(join "", @bit_msg[$datastart + 16.. $datastart + 19]))) & 0x07;
my $hc = (oct( "0b".(join "", @bit_msg[$datastart + 21.. $datastart + 24]))) & 0x07;
my $summe = (oct( "0b".(join "", @bit_msg[$datastart + 26.. $datastart + 29]))) & 0x07;
# my $command = oct( "0b".(join "", @bit_msg[$datastart + 1.. $datastart + 4])) & 0x07;
# my $ebenel = oct( "0b".(join "", @bit_msg[$datastart + 6.. $datastart + 9])) & 0x07;
# my $ebeneh = oct( "0b".(join "", @bit_msg[$datastart + 11.. $datastart + 14])) & 0x07;
# my $u = oct( "0b".(join "", @bit_msg[$datastart + 16.. $datastart + 19])) & 0x07;
# my $hc = oct( "0b".(join "", @bit_msg[$datastart + 21.. $datastart + 24])) & 0x07;
# my $summe = oct( "0b".(join "", @bit_msg[$datastart + 26.. $datastart + 29])) & 0x07;
Log3 $name, 3, "$name: $subname unbenutzt  $u";
Log3 $name, 3, "$name: $subname Hauscode   $hc";
Log3 $name, 3, "$name: $subname Ebene high $ebeneh";
Log3 $name, 3, "$name: $subname Ebene low  $ebenel";
Log3 $name, 3, "$name: $subname Command    $command";
Log3 $name, 3, "$name: $subname Summe      $summe";
@new_bit_msg[0 .. 3] = @bit_msg[$datastart + 1.. $datastart + 4];
$new_bit_msg[0] = "0";
@new_bit_msg[4 .. 7] = @bit_msg[$datastart + 6.. $datastart + 9];   
$new_bit_msg[4] = "0";
@new_bit_msg[8 .. 11] = @bit_msg[$datastart + 11.. $datastart + 14];
$new_bit_msg[8] = "0";
@new_bit_msg[12 .. 15] = @bit_msg[$datastart + 16.. $datastart + 19];
$new_bit_msg[12] = "0";
@new_bit_msg[16 .. 19] = @bit_msg[$datastart + 21.. $datastart + 24];
$new_bit_msg[16] = "0";
@new_bit_msg[20 .. 23] = @bit_msg[$datastart + 26.. $datastart + 29];
$new_bit_msg[20] = "0";
Debug "$name: $subname ########### Ende SIGNALduino_postDemo_FS10 ###########" if ($debug);
return (1, @new_bit_msg);
    } else {
        return (0);
    }
} else {
    Log3 $name, 3, "$name: $subname ERROR preamble";
    return (0);
}

}

Das Modul 10_FS10.pm wurde 2013 von "KlausR" im Forum https://forum.fhem.de/index.php?topic=10248.0 veröffentlicht und von mir jetzt für das Senden mittels SIGNALduino angepasst. 10_FS10.zip Ist alles noch Beta-Stadium, funktioniert aber hier schon sehr gut.

sidey79 commented 7 years ago

ccf1b2b6316bb6629fe9f5adb3aa2699515323dd

Ralf9 commented 7 years ago

Mir ist nicht klar zu was die sub SIGNALduino_postDemo_FS10() überhaupt benötigt wird, diese Vorverarbeitung müsste man doch auch in der Parse Routine vom FS10 Modul machen können. Oder übersehe ich da was?

Ralf9 commented 7 years ago

Ich habe beim 10_FS10 Modul an der Parse Routine etwas gebastelt. Die SIGNALduino_postDemo_FS10 ist damit nicht notwendig. https://github.com/Ralf9/FS10/blob/dev-r33/FHEM/10_FS10.pm

elektron-bbs commented 7 years ago

Tja, das funktioniert bei mir nicht auf Anhieb. Ich habe in der ProtocolListSIGNALduino den Eintrag postDemodulation auskommentiert. Dann mäkelt FHEM erst mal: Messages collected while initializing FHEM: configfile: Define FS10_0111: wrong housecode format: specify a 1 digit value [0-7] usw. Habe ich dann wieder auf 2-stellig geändert, aber dann erfolgt auch keine Reaktion auf meine Fernbedienung.

Meine Vorverarbeitung habe ich mittlerweile noch etwas abgeändert. Lade ich mit hoch.

Ich würde die Preambel nicht auf einen festen Wert setzen. Der Signalduino scheint im Moment immer das erste und letzte Bit zu verschlucken und außerdem muss die Preambel ja nicht unbedingt vollständig sein. Diese ist ja eigentlich nur dafür da, um dem Empfänger Zeit zu geben, um sich einzuregeln. Da kann schon mal das eine oder andere Bit verloren gehen.

postdem.zip

Ralf9 commented 7 years ago

Die Preambel nach der gesucht wird lässt sich bei Bedarf noch verkleinern $datastart = index($bitData, "00000000001");

Ich habe inzwischen die 10_FS10.pm komplett überarbeitet. Es fehlt u.a. noch das follow-on-timer beim set und die Device specific help https://github.com/Ralf9/FS10/blob/dev-r33/FHEM/10_FS10.pm

Zum Testen müssen die vorhandenen FS10 device defines gelöscht werden, da das Format sich geändert hat: z.B. bei housecode 1 und Kanal 2:

Name:  FS10_1_21
DEF: 1_21
sidey79 commented 7 years ago

Das ^FS10 als Identifizierung, sollten wir vermeiden.

$hash->{Match} = "^FS10[a-fA-F0-9]{8}";

Andere Module erhalten vielleicht auf ^F prüfen und da fällt dann FS10 auch rein. Besser finde ich es, wenn man die Protokoll ID, so wie üblich übergibt. Das lässt dann auch die Möglichkeit offen im Modul noch Protokolle unterscheiden zu können, sollte es einmal notwendig werden.

Ralf9 commented 7 years ago

Das FS10 ist nur im Modulname: $hash->{Match} = ""21:FS10" => '^P61#[A-F0-9]+',"

Ralf9 commented 7 years ago

@elektron-bbs Mein komplett überarbeitetes FS10 Modul https://github.com/Ralf9/FS10/blob/dev-r33/FHEM/10_FS10.pm ist nur ein Vorschlag/Anregung. Falls es für Dich so nicht passt, kannst Du gerne an deiner Version weiterentwickeln.

elektron-bbs commented 7 years ago

Vielleicht machen wir zusammen ja das Beste daraus. Ich wusste nicht, das du parallel daran weiter arbeitest. Hast du eigentlich noch mehr Geräte aus der FS10-Serie, außer der FS10-S8?

Ralf9 commented 7 years ago

Ich habe außer der FS10-S8 noch zwei FS10ST. Ich habe mal gegoogled was es an FS10 gibt und habe die folgenden 4 Empfänger gefunden. Sind dies alle oder gibt es noch mehr?

my %models = (
    FS10_ST      => 'simple',
    FS10_DI      => 'dimmer',
    FS10_HD      => 'dimmer',
    FS10_SA      => 'timer',
);

Ich werde mein überarbeitetes FS10 Modul dann mal ins dev-r33 commiten und dann einige Deiner Ergänzungen einarbeiten.

Ich habe das hier durch readingsBulkUpdate ersetzt. Mir ist nicht klar zu was das foreach my $n (keys %{ $def }) { gut sein soll

my $def = $modules{FS10}{defptr}{"$dev $btn"}; if ($def) { my @list; foreach my $n (keys %{ $def }) { my $lh = $def->{$n}; $n = $lh->{NAME}; # It may be renamed return "" if(IsIgnored($n)); # Little strange. $lh->{CHANGED}[0] = $v; $lh->{STATE} = $v; $lh->{READINGS}{state}{TIME} = TimeNow(); $lh->{READINGS}{state}{VAL} = $v; Log3 $name, 4, "FS10: received command $n $v"; # FS10_0111 on

elektron-bbs commented 7 years ago

FS10SA ist aber wohl Aufputz-Funkschalter, müsste man behandeln wie FS10ST. Ich habe noch Markisensteuerungen FS10MS in Betrieb. Für FHEM dürften eigentlich nur zwei Modi interessant sein: Simpler Schalter oder Dimmer. Das Funkprotokoll kennt nur drei Zustände:

  1. Taste drücken
  2. Wiederholungen bei längerem Halten einer Taste
  3. Taste loslassen

In der Schleife werden wohl die INTERNALS und READINGS aktualisiert. Ich wollte darin eigentlich jetzt noch die Protokoll-ID vom sduino speichern, habe aber bemerkt, das man die ja auch aus der sduino_DMSG auslesen könnte.

XMIT habe ich übrigens in HC umbenannt, passt wohl besser zu Hauscode :-)

Ralf9 commented 7 years ago

@sidey79 ich habe gestern das FS10 Modul commited, aber irgendwas passt noch nicht Binary file not shown. https://github.com/RFD-FHEM/RFFHEM/commit/e712df75111a8bde329869a4e085ba237055e194

Ralf9 commented 7 years ago

Das FS10 Modul ist nun im dev-r33 commited. Bis auf ein paar Kleinigkeiten müsste es so passen. Ich habe die specific help ergänzt und das set optimiert. Es fehlt noch die englische Device specific help und der syntax check im define.

Ralf9 commented 7 years ago

Ich habe bei define den Syntax Check zugefügt

elektron-bbs commented 7 years ago

Ich habe das jetzt mal ausprobiert. Zuerst kommt mal eine Fehlermeldung: 2017.04.05 20:40:33 1: PERL WARNING: Unrecognized escape \d passed through at ./FHEM/10_FS10.pm line 43. Nach einer Änderung funktioniert das dann soweit.

Wie willst du eigentlich die Funktionen, wie z.B. Dimmer ohne passende Hardware testen?

Ralf9 commented 7 years ago

Damit es funktioniert muss dies in die matchlist in der 00_signalduino.pm eingetragen werden: "21:FS10" => '^P61#[A-F0-9]+',

Ob es auch mit dem Dimmer funktioniert, lässt sich erst testen, wenn jemand mit einem Dimmer das Modul verwendet

Ralf9 commented 7 years ago

$newmsg .= "#R1"; Ich finde beim Senden eine Repetition von 1 zuwenig. Spricht was dagegen diese auf 3 oder evtl auf 6 zu erhöhen?

elektron-bbs commented 7 years ago

Das dürfte dann wohl in etwa der Befehl zum Dimmen sein. Die Fernbedienung sendet genau einmal beim Betätigen der Taste und einmal beim Loslassen mit einem Abstand von 200 mSek, wobei beim Loslassen ein zusätzliches Bit gesetzt wird. Bei längerem Festhalten einer Taste wird auch wieder beim Betätigen einmal gesendet und danach wird im Abstand von wieder je 200 mSek ein Befehl, wobei ein anderes Bit gesetzt ist, wiederholt gesendet. Ich habe allerdings die Erfahrung gemacht, das die Empfänger auch schon auf einen einzigen empfangenen Befehl reagieren. Ein Wiederholen ist eigentlich nicht notwendig. Keine Ahnung, ob das für alle Empfänger gilt.

Kann man zu dem Parameter "#Rx" eigentlich noch einen Abstand der Wiederholungen mitgeben?

Ralf9 commented 7 years ago

Bei mir funktioniert es auch mit einer Repetition von 3. Es kann sein, daß eine Nachricht durch Störungen nicht ankommt. Bei den IT-Steckdosen wird eine Repetition von 6 verwendet. Das Senden erfolgt über eine SendQueue. Die zweite Nachricht wird erst gesendet, wenn vom sduino die Rückmeldung kommt, daß die erste gesendet wurde. Nein, der Abstand der Wiederholungen lässt sich nicht mitgeben

2017.04.06 18:54:44.231 3: FS10_set FS10_1_11: 1. setstate=on kc=1
2017.04.06 18:54:44.231 3: FS10_1_11: Send 1.message P61#0000000000001000110001100011100011000101111#R3
2017.04.06 18:54:44.231 3: FS10_set FS10_1_11: 2. setstate=on kc=3
2017.04.06 18:54:44.231 3: FS10_1_11: Send 2.message P61#0000000000001101110001100011100011000100101#R3
2017.04.06 18:54:44.334 4: sduinoE SendFromQueue: msg=SR;R=3;P0=390;P1=-780;P2=-390;D=02020202020202020202020201020202010102020201010202020101010202020101020202010201010101;
2017.04.06 18:54:44.491 4: sduinoE/read sendraw answer: SR;R=3;P0=390;P1=-780;P2=-390;D=02020202020202020202020201020202010102020201010202020101010202020101020202010201010101;
2017.04.06 18:54:44.501 4: sduinoE SendFromQueue: msg=SR;R=3;P0=390;P1=-780;P2=-390;D=02020202020202020202020201010201010102020201010202020101010202020101020202010202010201;
elektron-bbs commented 7 years ago

Warum willst du dich nicht an das Protokoll halten, so wie es vom Hersteller verwendet wird? Was die IT-Steckdosen brauchen, ist doch eine ganz andere Baustelle. Das mehrfache Senden könnte als Dimm-Befehl verstanden werden, was ich mangels Dimmer allerdings nicht prüfen kann. Außerdem wird der Befehl ja jetzt schon zweimal gesendet. Ich habe hier ca. 20 FS10-Empfänger im Einsatz und da funktioniert das Schalten auch über Entfernungen von bis zu 2 Etagen mit diesem Verfahren wunderprächtig. Wenn du das unbedingt verändern willst, so solltest du es als Option einbauen, die der User auf eigenen Wunsch auswählen kann, aber nicht als Vorgabe.

Ralf9 commented 7 years ago

ok, ich habe es als default auf 1 gelassen und das attribut repetition zugefügt. Ich habe auch die log Ausgaben überarbeitet. Wenn es so für Dich passt, werde ich es auch in der 00_Signalduino.pm committen

elektron-bbs commented 7 years ago

Ich habe jetzt deine 10_FS10.pm komplett übernommen. Diese Fehlermeldung kommt immer noch:

2017.04.08 11:13:28 1: PERL WARNING: Unrecognized escape \d passed through at ./FHEM/10_FS10.pm line 43, <$fh> line 758.

Nach deiner empfohlenen Änderung 00_SIGNALduino.pm Matchlist: "21:FS10" => '^P61#[A-F0-9]+',

"21:FS10" => "^P61#[a-fA-F0-9]{6}",

ändert sich nichts: 2017.04.08 11:21:08 1: PERL WARNING: Unrecognized escape \d passed through at ./FHEM/10_FS10.pm line 43, <$fh> line 758.

Ich habe dann folgende Änderung vorgenommen 10_FS10.pm sub FS10_Initialize: $hash->{Match} = "^P'\d+'#[a-fA-F0-9]{8,12}";

$hash->{Match} = "^P\d+#[a-fA-F0-9]{8,12}";

Danach lief es dann durch. Nach Umstellung sämtlicher Hauscodes bei mir von 0-7 in 1-8 funktioniert es erst mal. Sämtliche Tests habe ich natürlich noch nicht durchgeführt. Die BTN-Codes habe ich allerdings noch umgedreht (High-Byte zuerst):

Senden: my $ebenel = substr($hash->{BTN}, 1, 1); my $ebeneh = substr($hash->{BTN}, 0, 1);

my $ebenel = substr($hash->{BTN}, 0, 1);

my $ebeneh = substr($hash->{BTN}, 1, 1);

Empfang: my $btn = $ebeneh . $ebenel;

my $btn = $ebenel . $ebeneh;

Ich würde dann noch beim Senden das Dimmen einbauen. Wie ich dabei allerdings dein Repeat-Attribut einbauen soll, weiß ich noch nicht. Schöner wäre es, wenn man zu "#Rx" noch den zeitlichen Abstand der Wiederholungen übergeben könnte. Oder wir hoffen einfach darauf, das die Pausen zufällig passen?

Außerdem schwebt mir eigentlich noch vor, das Modul auch für den CUL verwenden zu können, da ich auch noch einen Raspberry damit laufen habe.

Ralf9 commented 7 years ago
Ich habe dann folgende Änderung vorgenommen 10_FS10.pm sub FS10_Initialize:
$hash->{Match} = "^P'\d+'#[a-fA-F0-9]{8,12}";

Ich habe die doppelte hochkomma durch einfache ersetzt. Funktioniert es damit? $hash->{Match} = '^P\d+#[a-fA-F0-9]{8,12}';

Ich habe den tausch von ebeneh und ebenel auch commited.

Ich würde dann noch beim Senden das Dimmen einbauen. Das senden von dimup und dimdown ist bereits eingebaut, aber ohne Wiederholungen. Ob dies so funktioniert oder noch Wiederholungen notwendig sind, lässt sich erst feststellen, wenn dies jemand mit dimmer testet.

Die Pausen dürften momentan ca 150ms sein, wenn es damit auch funktioniert, würde ich gerne so lassen.

Hast Du schon Vorstellungen wie Du das Modul auch für den CUL verwenden kannst. Wenn ich das richtig überblicke, kann die (a-)culfw momentan noch nicht das FS10 Protokol.

Ralf9 commented 7 years ago

war ein Denkfehler, dies kann nur funktionieren, wenn die Protocol ID festgelegt wird $hash->{Match} = '^P61#[a-fA-F0-9]{8,12}';

elektron-bbs commented 7 years ago

Mhmm, scheinbar doch kein Denkfehler. Hier funktioniert das mit: $hash->{Match} = '^P\d+#[a-fA-F0-9]{8,12}'; auf beiden Systemen. Meine Variante funktionierte auf dem Pi nämlich nicht.

elektron-bbs commented 7 years ago

Zu den Dimm-Befehlen: Hab ich eben getestet, dabei fällt mir auf, das da jeweils nur eine Nachricht gesendet wird. Eigentlich müssten ja auch wieder mindestens 2 gesendet werden: dimup:

  1. $kc = 1;
  2. $kc = 5; jetzt könnte man wiederholen mit "$kc = 5". Wie oft, weiß ich allerdings auch nicht. Hängt ja davon ab, in welchen Schritten die Dimmer den Bereich von 0-100% durchlaufen. Ebenso dann bei "dimdown" einmal mit "$kc = 0" und dann weiter mit "$kc = 4".

Beim Empfang der Fernbedienungsbefehle scheint FHEM sowieso nicht hinterher zu kommen. Von (geschätzt) 10 gesendeten Befehlen bei Halten der Taste an der FB erscheinen im Log vielleicht 3 davon.

Ralf9 commented 7 years ago

Danke, nun ist mir das mit den mindestens 2 gesendet werden bei dimup und dimdown klar geworden. Ich habe auch noch ergänzt, daß bei dimup und dimdown Wiederholungen angegeben werden können.

elektron-bbs commented 7 years ago

Das sieht gut aus! Einzig der Befehl "#$kc &= 7;" funktioniert bei mir komischerweise nicht. Ich hab das geändert in "$kc = $kc & 7;".

Brauchen wir die Pause zwischen den einzelnen Nachrichten? Besser wäre es sicher.

    IOWrite($hash, 'sendMsg', $newmsg);
    Log3 $name, 4, "$io->{NAME} FS10_set: $i.sendMsg=$newmsg";
    if ($i < $iNum) {
       Log3 $name, 4, "$io->{NAME} FS10_set: wait 200 mS";
    select(undef, undef, undef, 0.2);   # 200 mSek warten
    }
Ralf9 commented 7 years ago

$kc &= 7; Dies funktioniert bei mir. Siehe auch: https://de.wikibooks.org/wiki/Perl-Programmierung:_Operatoren#Kombinierte_Operatoren Welche Perl Version hast Du?

Das select hat den Nachteil, daß es blockierend ist. Die 200ms non blocking einzubauen, wird etwas aufwendiger. Diesen Aufwand möchte ich vermeiden, wenn es auch ohne die extra Pause funktioniert.

pejonp commented 7 years ago

$kc &= 7;

wenn bei Perl ein # davor steht, ist es auskommentiert

elektron-bbs commented 7 years ago

Ist schon klar, deshalb schrieb ich ja auch "komischerweise". Die Version von Perl auf dem Rechner ist v5.14.2 Die Raute hatte ich versehentlich mit kopiert.

Der PC-Wettersensorempfänger von ELV erkennt ohne die Pause jedenfalls meistens nur eine Nachricht. Ich habe allerdings eben festgestellt, das meine Variante sowieso nicht funktioniert. Der SIGNALduino sendet die Nachrichten egal wie groß ich die Pause definiere gleich nacheinander ohne Pause. Die Wartezeit läuft vor dem Senden der ersten Nachricht ab.

Ralf9 commented 7 years ago

Welche Fehlermeldung bekommst Du bei $kc &= 7;

@sidey79 Hast Du eine Idee wie man das mit der 200 ms Pause hinbekommen kann? Wäre das Senden von 0 eine Möglichkeit? Wird damit 128 ms 0 gesendet? raw SR;R=1;P0=-32000;D=000;

elektron-bbs commented 7 years ago

Ich bekomme gar keine Fehlermeldung, $kc ist danach einfach leer: Ausgabe von $i $iNum $kc, jeweils einmal vor "$kc &= 7; " und danach: 2017.04.10 11:08:43 3: 1 2 1 2017.04.10 11:08:43 3: 1 2 2017.04.10 11:08:43 3: 2 2 3 2017.04.10 11:08:43 3: 2 2

Ralf9 commented 7 years ago

Das ist seltsam, bei mir passt es

     Log3 $name, 4, "vor:  i=$i kc=$kc";
     $kc &= 7;
     Log3 $name, 4, "nach: i=$i kc=$kc";
2017.04.10 20:59:25.615 3: sduinoE FS10_set: FS10_1_12 on
2017.04.10 20:59:25.615 4: sduinoE FS10_set: FS10_1_12: hc=0 ebeneHL=1 2 setstate=on
2017.04.10 20:59:25.615 4: vor:  i=1 kc=1
2017.04.10 20:59:25.615 4: nach: i=1 kc=1
2017.04.10 20:59:25.615 4: sduinoE FS10_set: FS10_1_12 1. setstate=on kc=1
2017.04.10 20:59:25.615 4: sduinoE FS10_set: 1.sendMsg=P61#0000000000001000110010100011100011000111101#R1
2017.04.10 20:59:25.615 4: vor:  i=2 kc=3
2017.04.10 20:59:25.615 4: nach: i=2 kc=3
2017.04.10 20:59:25.615 4: sduinoE FS10_set: FS10_1_12 2. setstate=on kc=3
elektron-bbs commented 7 years ago

Hier aber eben nicht immer:

Linux-Server: Perl : v5.14.2 2017.04.11 11:15:34 3: sduino FS10_set: FS10_6_11 off 2017.04.11 11:15:34 3: vor: i=1 kc=0 2017.04.11 11:15:34 3: nach: i=1 kc= 2017.04.11 11:15:34 3: vor: i=2 kc=2 2017.04.11 11:15:34 3: nach: i=2 kc=

Raspberry Pi: Perl : v5.20.2 2017.04.11 11:29:31 3: CUL_0 FS10_set: FS10_1_11 on 2017.04.11 11:29:31 3: vor: i=1 kc=1 2017.04.11 11:29:31 3: nach: i=1 kc=1 2017.04.11 11:29:31 2: CUL cannot translate sendMsg P61#0000000000001000110001100011100011000101111#R1 2017.04.11 11:29:31 3: vor: i=2 kc=3 2017.04.11 11:29:31 3: nach: i=2 kc=3 2017.04.11 11:29:31 2: CUL cannot translate sendMsg P61#0000000000001101110001100011100011000100101#R1

Ralf9 commented 7 years ago

Ich habe Perl v5.18.1 Außer der Perl Version ist für mich kein Grund ersichtlich warum es nicht immer funktioniert. Ich werde es auf $kc = $kc & 7; ändern

sidey79 commented 7 years ago

Keine Ahnung, welcher Empfänger 128ms auf Empfang bleibt.

Rechnerisch sind 3*32000 = 96000 also 96ms in denen der Signalduino dann nichts sendet, nichts empfängt und auch auf kein serielles Kommando reagiert. Er ist sozusagen in einer Schleife blockiert.

Ralf9 commented 7 years ago

Der PC-Wettersensorempfänger von ELV erkennt ohne die Pause jedenfalls meistens nur eine Nachricht.

Du kannst mal zum Testen z.B. eine 64 ms Pause einfügen

        if ($i < $iNum) {
           IOWrite($hash, 'raw', 'SR;R=1;P0=-32000;D=00;')
        }
elektron-bbs commented 7 years ago

Das scheint nicht zu funktionieren. Ich habe probeweise bis zu 256 mS erhöht, aber es wird immer nur die erste Nachricht dekodiert. Hier ein Auszug aus dem Logfile vom PC-Wettersensorempfänger:

/var/log/pcwsd/remote_23.gnu 10270/10270 100% 2017/04/08 20:20:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/08 20:20:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/08 21:38:39: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/08 21:38:39: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/08 23:27:12: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/08 23:27:12: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/09 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/09 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/09 20:20:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/09 20:20:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/09 22:19:19: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/09 22:19:19: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/09 23:25:57: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/09 23:25:57: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/10 18:10:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/10 18:10:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/10 20:20:11: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/10 20:20:11: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/10 22:17:05: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/10 22:17:05: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/10 23:19:06: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/10 23:19:06: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/11 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/11 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/11 20:20:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/11 20:20:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/11 21:53:18: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/11 21:53:18: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/11 23:01:11: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/11 23:01:11: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/12 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/12 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/12 20:20:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/12 20:20:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/12 22:28:03: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/12 23:05:14: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/12 23:05:14: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0 2017/04/13 18:10:02: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/13 18:10:03: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 1 2017/04/13 20:20:10: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/13 20:20:11: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 1 Befehl: 0

Bis hier stammen diese von einer Original-Ferbedienung, jetzt vom sduino:

2017/04/13 20:47:15: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/13 20:47:19: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0 2017/04/13 20:59:07: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 1 2017/04/13 20:59:09: remote_control: HC: 2 Typ: 0 Gr: 1 Adr: 3 Wh: 0 Befehl: 0

Ralf9 commented 7 years ago

Nun habe ich keine weitere Idee, was wir noch versuchen können. Der PC-Wettersensorempfänger verhält sich anders als die Steckdosen. Die Steckdosen lassen sich auch ohne zusätzliche Pausen schalten.

@sidey79 fällt Dir noch was ein?

elektron-bbs commented 7 years ago

Eine Idee, wie man es lösen könnte, habe ich auch nicht. Die Empfänger, die ich hier habe (Steckdosen und Markisensteuerung), schalten auch schon bei Empfang von nur einer Nachricht. Ob die Pause bei den Dimmern wichtig ist, kann ich nicht prüfen.

sidey79 commented 7 years ago

Ich habe mich jetzt durch eure Beiträge durchgearbeitet. Wenn ich alles richtig verstanden habe, dann wollt ihr dass ein Befehl gesendet wird. Dann wird 200ms lange nichts gesendet und anschließend soll wieder der gleiche Befehl gesendet werden.

Für das Aufwachen des Empfängers erscheint mit außerdem die Preamble verantwortlich. Es ist davon auszugehen, dass mehr gesendet wird, als der Empfänger tatsächlich aufschnappt.

Ralf9 commented 7 years ago

So wie ich das verstehe, wird der 2.Befehl für den Dimmer benötigt um zwischen kurzem (ein/aus) und langem (dimmen) Tastendruck zu unterscheiden. Ob es so wie es jetzt im FS10 Modul eingebaut ist, auch beim Dimmer funktioniert, lässt sich erst feststellen, wenn es jemand mit einem Dimmer testet. Für mich ist das FS10 Modul erstmal soweit fertig. Es fehlt nur noch die englische Device specific help

elektron-bbs commented 7 years ago

Ich hänge mal ein Bild von meinen Aufzeichnungen zum besseren Verständnis an. fs10

elektron-bbs commented 7 years ago

Auch hier habe ich die Zeiten und Kommentare angepasst:

  "61" =>   ## ELV FS10
  {
     # tested transmitter:   FS10-S8, FS10-S4, FS10-ZE
     # tested receiver:      FS10-ST, FS10-MS, WS3000-TV, PC-Wettersensor-Empfänger
     # das letzte Bit 1 und 1 x 0 Preambel fehlt meistens
     #  ____            ____
     # |    |____      |    |________
     #    Bit 0            Bit 1
     # 400µS 400µS     400µS  800µS - Sollzeiten 
     name                 => 'FS10',
     id                   => '61',
     one                  => [1,-2],            
     zero                 => [1,-1],
     clockabs             => 400,  
     preamble             => 'P61#',     # prepend to converted message
     postamble            => '',         # Append to converted message
     clientmodule         => 'FS10',     # xx_FS10.pm
     length_min           => '38',       # eigentlich 41 oder 46 (Prüfsumme nicht bei allen)
     length_max           => '48',       # eigentlich 46
  }, 

In der Datei "10_FS10.pm" Zeile 314 sollte vielleicht noch "verbose" auf 4 gesetzt werden:

Log3 $name, 3, "$ioname FS10_Parse: $name $v";