Unbekannte Funkprotokolle: Unterschied zwischen den Versionen
K (Tippfehler korrigiert) |
|||
(23 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
Es gibt jede Menge offiziell in FHEM unterstützte Devices und Funkprotokolle. Solange das Device Ross und Reiter benennt (Homematic, Z-Wave, Intertechno etc.) ist es einfach dieses in FHEM einzubinden. Was aber, wenn selbst mit hinreichend gut aktualisierter Installation nichts erkannt wird und es ein No-Name Produkt ist bei dem man nur die Hoffnung hat, dass es im Innern etwas Bekanntes beherbergt? | Es gibt jede Menge offiziell in FHEM unterstützte Devices und Funkprotokolle. Solange das Device Ross und Reiter benennt (Homematic, Z-Wave, Intertechno etc.), ist es einfach, dieses in FHEM einzubinden. Was aber, wenn selbst mit hinreichend gut aktualisierter Installation nichts erkannt wird und es ein No-Name Produkt ist, bei dem man nur die Hoffnung hat, dass es im Innern etwas Bekanntes beherbergt? | ||
Dieser Wiki-Artikel soll jenen helfen, die Geräte mit einem unbekannten Funkprotokoll an FHEM anbinden bzw. mit FHEM steuern wollen. | Dieser Wiki-Artikel soll jenen helfen, die Geräte mit einem unbekannten Funkprotokoll an FHEM anbinden bzw. mit FHEM steuern wollen. | ||
Wenn hier drin irgendetwas unverständlich sein sollte (und wenn es nur deswegen sein sollte, weil es hinreichend bescheuert beschrieben ist :)), dann --> <big>'''MELDEN!'''</big> (oder natürlich einfach verbessern) - die Usability dieses Projekts sollte sehr gut werden... | Wenn hier drin irgendetwas unverständlich sein sollte (und wenn es nur deswegen sein sollte, weil es hinreichend bescheuert beschrieben ist :)), dann --> <big>'''MELDEN!'''</big>, vielleicht via BenutzerSeite (oder natürlich einfach direkt verbessern) - die Usability dieses Projekts sollte sehr gut werden... | ||
Dieser Artikel soll eine möglichst gut chronologische Sortierung haben, also: | Dieser Artikel soll eine möglichst gut chronologische Sortierung haben, also: | ||
Zeile 20: | Zeile 20: | ||
* Frequenzband (433 MHz, 868 MHz) | * Frequenzband (433 MHz, 868 MHz) | ||
(bei SIGNALduino / CUL kann manche Hardware - z.B. nanoCUL - da hardware-kompatibel, mit Projektaktivitäten von CUL ''oder'' SIGNALduino betrieben/firmware-geflasht werden; evt. ist es sogar außerdem empfehlenswert, mehrere baugleiche Geräte zu haben, um SIGNALduino ''und'' CUL gleichzeitig verfügbar zu haben - evt. auch weitere Geräte mit unterschiedlichen Frequenzen: 433/868) | (bei SIGNALduino / CUL kann manche Hardware - z.B. nanoCUL - da hardware-kompatibel, mit Projektaktivitäten von CUL ''oder'' SIGNALduino betrieben/firmware-geflasht werden; evt. ist es sogar außerdem empfehlenswert, mehrere baugleiche Geräte zu haben, um Support für SIGNALduino ''und'' CUL gleichzeitig verfügbar zu haben - evt. auch weitere Geräte mit unterschiedlichen Frequenzen: 433/868) | ||
==== Frequenzbereich ==== | ==== Frequenzbereich ==== | ||
Zeile 38: | Zeile 38: | ||
==== Encoding oder auch Leitungscode ==== | ==== Encoding oder auch Leitungscode ==== | ||
Die Art und Weise wie dieses Signal interpretiert wird hängt wiederum vom Encoding ab. Dazu sei auf die nachfolgenden Quellen verwiesen. | Die Art und Weise wie dieses Signal interpretiert wird, hängt wiederum vom Encoding ab. Dazu sei auf die nachfolgenden Quellen verwiesen. | ||
* [https://de.wikipedia.org/wiki/Leitungscode Leitungscode (Einstieg)] | * [https://de.wikipedia.org/wiki/Leitungscode Leitungscode (Einstieg)] | ||
Zeile 49: | Zeile 49: | ||
interpretiert. | interpretiert. | ||
Im FHEM-Forum gibt es viele freundliche Helfer die Euch bei Bedarf den richtigen Weg weisen. | Im FHEM-Forum gibt es viele freundliche Helfer, die Euch bei Bedarf den richtigen Weg weisen. | ||
==== Signalstruktur ==== | ==== Signalstruktur ==== | ||
Zeile 72: | Zeile 72: | ||
Das ist der herstellerspezifische Teil des Signalstroms - die Daten. Hersteller haben i.d.R. ihre eigene Definition der übertragenen Datenströme. Teils werden feste Code-Sequenzen übertragen, es gibt aber auch rollierende Codes (Engl.: Rolling Codes) bei denen sich die Daten bei jeder Übertragung ändern (Fremd-Manipulations-Sicherheit). | Das ist der herstellerspezifische Teil des Signalstroms - die Daten. Hersteller haben i.d.R. ihre eigene Definition der übertragenen Datenströme. Teils werden feste Code-Sequenzen übertragen, es gibt aber auch rollierende Codes (Engl.: Rolling Codes) bei denen sich die Daten bei jeder Übertragung ändern (Fremd-Manipulations-Sicherheit). | ||
Mit etwas Glück erkennt z.B. SIGNALduino das Protokoll, damit den Hersteller und legt automatisch ein passendes Device in FHEM an. Manchmal gibt es auch Fehlinterpretationen und das vermeintlich bekannte Device entpuppt sich als etwas anderes (Statement aus dem Forum: "Lösung war, wo Dooya drauf steht muss nicht immer Dooya drin stecken."). | Mit etwas Glück erkennt z.B. SIGNALduino bereits das Protokoll, damit den Hersteller und legt automatisch ein passendes Device in FHEM an. Manchmal gibt es auch Fehlinterpretationen und das vermeintlich bekannte Device entpuppt sich als etwas anderes (Statement aus dem Forum: "Lösung war, wo Dooya drauf steht muss nicht immer Dooya drin stecken."). | ||
== Wie fange ich an? == | == Wie fange ich an? == | ||
Zeile 89: | Zeile 89: | ||
Einfach probieren: Bau Dir einen [[SIGNALduino]] für das passende Frequenzband (die 433 oder 868 MHz-Variante des CC1101). Stelle im SIGNALduino-Setting die Frequenz auf die genannte ein (durch den Befehl cc1101_freq = 433.000 oder 868.000) und die Bandbreite auf das Maximum (cc1101_bWidth = 325 kHz bzw. 650 kHz). Jetzt noch das Attribut verbose auf 5 setzen und dann das FHEM-log (tail -f fhem-yyyy-mm.log) beobachten. | Einfach probieren: Bau Dir einen [[SIGNALduino]] für das passende Frequenzband (die 433 oder 868 MHz-Variante des CC1101). Stelle im SIGNALduino-Setting die Frequenz auf die genannte ein (durch den Befehl cc1101_freq = 433.000 oder 868.000) und die Bandbreite auf das Maximum (cc1101_bWidth = 325 kHz bzw. 650 kHz). Jetzt noch das Attribut verbose auf 5 setzen und dann das FHEM-log (tail -f fhem-yyyy-mm.log) beobachten. | ||
Ist ein Gerät in Reichweite, das regelmäßig etwas sendet (z.B. ein Funkthermometer), sollte hin und wieder etwas empfangen werden. Wenn | Ist ein Gerät in Reichweite, das regelmäßig etwas sendet (z.B. ein Funkthermometer), sollte hin und wieder etwas empfangen werden. Wenn [[Autocreate|autocreate]] aktiv ist, werden auf Basis der erkannten, bekannten Funkprotokolle automatisch neue Devices angelegt (dabei können auch diverse Funkthermometer der Nachbarschaft auftauchen). | ||
Ist es ein Gerät, das sich über eine Fernbedienung steuern lässt: Eine Taste betätigen und hoffen, dass sich im FHEM-Log etwas tut. Auch hier gilt: Handelt es sich um ein bekanntes Funkprotokoll, wird automatisch ein Device angelegt, allerdings nur eines für die Gerätefamilie. Bei Baumarkt-Funksteckdosen z.B. nur das erste gefundene. Die anderen müsst Ihr manuell anlegen und die entsprechenden Codes zur Identifikation der einzelnen Steckdosen anpassen (schaut z.B. hier nach: [[Intertechno_Code_Berechnung]]). | Ist es ein Gerät, das sich über eine Fernbedienung steuern lässt: Eine Taste betätigen und hoffen, dass sich im FHEM-Log etwas tut. Auch hier gilt: Handelt es sich um ein bekanntes Funkprotokoll, wird automatisch ein Device angelegt, allerdings nur eines für die Gerätefamilie. Bei Baumarkt-Funksteckdosen z.B. nur das erste gefundene. Die anderen müsst Ihr manuell anlegen und die entsprechenden Codes zur Identifikation der einzelnen Steckdosen anpassen (schaut z.B. hier nach: [[Intertechno_Code_Berechnung]]). | ||
Zeile 108: | Zeile 108: | ||
* abfotografieren und das Foto vergrößern bis Ihr den Aufdruck lesen könnt | * abfotografieren und das Foto vergrößern bis Ihr den Aufdruck lesen könnt | ||
Danach folgt dann | Danach folgt dann Internet-Suchmaschine und das Studium der zugehörigen Data Sheets der Chips. | ||
Das gibt Euch weitere Anhaltspunkte zum Modulationsverfahren, den Frequenzen und Optionen | Das gibt Euch weitere Anhaltspunkte zum Modulationsverfahren, den Frequenzen und Optionen welche diese Chips unterstützen. | ||
Wenn die Grundsatzfrage geklärt ist, ergeben sich die ersten Handlungsoptionen | Wenn die Grundsatzfrage geklärt ist, ergeben sich die ersten Handlungsoptionen | ||
Zeile 116: | Zeile 116: | ||
* ASK/FSK -> [[Selbstbau_CUL]] oder [[JeeLink]] | * ASK/FSK -> [[Selbstbau_CUL]] oder [[JeeLink]] | ||
Die Devices senden/empfangen nicht notwendigerweise auf 433 oder 868 MHz, sondern auf Frequenzen "knapp daneben", das kann z.B. bis zu 870 MHz hochgehen. Darüber, welche Frequenz es genau ist, gibt möglicherweise der verbaute Quarz Auskunft. Meist klein, silber mit einer Gravur wie z.B. 6,70 MHz versehen. Mit Hilfe der Spezifikationen im Datenblatt des daneben verbauten Chips lässt sich dann die Sende- bzw. Empfangsfrequenz errechnen. | Die Devices senden/empfangen nicht notwendigerweise auf 433 oder 868 MHz, sondern auf Frequenzen "knapp daneben", das kann z.B. bis zu 870 MHz hochgehen. Darüber, welche Frequenz es genau ist, gibt möglicherweise der verbaute Quarz Auskunft. Meist klein, silber mit einer Gravur wie z.B. 6,70 MHz versehen. Mit Hilfe der Spezifikationen (Frequenzteiler, ...) im Datenblatt des daneben verbauten Chips lässt sich dann die tatsächliche Sende- bzw. Empfangsfrequenz errechnen. | ||
==== Ansatz 3 - Messen ==== | ==== Ansatz 3 - Messen ==== | ||
Zeile 123: | Zeile 123: | ||
* Zum einen könnt Ihr den nrfmon-Ansatz verfolgen (siehe [https://jeelabs.net/projects/cafe/wiki/NRfMon_-_nano_Spectrum_Analyzer_with_the_RFM12B hier)]. Tipp: bestellt Euch direkt genug Material um zwei zu bauen, denn die RF12demo kann als Sender und Empfänger genutzt werden. Damit lässt sich direkt verifizieren, dass Euer RFM12B-Device wirklich sendet/empfängt. | * Zum einen könnt Ihr den nrfmon-Ansatz verfolgen (siehe [https://jeelabs.net/projects/cafe/wiki/NRfMon_-_nano_Spectrum_Analyzer_with_the_RFM12B hier)]. Tipp: bestellt Euch direkt genug Material um zwei zu bauen, denn die RF12demo kann als Sender und Empfänger genutzt werden. Damit lässt sich direkt verifizieren, dass Euer RFM12B-Device wirklich sendet/empfängt. | ||
* Der andere Ansatz nutzt einen DVB-T-Stick (siehe z.B. [https://homematic-forum.de/forum/viewtopic.php?t=11087 hier]. Es gibt aber viele | * Der andere Ansatz nutzt einen DVB-T-Stick (siehe z.B. [https://homematic-forum.de/forum/viewtopic.php?t=11087 hier]. Es gibt aber viele Internet-Suchmaschine-Treffer unter dem Stichwort [https://www.mikrocontroller.net/topic/243367 SDR]. Außerdem ein konkretes Projekt: [https://github.com/merbanan/rtl_433/ rtl_433]. | ||
* Mein persönlicher Favorit ist der [https://github.com/jopohl/urh Universal Radio Hacker]. Mit dem war ich in der Lage mittels RTL-SDR-Stick nicht nur Sequenzen mitzuschneiden sondern auch direkt zu analysieren. | * Mein persönlicher Favorit ist der [https://github.com/jopohl/urh Universal Radio Hacker]. Mit dem war ich in der Lage, mittels RTL-SDR-Stick nicht nur Sequenzen mitzuschneiden sondern auch direkt zu analysieren. | ||
Wieso überhaupt so kompliziert? OOK nutzt nur eine Frequenz, FSK zwei, vier, je nach Variante. Es kann auch vorkommen (so wie bei mir), dass ein FSK-Device auf einen OOK-Sender anspricht. Der Grund dafür sind Oberwellen die mit dem Ein-/Auschalten der Frequenz einher gehen. | Wieso überhaupt so kompliziert? OOK nutzt nur eine Frequenz, FSK zwei, vier, je nach Variante. Es kann auch vorkommen (so wie bei mir), dass ein FSK-Device auf einen OOK-Sender anspricht. Der Grund dafür sind Oberwellen die mit dem Ein-/Auschalten der Frequenz einher gehen. | ||
Zeile 165: | Zeile 165: | ||
Das folgende Beispiel geht davon aus, dass Ihr im 868 MHz-Band unterwegs seid. Bei 433 MHz könnt Ihr in gleicher Weise vorgehen. | Das folgende Beispiel geht davon aus, dass Ihr im 868 MHz-Band unterwegs seid. Bei 433 MHz könnt Ihr in gleicher Weise vorgehen. | ||
Fangt damit an, dass Ihr den CC101 mittels set-Command cc1101_freq auf 868.000, cc1101_bWidth auf 650 und cc11=1_sens auf 8 einstellt. Kontrollieren könnt Ihr das durch get ccconf. Die Bandbreite bWidth gibt an wie groß der Empfangsbereich ist. Bei 650 kHz sind das z.B. +/- 325 kHz, also der Bereich von 867.675 bis 868.325 MHz. | Fangt damit an, dass Ihr den CC101 mittels set-Command cc1101_freq auf 868.000, cc1101_bWidth auf 650 und cc11=1_sens auf 8 einstellt. Kontrollieren könnt Ihr das durch <code>get ccconf</code>. Die Bandbreite bWidth gibt an wie groß der Empfangsbereich ist. Bei 650 kHz sind das z.B. +/- 325 kHz, also der Bereich von 867.675 bis 868.325 MHz. | ||
Wenn ihr etwas empfangt ist das ein Ansatzpunkt. Anderfalls könnt Ihr die cc1101_freq in 200 kHz-Schritten (868.200, 868.400 ...) erhöhen und das Frequenzband auf diese Art und Weise absuchen. Ein Hinweis an der Stelle: Im FHEM-Log folgt bei den SIGNALduino-Einträgen nach dem Datenteil D= die Empfangsstärke R=. Damit könnt Ihr feststellen, ob Ihr Euch der Sendefrequenz nähert oder entfernt. | Wenn ihr etwas empfangt ist das ein Ansatzpunkt. Anderfalls könnt Ihr die cc1101_freq in 200 kHz-Schritten (868.200, 868.400 ...) erhöhen und das Frequenzband auf diese Art und Weise absuchen. Ein Hinweis an der Stelle: Im FHEM-Log folgt bei den SIGNALduino-Einträgen nach dem Datenteil D= die Empfangsstärke R=. Damit könnt Ihr feststellen, ob Ihr Euch der Sendefrequenz nähert oder entfernt. | ||
Zeile 209: | Zeile 209: | ||
Wie ist diese Sequenz zu interpretieren? | Wie ist diese Sequenz zu interpretieren? | ||
Anhand der anfänglich gelisteten Puls-Beschreibungen Px= (Aktiv-Indikator/Dauer): | |||
* Es startet mit einer Pause D='''0'''123232323232 | * Es startet mit einer Pause D='''0'''123232323232 | ||
* gefolgt von einem Signal D=0'''1'''23232323232 in der Länge von ca. 16 ms. | * gefolgt von einem Signal D=0'''1'''23232323232 in der Länge von ca. 16 ms (15916 µs). | ||
* danach folgt ein Sync-Block D=01'''23232323232'''... bei dem jeweils Pärchen von 400 µs Pause/400 µs Signal wiederholt werden. | * danach folgt ein Sync-Block D=01'''23232323232'''... bei dem jeweils Pärchen von 400 µs Pause/400 µs Signal wiederholt werden. | ||
* Sync- und Datenteil sind durch einen Puls von 4 ms [P4=4008] getrennt D=0123232323232323232323232'''4'''53265 | * Sync- und Datenteil sind durch einen Puls von 4 ms [P4=4008] getrennt D=0123232323232323232323232'''4'''53265 | ||
* gefolgt vom Datenteil D=01232323232323232323232324'''53265'''.... | * gefolgt vom Datenteil D=01232323232323232323232324'''53265'''.... | ||
Beim Datenteil wird es etwas komplizierter. Hier sind immer ein kurzer (2 oder 3) und ein langer (5 oder 6) Wert kombiniert. Folglich muss man bei der Interpretation zwischen Vorzeichen und Dauer differenzieren. Ein Pärchen ist immer 1.200 µs lang. In der Mitte dieser Zeitscheibe kann der übertragene Wert folglich eine Pause oder ein Signal sein. | Beim Datenteil wird es etwas komplizierter. Hier sind immer ein kurzer (2 oder 3) und ein langer (5 oder 6) Wert kombiniert. Folglich muss man bei der Interpretation zwischen Aktiv-Indikator (Vorzeichen) und Dauer differenzieren. Ein Pärchen ist immer 1.200 µs lang. In der Mitte dieser Zeitscheibe kann der übertragene Wert folglich eine Pause oder ein Signal sein. | ||
Beispiel: Den Vorspann | Beispiel: Den Vorspann | ||
<code>P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324</code> lassen wir mal außen vor und konzentrieren uns auf | <code>P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324</code> (bestehend aus Puls-Beschreibungen und initialer Puls-Aktivität) lassen wir mal außen vor und konzentrieren uns auf den nachfolgenden echten Nutz-Daten-Teil (hinsichtlich dessen logischer Protokoll-Umformung hin zur finalen Nutz-Datenwort-Sequenz): | ||
<code>53265326535326535326265353262653265353535326265353265326262653265326265353535353532653535353262653265353265353535353535353532626 | <code>53265326535326535326265353262653265353535326265353265326262653265326265353535353532653535353262653265353265353535353535353532626 (rohe Abfolge der Puls-Typen) | ||
lSsLlSsLlSlSsLlSlSsLsLlSlSsLsLlSsLlSlSlSlSsLsLlSlSsLlSsLsLsLlSsLlSsLsLlSlSlSlSlSlSsLlSlSlSlSsLsLlSsLlSlSsLlSlSlSlSlSlSlSlSlSsLsL | lSsLlSsLlSlSsLlSlSsLsLlSlSsLsLlSsLlSlSlSlSsLsLlSlSsLlSsLsLsLlSsLlSsLsLlSlSlSlSlSlSsLlSlSlSlSsLsLlSsLlSlSsLlSlSlSlSlSlSlSlSlSsLsL (als sSlL-Notation) | ||
1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 | 1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 (als Bitfolge) | ||
10101101 10011001 01111001 10100010 10011111 10111100 10110111 11111100 | 10101101 10011001 01111001 10100010 10011111 10111100 10110111 11111100 (Gruppierung auf Bit-Datenworte) | ||
AD99 79A2 9FBC B7FC</code> | AD99 79A2 9FBC B7FC (als Hex-Datenworte)</code> | ||
Die Analyse basiert auf folgenden Annahmen (mit Beispiels-Werten) | Die Analyse basiert auf folgenden Annahmen (mit Beispiels-Werten) | ||
Zeile 240: | Zeile 242: | ||
* es ist wohl sinnvoll, zu versuchen, sich evt. an einem längsten Puls (das ist nämlich evt. eine Sync-Pause) zu orientieren, um nachfolgende Bereiche evt. als startendes Bit-Datenpaket identifizieren zu können | * es ist wohl sinnvoll, zu versuchen, sich evt. an einem längsten Puls (das ist nämlich evt. eine Sync-Pause) zu orientieren, um nachfolgende Bereiche evt. als startendes Bit-Datenpaket identifizieren zu können | ||
* man sollte die Pulsfolge per Textsuche analysieren, in einem Editor/Reader, der Such-Texte in einer Zeile '''mehrfach''' farbig markieren kann (less, ...) - bei markiertem Suchtreffer kann man dann Teil-Folgen identifizieren, welche sich deterministisch ''wiederholen'' - diese sind dann wohl offensichtlich codierte Bit-Daten, welche es passend zu entschlüsseln gilt | * man sollte die Pulsfolge per Textsuche analysieren, in einem Editor/Reader, der Such-Texte in einer Zeile '''mehrfach''' farbig markieren kann (less, ...) - bei markiertem Suchtreffer kann man dann Teil-Folgen identifizieren, welche sich deterministisch ''wiederholen'' - diese sind dann wohl offensichtlich codierte Bit-Daten, welche es passend zu entschlüsseln gilt | ||
* die identifizierten Merkmale sind dann als ein neues Protokoll (falls kein bereits existierendes Protokoll zu unpräzise formuliert sein sollte!) in <code>FHEM/lib/signalduino_protocols.hash</code> hinzuzufügen (Angabe präziser Durchschnittswerte von Basis-Takt, Gesamt-Patternlänge, Puls-Pause-Verhältnisse, ... - Details dieses Protokolls siehe Header dieser Datei), und dann muss ein | * die identifizierten Merkmale sind dann als ein neues Protokoll (falls kein bereits existierendes Protokoll zu unpräzise formuliert sein sollte!) in <code>FHEM/lib/signalduino_protocols.hash</code> hinzuzufügen (Angabe präziser Durchschnittswerte von Basis-Takt, Gesamt-Patternlänge, Puls-Pause-Verhältnisse, ... - Details dieses Protokolls siehe Header dieser Datei), und dann muss ein <code>reload 00_SIGNALduino</code> gemacht werden, um dies zu testen (hier: beim sduino-Device temporär(!! - hoher Platzbedarf...) Attribute verbose 5 und debug 1 setzen!) | ||
* für Beispiele einer Protokoll-Implementierung sollte man sich wohl auch die History (entsprechende Commits) im [[#Links|RFFHEM git repository]] ansehen | * für Beispiele einer Protokoll-Implementierung sollte man sich wohl auch die History (entsprechende Commits) im [[#Links|RFFHEM git repository]] ansehen | ||
* es ist evt. sinnvoll, sich die Verarbeitungskette anhand von Empfang/Senden bereits funktionsfähiger Protokolle / Geräte zu verdeutlichen, bevor man selber loslegt, neue Geräte (Protokolle) zu unterstützen | * es ist evt. sinnvoll, sich die Verarbeitungskette anhand von Empfang/Senden bereits funktionsfähiger Protokolle / Geräte zu verdeutlichen, bevor man selber loslegt, neue Geräte (Protokolle) zu unterstützen | ||
Zeile 283: | Zeile 285: | ||
* aus diesen dann einen Mittelwert bilden, damit man die größte Präzision erreicht | * aus diesen dann einen Mittelwert bilden, damit man die größte Präzision erreicht | ||
* evt. sogar längere (Sync-)Pulse (z.B.: 15x ''clockabs'' Low, 1x ''clockabs'' High) heranziehen, um durch Mittelung (+ Teilung) über viele dieser z.B. 15x wiederholten Pulslängen einen daraus resultierend maximal präzisen ''clockabs''-Basistakt-Mittelwert zu ermitteln | * evt. sogar längere (Sync-)Pulse (z.B.: 15x ''clockabs'' Low, 1x ''clockabs'' High) heranziehen, um durch Mittelung (+ Teilung) über viele dieser z.B. 15x wiederholten Pulslängen einen daraus resultierend maximal präzisen ''clockabs''-Basistakt-Mittelwert zu ermitteln | ||
* evt. ist es auch hilfreich, den im Gerät verbauten | * evt. ist es auch hilfreich, den im Gerät verbauten Quarz zu berücksichtigen - u.U. lässt sich hieraus (falls eine solche Verarbeitung im Gerät tatsächlich Timer-mäßig relevant sein sollte!) ein sehr präziser da "mechanisch" passender Puls-Takt-Wert ermitteln (Pseudo-Beispiel: | ||
<code>(1 / 8MHz) * 2048 [digitaler Teiler] = 0.256ms == 256us</code> | <code>(1 / 8MHz) * 2048 [digitaler Teiler] = 0.256ms == 256us</code> | ||
); wobei der mechanische Gerätetakt evt. doch erstaunlich anders sein könnte als die von SIGNALduino erfassten Werte (inwiefern das dann hinsichtlich Rx-/Tx-Präzision relevant ist - wer weiß...) | ); wobei der mechanische Gerätetakt evt. doch erstaunlich anders sein könnte als die von SIGNALduino erfassten Werte (inwiefern das dann hinsichtlich Rx-/Tx-Präzision relevant ist - wer weiß...) | ||
Zeile 291: | Zeile 293: | ||
Es ist evt. empfehlenswert, auf github einen eigenen Fork des RFFHEM-Upstream-Repositories zu erstellen - dann kann man ''dort'' seine Entwicklung durchführen: | Es ist evt. empfehlenswert, auf github einen eigenen Fork des RFFHEM-Upstream-Repositories zu erstellen - dann kann man ''dort'' seine Entwicklung durchführen: | ||
* Änderungen durchführen (im korrekten Branch) | * Änderungen durchführen (im korrekten Branch) | ||
* alles committen | * alles committen | ||
* mit dem üblichen FHEM-Befehl (<code>update all ...</code>, aber eben sinnigerweise unter Angabe der URL seines ''eigenen'' Repositories | * <code>controls_signalduino.txt</code> updaten (wird via github actions automatisch aktualisiert), sonst kann nicht über den update Befehl installiert werden! | ||
* mit dem üblichen FHEM-Befehl (<code>update all ...</code>, aber eben sinnigerweise unter Angabe der URL seines ''eigenen'' Repositories!) seine eigenen Änderungen jeweils korrekt verwaltend und updatend austesten | |||
* evt. hier jeweils <code>reload BEARBEITETES_MODUL</code> nötig | * evt. hier jeweils <code>reload BEARBEITETES_MODUL</code> nötig | ||
* wenn das alles passt, hat man bereits seinen eigenen Fork fix und fertig (und authentisch getestet) und kann somit direkt - evt. nach einem bereinigenden <code>git rebase -i @{u}</code> - einen Pull Request daraus machen (anders ausgedrückt: "direkt kontext-integrierte Entwicklung", "am Puls der Zeit", "mit voller Tool-Unterstützung"). Dies am besten vollständig Automatisierungs-gekapselt durch ein Shell-Script (FIXME: am besten hier einfach direkt hier präsentieren?), welches an FHEM den <code>update all ...</code> request schickt (über telnet, Port 7072) ''und'' den <code>reload BEARBEITETES_MODUL</code> durchführt. | * wenn das alles passt, hat man bereits seinen eigenen Fork fix und fertig (und authentisch getestet) und kann somit direkt - evt. nach einem bereinigenden <code>git rebase -i @{u}</code> - einen Pull Request daraus machen (anders ausgedrückt: "direkt kontext-integrierte Entwicklung", "am Puls der Zeit", "mit voller Tool-Unterstützung"). Dies am besten vollständig Automatisierungs-gekapselt durch ein Shell-Script (FIXME: am besten hier einfach direkt hier präsentieren?), welches an FHEM den <code>update all ...</code> request schickt (über telnet, Port 7072) ''und'' den <code>reload BEARBEITETES_MODUL</code> durchführt. | ||
== SIGNALduino - FSK == | == SIGNALduino - FSK == | ||
Dieses Kapitel geht davon aus, dass ihr einen SIGNALduino für alle weiteren Schritte nutzt. | |||
Aktuell laufen Bestrebungen den SIGNALduino FSK-fähig zu machen: siehe [https://forum.fhem.de/index.php/topic,106582.0.html FSK mit SIGNALduino] (vormals https://forum.fhem.de/index.php/topic,82379.0.html) | Aktuell laufen Bestrebungen, den SIGNALduino FSK-fähig zu machen: siehe [https://forum.fhem.de/index.php/topic,106582.0.html FSK mit SIGNALduino] (vormals https://forum.fhem.de/index.php/topic,82379.0.html) | ||
Die Summary der CC1101-Settings findet ihr [https://forum.fhem.de/index.php/topic,106594.0.html#new hier]. | Die Summary der CC1101-Settings findet ihr [https://forum.fhem.de/index.php/topic,106594.0.html#new hier]. | ||
=== FSK Senden === | === FSK Senden === | ||
Die ersten Bits des CC1101-Register 12 MDMCFG2 bestimmen die Übertragungsweise: | Die ersten Bits des CC1101-Register 12 MDMCFG2 bestimmen die Übertragungsweise: | ||
000 = 2-FSK | 000 = 2-FSK | ||
Zeile 325: | Zeile 314: | ||
Schaut Euch den aktuellen Registerinhalt an, bevor Ihr ihn ändert. Am einfachsten geht das über | Schaut Euch den aktuellen Registerinhalt an, bevor Ihr ihn ändert. Am einfachsten geht das über | ||
<code>get <mysduino> ccreg 99</code> | |||
Ihr müsst beim angezeigten Wert die ersten drei Bits entsprechend abändern, also z.B. aus 0x30 dann 0x10 für GFSK statt OOK machen. | Ihr müsst beim angezeigten Wert die ersten drei Bits entsprechend abändern, also z.B. aus 0x30 dann 0x10 für GFSK statt OOK machen. | ||
Das Register wird über | Das Register wird über | ||
<code>set <mysduino> raw W1410</code> | |||
abgeändert (bitte beachtet das Offset von 0x02 für das Beschreiben eines Registers, 14 adressiert Register 12). | abgeändert (bitte beachtet das Offset von 0x02 für das Beschreiben eines Registers, 14 adressiert Register 12). | ||
Nun könnt Ihr FSK senden. Das im URH angezeigte Spektrum sollte nun zwei Spitzen aufweisen. Ihr seht daneben vermutlich auch weitere kleine links und rechts daneben. Das liegt daran, dass es Oberwellen gibt. Bei 2-FSK sind dies mehr als bei dem geglätteten GFSK. | Nun könnt Ihr FSK senden. Das im URH angezeigte Spektrum sollte nun zwei Spitzen aufweisen. Ihr seht daneben vermutlich auch weitere kleine links und rechts daneben. Das liegt daran, dass es Oberwellen gibt. Bei 2-FSK sind dies mehr als bei dem geglätteten GFSK. | ||
=== Sendefrequenz und Frequenzhub === | |||
<div class="tright" style="clear:none">[[Datei:PeakLow.png|mini|ohne|300px|FSK, Trägerfrequenz minus Hub]]</div> | |||
<div class="tright" style="clear:none">[[Datei:PeakHigh.png|mini|links|300px|FSK, Trägerfrequenz plus Hub]]</div> | |||
Bei OOK wird das Funksignal ein- und ausgeschaltet, um die bits als 0 und 1 darzustellen. Bei FSK sieht das anders aus. Zur Übertragung wird ein permanentes Signal ausgestrahlt; die Darstellung der bits 0 und 1 erfolgt durch Erniedrigung bzw. Erhöhung der Frequenz. Folglich gilt es sowohl die Trägerfrequenz als auch den Frequenzhub zu ermitteln. Das bit 0 wird i.d.R. durch Trägerfrequenz minus Hub, das bit 1 durch Trägerfrequenz plus Hub dargestellt. | |||
In diesem Beispielspektrum eines FSK-Signals ist ersichtlich, dass die untere Frequenz bei ca. 868,233 Mhz und die obere bei ca. 868,281 Mhz liegt. Die Trägerfrequenz liegt folglich in der Mitte bei 868,257 MHz und der Frequenzhub beträgt ca. 24 kHz. | |||
=== Ermittlung der Frequenzen === | |||
Wie im OOK-Kapitel bereits angesprochen, ist eine Messung mit Hilfe eines SDR-Sticks hilfreich. Doch Vorsicht - diese Sticks sind oftmals nicht geeicht und die angezeigte Frequenz wird "relativ" genau gemessen. Was aber hilft ist ein Vergleich Original/Kopie. Messt mit dem SDR-Stick unter Nutzung eines Programms wie URH die Frequenzen, sendet mit dem SDUINO ebenfalls ein Signal auf einer von Euch vorgegebenen Frequenz. Nehmt als Basis für den Ver- bzw. Abgleich die von Euch im SDUINO vorgegebene Frequenz. Die ist für die weiteren Aktivitäten relevant. Die Abweichung könnt Ihr in der URH-Software zur Frequenzkorrektur vorgeben, dann werden identische Werte angezeigt. | |||
=== Hub === | === Hub === | ||
Da hilft Euch das RF Studio für den CC1101. Der darin ermittelte Wert ist in das Register 15 DEVIATN zu übertragen. Bei 25 kHz Hub ist das der Wert 40, der mittels | |||
Da hilft Euch das RF Studio für den CC1101. Der darin ermittelte Wert ist in das Register 15 DEVIATN zu übertragen. Bei 25 kHz Hub ist das der Wert 40 der mittels | <code>set <mysduino> raw W1740</code> | ||
an den CC1101 des SDUINO übermittelt wird. | an den CC1101 des SDUINO übermittelt wird. | ||
Zeile 346: | Zeile 345: | ||
=== Baudrate === | === Baudrate === | ||
Beim SDUINO übernimmt der CC1101 die Funktion eines Modems. Die Signalaufbereitung bzw. -erzeugung erfolgt im Arduino. Das können wir auch für das Senden von FSK Signalen nutzen. Der CC1101 bietet eine Fülle weiterer Optionen (Sync, FIFO etc.), die aber eher für Spezialisten geeignet sind. | |||
Beim SDUINO übernimmt der CC1101 die Funktion eines Modems. Die Signalaufbereitung bzw. -erzeugung erfolgt im Arduino. Das können wir auch für das Senden von FSK Signalen nutzen. Der CC1101 bietet | |||
Welche Baudrate soll/muss ich angeben? Zunächst mal gilt es folgende Teilstrecken zu unterscheiden: | Welche Baudrate soll/muss ich angeben? Zunächst mal gilt es folgende Teilstrecken zu unterscheiden: | ||
FHEM <-> Arduino <-> CC1101 <-> Sendesignal | FHEM <-> Arduino <-> CC1101 <-> Sendesignal | ||
Die Baudrate zwischen FHEM und dem Arduino wird in FHEM vorgegeben. Die für den CC1101 angegebene und mittels | Die Baudrate zwischen FHEM und dem Arduino wird in FHEM vorgegeben. Die für den CC1101 angegebene und mittels <code>get <myduino> ccconf</code> ausgegebene Baudrate ist die zwischen dem Arduino und dem CC1101. Mit dieser Baudrate wird das Funksignal gesampled. | ||
Beim Empfang interpretiert der Arduino den Signalpegel und erkennt die Übergänge zwischen 0 und 1. Es wird die Dauer des jeweiligen Signals | Beim Empfang interpretiert der Arduino den Signalpegel und erkennt die Übergänge zwischen 0 und 1. Es wird die Dauer des jeweiligen Signals ermittelt und einem Parameter ('''P'''uls?) 0-7 zugeordnet. Auf diese Weise wird die gesamte empfangene Codesequenz beschrieben. | ||
<div class="tleft" style="clear:both">[[Datei:RIO-Signal | <div class="tleft" style="clear:both">[[Datei:RIO-Signal.png|mini|600px|RIO-Signal decodiert]]</div> | ||
<div style="clear:both"></div> | <div style="clear:both"></div> | ||
Die Baudrate lässt sich im CC1101 nur bedingt präzise einstellen, da dafür nur ein Byte zur Verfügung steht. | Die Baudrate lässt sich im CC1101 nur bedingt präzise einstellen, da dafür nur ein Byte zur Verfügung steht. | ||
Ich habe bei der obigen Sequenz die Baudrate bzw. SCLK aus dem Vorspann (Preamble) ermittelt und bin auf 2.482 Baud gekommen. Für die Übertragung habe ich aber die 10fache Rate verwendet, um die Steuerung des Zustandes 0/1 dem Arduino und nicht dem CC1101 zu überlassen. Statt einer 0 werden dann halt 10x 0 übertragen. Auf Sendeseite ändert sich dadurch nichts. Die | Ich habe bei der obigen Sequenz die Baudrate bzw. SCLK aus dem Vorspann (Preamble) ermittelt und bin auf 2.482 Baud gekommen. Für die Übertragung habe ich aber die 10fache Rate verwendet, um die Steuerung des Zustandes 0/1 dem Arduino und nicht dem CC1101 zu überlassen. Statt einer 0 werden dann halt 10x 0 übertragen. Auf Sendeseite ändert sich dadurch nichts. Die Software URH arbeitet ähnlich. Das Signal wird z.B. mit 1 MHz gesampled. Um auf die ermittelte Baudrate und eine reale Darstellung zu kommen, gebe ich 402 Samples/Symbol (Symbol=bit) ein. | ||
Das Ergebnis: | Das Ergebnis: | ||
<div class="tleft" style="clear:both">[[Datei:Vergleich RIO-SDUINO-Signale.png|mini|Vergleich RIO/SDUINO-Signale]]</div> | <div class="tleft" style="clear:both">[[Datei:Vergleich RIO-SDUINO-Signale.png|mini|600px|Vergleich RIO/SDUINO-Signale]]</div> | ||
<div style="clear:both"></div> | <div style="clear:both"></div> | ||
=== Codesequenzen === | === Codesequenzen === | ||
Die Interpretaion des low und high-Zustandes hängt von der Sende- und Empfangsfrequenz ab. Wenn Ihr im OOK-Modus Sequenzen mitgeschnitten habt werden die möglicherweise | Die Interpretaion des low- und high-Zustandes hängt von der Sende- und Empfangsfrequenz ab. Wenn Ihr im OOK-Modus Sequenzen mitgeschnitten habt werden die möglicherweise anders interpretiert als die mittels FSK empfangenen. Deshalb: Sequenzen mit der Original-Fernbedienung neu erzeugen und mitschneiden. Achtet dabei darauf, dass diese lang genug sind, um das komplette Steuerungssignal mitzuschneiden. Die Preamble ist recht auffällig (bei mir 01232323 ...). Die wiederholt sich nach dem eigentlichen Steuerungssignal. Ab hier könnt Ihr also abschneiden. Ferner empfiehlt sich, das mitgeschnittene Signal zu dekodieren und in Hex darzustellen. Dann erkennt Ihr, ob identische Inhalte/Sequenzen mitgeschnitten wurden. Das trennt die Spreu vom Weizen. | ||
Damit konnte ich mein Problem meines unbekannten Funkprotokolls (RIO-Fernbedienung) letztendlich lösen. | Damit konnte ich mein Problem meines unbekannten Funkprotokolls (RIO-Fernbedienung) letztendlich lösen. | ||
Last but not least: SDUINO Firmware war die Version v3.4.1_dev_21.12 | === Konfiguration === | ||
Last but not least meine Konfiguration: SDUINO Firmware war die Version v3.4.1_dev_21.12 | |||
Register-Settings: | |||
* Trägerfrequenz: 868.302 MHz | |||
* Deviation: 25 kHz | |||
* Bandwidth: 58 kHz | |||
* Baudrate: 24.795 kBaud | |||
* Modulation: GFSK | |||
<pre>ccregAll: | |||
ccreg 00: 0D 2E 2D 47 D3 91 3D 04 32 00 00 06 00 21 65 6F | |||
ccreg 10: F9 F4 18 23 B9 40 07 00 18 14 6C 07 00 91 87 6B | |||
ccreg 20: F8 56 11 EF 2D 12 1F 41 00 59 7F 3F 88 31 0B | |||
Configuration Register Detail (address, name, value): | |||
0x00 IOCFG2 - 0x0D | |||
0x01 IOCFG1 - 0x2E | |||
0x02 IOCFG0 - 0x2D | |||
0x03 FIFOTHR - 0x47 | |||
0x04 SYNC1 - 0xD3 | |||
0x05 SYNC0 - 0x91 | |||
0x06 PKTLEN - 0x3D | |||
0x07 PKTCTRL1 - 0x04 | |||
0x08 PKTCTRL0 - 0x32 | |||
0x09 ADDR - 0x00 | |||
0x0A CHANNR - 0x00 | |||
0x0B FSCTRL1 - 0x06 | |||
0x0C FSCTRL0 - 0x00 | |||
0x0D FREQ2 - 0x21 | |||
0x0E FREQ1 - 0x65 | |||
0x0F FREQ0 - 0x6F | |||
0x10 MDMCFG4 - 0xF9 | |||
0x11 MDMCFG3 - 0xF4 | |||
0x12 MDMCFG2 - 0x18 | |||
0x13 MDMCFG1 - 0x23 | |||
0x14 MDMCFG0 - 0xB9 | |||
0x15 DEVIATN - 0x40 | |||
0x16 MCSM2 - 0x07 | |||
0x17 MCSM1 - 0x00 | |||
0x18 MCSM0 - 0x18 | |||
0x19 FOCCFG - 0x14 | |||
0x1A BSCFG - 0x6C | |||
0x1B AGCCTRL2 - 0x07 | |||
0x1C AGCCTRL1 - 0x00 | |||
0x1D AGCCTRL0 - 0x91 | |||
0x1E WOREVT1 - 0x87 | |||
0x1F WOREVT0 - 0x6B | |||
0x20 WORCTRL - 0xF8 | |||
0x21 FREND1 - 0x56 | |||
0x22 FREND0 - 0x11 | |||
0x23 FSCAL3 - 0xEF | |||
0x24 FSCAL2 - 0x2D | |||
0x25 FSCAL1 - 0x12 | |||
0x26 FSCAL0 - 0x1F | |||
0x27 RCCTRL1 - 0x41 | |||
0x28 RCCTRL0 - 0x00 | |||
0x29 FSTEST - 0x59 | |||
0x2A PTEST - 0x7F | |||
0x2B AGCTEST - 0x3F | |||
0x2C TEST2 - 0x88 | |||
0x2D TEST1 - 0x31 | |||
0x2E TEST0 - 0x0B | |||
</pre> | |||
=== Finale === | |||
Nach Aktivierung der vormals ausgeschalteten Message-Typen im SIGNALduino werden nunmehr SD_Keeloq-Devices angelegt. | |||
Der SIGNALduino erkennt | |||
<pre> | |||
2020.01.12 14:33:03 4: mySIGNALduino: Parse_MS, Decoded matched MS Protocol id 88 dmsg P88#74D21B18008B48058 length 68 RSSI = -32 | |||
2020.01.12 14:33:03 5: mySIGNALduino: Dispatch, P88#74D21B18008B48058, test ungleich: disabled | |||
2020.01.12 14:33:03 5: mySIGNALduino: Dispatch, P88#74D21B18008B48058, -32 dB, dispatch | |||
2020.01.12 14:33:03 5: mySIGNALduino: dispatch P88#74D21B18008B48058 | |||
2020.01.12 14:33:04 2: mySIGNALduino: SD_Keeloq_Parse Unknown device unknown with Code 012D100 detected, please define (rawdate=74D21B18008B48058) | |||
2020.01.12 14:33:04 2: autocreate: define SD_Keeloq_012D100 SD_Keeloq 012D100 | |||
2020.01.12 14:33:04 2: autocreate: define FileLog_SD_Keeloq_012D100 FileLog ./log/SD_Keeloq_012D100-%Y.log SD_Keeloq_012D100 | |||
2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, Matched MS Protocol id 91.1 -> Atlantic security | |||
2020.01.12 14:33:04 5: mySIGNALduino: Parse_MS, Starting demodulation at Position 3 | |||
2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, last part pair=2 reconstructed, last bit=0 | |||
2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, Matched MS Protocol id 87 -> JAROLIFT | |||
2020.01.12 14:33:04 5: mySIGNALduino: Parse_MS, Starting demodulation at Position 2 | |||
2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, last part pair=1 reconstructed, last bit=1 | |||
2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, Matched MS Protocol id 88 -> HCS300/HCS301 | |||
2020.01.12 14:33:04 5: mySIGNALduino: Parse_MS, Starting demodulation at Position 2 | |||
</pre> | |||
und routet die Requests an das Modul SD_Keeloq weiter. Der Hinweis auf HCS301 führt auf die richtige Spur. Das analysierte Protokoll KeeLoq ist im Data Sheet des Microchip HCS301 (KeeLoq Code Hopping Encoder) beschrieben. Somit wurde aus einem unbekannten Funkprotokoll letztlich ein bekanntes. | |||
Mittlerweile ist das Protokoll als '''model enjoy_motors_HS''' in das Modul '''SD_Keeloq''' aufgenommen. | |||
== CUL - FSK und Co. == | == CUL - FSK und Co. == | ||
Dieses Kapitel geht davon aus, dass ihr einen CUL für alle weiteren Schritte nutzt. | Dieses Kapitel geht davon aus, dass ihr einen CUL für alle weiteren Schritte nutzt. | ||
Zeile 382: | Zeile 469: | ||
== FAQ == | == FAQ == | ||
=== Woran genau wird erkannt ob ein Signal ShortHigh, bzw ShortLow ist? === | === Woran genau wird erkannt ob ein Signal ShortHigh, bzw ShortLow ist? === | ||
Diese Begriffe kommen nur bei der Manchester Codierung zum Einsatz. | Diese Begriffe kommen nur bei der Manchester Codierung zum Einsatz. | ||
Die Bestimmung short High / Low erfolgt einfach dadurch ob gesendet wird oder ob gerade eine Pause eingelegt wird. | Die Bestimmung short High / Low erfolgt einfach dadurch, ob gesendet wird oder ob gerade eine Pause eingelegt wird. | ||
Short und Long wird einfach durch die Kalkulation der Dauer ermittelt. | Short und Long wird einfach durch die Kalkulation der Dauer ermittelt. | ||
Zeile 408: | Zeile 493: | ||
== Links == | == Links == | ||
* [https://github.com/RFD-FHEM/RFFHEM RFFHEM git repository] (drandenken: korrekten Branch auswählen!) | * [https://github.com/RFD-FHEM/RFFHEM RFFHEM git repository] (drandenken: korrekten Branch auswählen!) | ||
* [https://www.hamspirit.de/2286/signalanalyse-fuer-dummies/ Signalanalyse für Dummies] | * [https://www.hamspirit.de/2286/signalanalyse-fuer-dummies/ Signalanalyse für Dummies] | ||
Zeile 421: | Zeile 505: | ||
[[Kategorie:HOWTOS]] | [[Kategorie:HOWTOS]] | ||
[[Kategorie:433MHz]] | [[Kategorie:433MHz]] | ||
[[Kategorie:868MHz]] |
Aktuelle Version vom 8. Januar 2023, 11:18 Uhr
Es gibt jede Menge offiziell in FHEM unterstützte Devices und Funkprotokolle. Solange das Device Ross und Reiter benennt (Homematic, Z-Wave, Intertechno etc.), ist es einfach, dieses in FHEM einzubinden. Was aber, wenn selbst mit hinreichend gut aktualisierter Installation nichts erkannt wird und es ein No-Name Produkt ist, bei dem man nur die Hoffnung hat, dass es im Innern etwas Bekanntes beherbergt?
Dieser Wiki-Artikel soll jenen helfen, die Geräte mit einem unbekannten Funkprotokoll an FHEM anbinden bzw. mit FHEM steuern wollen.
Wenn hier drin irgendetwas unverständlich sein sollte (und wenn es nur deswegen sein sollte, weil es hinreichend bescheuert beschrieben ist :)), dann --> MELDEN!, vielleicht via BenutzerSeite (oder natürlich einfach direkt verbessern) - die Usability dieses Projekts sollte sehr gut werden...
Dieser Artikel soll eine möglichst gut chronologische Sortierung haben, also:
Einführung ... erste Schritte ... Tests ... Analyse ... stabiler Betrieb ... Verfeinerung / letzte Schritte (Expertise-Details).
Basics
Hardware
Neben den bekannten Hardware-Dongles gibt es Selbstbaulösungen in Form eines SIGNALduino, CUL oder JeeLink.
Diese unterscheiden sich in verschiedener Hinsicht:
- Sendemodul (SIGNALduino/CUL -> CC1101; JeeLink -> RF12B) [1]
- Modulationsverfahren (OOK, ASK/FSK)
- Frequenzband (433 MHz, 868 MHz)
(bei SIGNALduino / CUL kann manche Hardware - z.B. nanoCUL - da hardware-kompatibel, mit Projektaktivitäten von CUL oder SIGNALduino betrieben/firmware-geflasht werden; evt. ist es sogar außerdem empfehlenswert, mehrere baugleiche Geräte zu haben, um Support für SIGNALduino und CUL gleichzeitig verfügbar zu haben - evt. auch weitere Geräte mit unterschiedlichen Frequenzen: 433/868)
Frequenzbereich
Für die funkbasierte Heimautomation kommen im Wesentlichen zwei Frequenzbänder in Frage: 433 und 868 MHz. Die meisten Geräte haben auf der Rückseite ein Typenschild, auf dem das Frequenzband ausgewiesen ist.
Dann gibt es noch 2,4 GHz (WLAN, Bluetooth, Funkmaus-Chipsätze...) und 5GHz (WLAN...), diese Frequenzbänder werden in diesem Artikel aber nicht betrachtet.
Modulationsverfahren
So, wie vom Rundfunk (AM/FM) her bekannt, kennt man auch bei 433/868 MHz verschiedene Modulationsverfahren.
- Das Signal des Senders wird auf der angegebenen Frequenz ein-/ausgeschaltet um die Dateninformationen zu übermitteln.
- Der Sender überträgt den Datenstrom indem, ausgehend von der Trägerfrequenz, zwischen Frequenzen (z.B. Frequenz-Frequenzhub, Frequenz+Frequenzhub) hin- und hergeschaltet wird. Dieses Verfahren kennt verschiedene Ausprägungen: 2-FSK, 4-FSK, GFSK (Details siehe hier).
Encoding oder auch Leitungscode
Die Art und Weise wie dieses Signal interpretiert wird, hängt wiederum vom Encoding ab. Dazu sei auf die nachfolgenden Quellen verwiesen.
Je nach verwendetem Encoding wird ggf. mehr als 1 Übertragungs-Bit für ein Datenbit benötigt. Der Empfänger erwartet z.B. einen Bitwechsel zu einem bestimmten Zeitpunkt. Eine Abfolge
- 100 (short high, long low) wird als 0
- 110 (long high, short low) wird als 1
interpretiert.
Im FHEM-Forum gibt es viele freundliche Helfer, die Euch bei Bedarf den richtigen Weg weisen.
Signalstruktur
Ein typischer Aufbau einer Signalstruktur sieht z.B. so aus
| Pause | Sync | Pause | Daten |
- eine größere Pause zur Trennung der Sequenzen
- ein Sync-Block mit dem sich der Empfänger auf den Sender einstellt
- eine Pause um Sync und Daten zu trennen
- die eigentlichen, zu übertragenden Daten.
Es müssen nicht immer alle Bestandteile in der übertragenen Signalstruktur vorkommen (Details siehe auch Datenpräambel oder auch Syncword).
Die Sequenz wird ggf. mehrfach wiederholt
| Pause | Sync | Pause | Daten | Pause | Sync | Pause | Daten | Pause | Sync | Pause | Daten | ...
Protokoll
Das ist der herstellerspezifische Teil des Signalstroms - die Daten. Hersteller haben i.d.R. ihre eigene Definition der übertragenen Datenströme. Teils werden feste Code-Sequenzen übertragen, es gibt aber auch rollierende Codes (Engl.: Rolling Codes) bei denen sich die Daten bei jeder Übertragung ändern (Fremd-Manipulations-Sicherheit).
Mit etwas Glück erkennt z.B. SIGNALduino bereits das Protokoll, damit den Hersteller und legt automatisch ein passendes Device in FHEM an. Manchmal gibt es auch Fehlinterpretationen und das vermeintlich bekannte Device entpuppt sich als etwas anderes (Statement aus dem Forum: "Lösung war, wo Dooya drauf steht muss nicht immer Dooya drin stecken.").
Wie fange ich an?
Recherche
Sucht im Internet nach Informationen zu dem fraglichen Device. Zu bekannten Devices sollten sich Informationen finden lassen, die einem weiter helfen. Solltet Ihr fündig werden, verfolgt die Hinweise, wie diese Devices in FHEM eingebunden werden können.
Evt. haben auch konkrete verwandte Projekte bereits Protokoll-Informationen über das Gerät, z.B.:
Wenn sich nichts Verwertbares finden lässt, geht's mit dem nächsten Abschnitt weiter.
Ansatz 1 - Versuchen
Einfach probieren: Bau Dir einen SIGNALduino für das passende Frequenzband (die 433 oder 868 MHz-Variante des CC1101). Stelle im SIGNALduino-Setting die Frequenz auf die genannte ein (durch den Befehl cc1101_freq = 433.000 oder 868.000) und die Bandbreite auf das Maximum (cc1101_bWidth = 325 kHz bzw. 650 kHz). Jetzt noch das Attribut verbose auf 5 setzen und dann das FHEM-log (tail -f fhem-yyyy-mm.log) beobachten.
Ist ein Gerät in Reichweite, das regelmäßig etwas sendet (z.B. ein Funkthermometer), sollte hin und wieder etwas empfangen werden. Wenn autocreate aktiv ist, werden auf Basis der erkannten, bekannten Funkprotokolle automatisch neue Devices angelegt (dabei können auch diverse Funkthermometer der Nachbarschaft auftauchen).
Ist es ein Gerät, das sich über eine Fernbedienung steuern lässt: Eine Taste betätigen und hoffen, dass sich im FHEM-Log etwas tut. Auch hier gilt: Handelt es sich um ein bekanntes Funkprotokoll, wird automatisch ein Device angelegt, allerdings nur eines für die Gerätefamilie. Bei Baumarkt-Funksteckdosen z.B. nur das erste gefundene. Die anderen müsst Ihr manuell anlegen und die entsprechenden Codes zur Identifikation der einzelnen Steckdosen anpassen (schaut z.B. hier nach: Intertechno_Code_Berechnung).
Solltet Ihr mit diesem Ansatz Erfolg haben, ist das schon mal gut - Euer Gerät sendet ein bekanntes Protokoll und wird unterstützt.
Solltet Ihr etwas empfangen (MC, MS, MU), aber keine neuen Devices sehen, wird Euer Gerät möglicherweise noch nicht unterstützt. Jetzt gibt es zwei Varianten
- es handelt sich um ein neues, noch nicht bekanntes Protokoll -> postet einen Log-Ausschnitt auf github wie im SIGNALduino-Wiki vorgeschlagen)
- es handelt sich um etwas proprietäres, altes oder ähnlich kompliziertes (nicht aufgeben, weiterlesen)
Ansatz 2 - Aufschrauben
Fernbedienung aufschrauben, schauen welcher Chip dort verbaut ist. Endgerät/Device aufschrauben, schauen welcher Chip dort verbaut ist.
Das Teil ist zu klein? Folgende Möglichkeiten:
- so im Winkel gegen ein Lampenlicht halten, dass man die Schrift besonders gut lesen kann
- abfotografieren und das Foto vergrößern bis Ihr den Aufdruck lesen könnt
Danach folgt dann Internet-Suchmaschine und das Studium der zugehörigen Data Sheets der Chips.
Das gibt Euch weitere Anhaltspunkte zum Modulationsverfahren, den Frequenzen und Optionen welche diese Chips unterstützen.
Wenn die Grundsatzfrage geklärt ist, ergeben sich die ersten Handlungsoptionen
- OOK-Modulation -> SIGNALduino
- ASK/FSK -> Selbstbau_CUL oder JeeLink
Die Devices senden/empfangen nicht notwendigerweise auf 433 oder 868 MHz, sondern auf Frequenzen "knapp daneben", das kann z.B. bis zu 870 MHz hochgehen. Darüber, welche Frequenz es genau ist, gibt möglicherweise der verbaute Quarz Auskunft. Meist klein, silber mit einer Gravur wie z.B. 6,70 MHz versehen. Mit Hilfe der Spezifikationen (Frequenzteiler, ...) im Datenblatt des daneben verbauten Chips lässt sich dann die tatsächliche Sende- bzw. Empfangsfrequenz errechnen.
Ansatz 3 - Messen
Ihr nutzt einen Spektrumanalysator. Es gibt verschiedene preisgünstige Ansätze.
- Zum einen könnt Ihr den nrfmon-Ansatz verfolgen (siehe hier). Tipp: bestellt Euch direkt genug Material um zwei zu bauen, denn die RF12demo kann als Sender und Empfänger genutzt werden. Damit lässt sich direkt verifizieren, dass Euer RFM12B-Device wirklich sendet/empfängt.
- Der andere Ansatz nutzt einen DVB-T-Stick (siehe z.B. hier. Es gibt aber viele Internet-Suchmaschine-Treffer unter dem Stichwort SDR. Außerdem ein konkretes Projekt: rtl_433.
- Mein persönlicher Favorit ist der Universal Radio Hacker. Mit dem war ich in der Lage, mittels RTL-SDR-Stick nicht nur Sequenzen mitzuschneiden sondern auch direkt zu analysieren.
Wieso überhaupt so kompliziert? OOK nutzt nur eine Frequenz, FSK zwei, vier, je nach Variante. Es kann auch vorkommen (so wie bei mir), dass ein FSK-Device auf einen OOK-Sender anspricht. Der Grund dafür sind Oberwellen die mit dem Ein-/Auschalten der Frequenz einher gehen.
Die Spektrumanalyse gibt Aufschluss über
- das Modulationsverfahren (OOK vs. FSK) sowie
- die relevante(n) Frequenz(en)
SIGNALduino - OOK
Dieses Kapitel geht davon aus, dass ihr einen SIGNALduino für alle weiteren Schritte nutzt.
Log-Meldungen
Der SIGNALduino empfängt die Rohdaten, ermittelt identische Zeitscheiben und ordnet diese den Zahlen 0-7 zu (P0...P7). Ein negativer Zahlenwert bedeutet "kein Empfang" und ein positiver "Signal empfangen". Damit lässt sich der Datenstrom analysieren und für das Senden auch wieder generieren.
Die folgenden Pulslängen-Zahlen stehen für Mikrosekunden.
P0=-13020;P1=15916;P2=-398;P3=415;P4=4008;P5=-794;P6=812;D=01232323232323232323232324532653265353532653262653265326 26262626265353532653265326532653535326265353535353265353532653262653265353265353535353535353265326;
Was bedeutet D=012323...?
- 0 -> P0=-13020 => 13.020 Mikrosekunden Pause
- 1 -> P1=15916 => 15.916 Mikrosekunden Signal
- 2 -> P2=-398 => 398 Mikrosekunden Pause
- 3 -> P3=415 => 415 Mikrosekunden Signal
- 2 -> P2=-398 => 398 Mikrosekunden Pause
- 3 -> P3=415 => 415 Mikrosekunden Signal
- ...
Tip: um hier schnell zu einem guten Analyse-Ergebnis zu kommen, sind einige verfügbare Beispiel-Zeilen sinnvoll - hier könnte folgendes hilfreich sein:
Bei Geräten, die nicht on-demand (Knopfdruck) Funk-Aktivität generieren können:
Nicht langwierig auf das jeweils nächste verzögerte Intervall der Funk-Aktivität des Geräts warten, sondern stattdessen mehrfach die Geräte-Batterien erneut wieder einsetzen, so dass (hoffentlich) das Gerät immer eine erste Funk-Aktivität sendet, die:
- Log-Zeitstempelmäßig genau erkennbar ist
- hoffentlich immer gleich/ähnlich ist --> gute Analyse-Grundlage
Damit dürfte die Funk-Aktivität hinsichtlich Empfangsstärke, Trägerfrequenz etc. leichter festnagelbar sein.
Frequenz ermitteln
Das folgende Beispiel geht davon aus, dass Ihr im 868 MHz-Band unterwegs seid. Bei 433 MHz könnt Ihr in gleicher Weise vorgehen.
Fangt damit an, dass Ihr den CC101 mittels set-Command cc1101_freq auf 868.000, cc1101_bWidth auf 650 und cc11=1_sens auf 8 einstellt. Kontrollieren könnt Ihr das durch get ccconf
. Die Bandbreite bWidth gibt an wie groß der Empfangsbereich ist. Bei 650 kHz sind das z.B. +/- 325 kHz, also der Bereich von 867.675 bis 868.325 MHz.
Wenn ihr etwas empfangt ist das ein Ansatzpunkt. Anderfalls könnt Ihr die cc1101_freq in 200 kHz-Schritten (868.200, 868.400 ...) erhöhen und das Frequenzband auf diese Art und Weise absuchen. Ein Hinweis an der Stelle: Im FHEM-Log folgt bei den SIGNALduino-Einträgen nach dem Datenteil D= die Empfangsstärke R=. Damit könnt Ihr feststellen, ob Ihr Euch der Sendefrequenz nähert oder entfernt.
Wenn Ihr nun Frequenzen gefunden habt bei denen Ihr etwas empfangt, dann könnt Ihr die bWidth jeweils halbieren und den Bereich, in dem etwas empfangen wurde, mit halbierter Frequenz-Schrittweite weiter durchforsten. Das macht Ihr so lange, bis bWidth bei 58 kHz angekommen ist. Damit sollte sich die gesuchte Trägerfrequenz herauskristallisieren.
Eingrenzung - Selektiver Empfang
Am sichersten geht man selektiv vor - einen Message-Typ nach dem anderen testen. Im SIGNALduino kann man über das set-Command disableMessagetype
die Interpretation als MC, MS und MU selektiv ausschalten. Man kann mit MC beginnen und danach beobachten, ob es bei aktivem MS + MU Dekoder jeweils nur eine Art von Nachrichten gibt.
Sobald man sieht, dass die Meldungen im FHEM-Log wechseln, die Message-Typen MS, MU bzw. MC mit nur einem aktiven Dekoder aufzeichnen.
Das sollte Anhaltspunkte geben worauf der S'duino am Besten reagiert.
Eingrenzung - Log-Analyse via regex
Wenn man schon ziemlich genau weiß, wie das Message-Pattern des relevanten Geräts aussieht, dann kann man sich folgendermaßen sehr elegant und schnell viele weitere zu diesem Gerät gehörige Aktivitäten aus dem Log fischen, ohne sehr störenden Traffic von anderen Geräten mit dabei zu haben: z.B.:
tail -f log/fhem-2018-11.log|grep "sduino.*msg READ: .*=-4...;"
um sich alle Pattern eines Geräts rauszufischen, bei dem man weiß, dass dessen Sende-Traffic das hinreichend charakteristische Merkmal besitzt, einen Low-Puls mit +- 4000us Länge zu haben:
sduino433/msg READ: MU;P0=-956;P1=450;P2=-1987;P3=-4212;P4=96;P6=-304;D=01212121212121312131212131312121213131312131313431316;CP=1;R=224;
Anmerkung: dies ist natürlich mit einem On-Demand-beherrschbaren Gerät (z.B. Fernbedienung, oder Batterie-basiertes Außerbetriebsetzen) kein Problem: hier kann man direkt live (aktueller Zeitpunkt!) nachvollziehen, ob die aktuelle Regex-Filterung tatsächlich Geräte-Aktivität richtig herausfischt (oder eben dummerweise nicht!). Jedoch bei nicht so leicht kontrollierbaren Geräten (intervall-mäßiges Senden, z.B. Klima-Sensoren, oder noch blöder, nur vereinzeltes Senden, z.B. Schwellwert-Sensoren, oder nicht direkt zugängliche Geräte) muss man natürlich den Regex möglichst wenig strikt formulieren, um sicherzustellen, dass man keine im Log abgelegte Aktivität dieses Geräts fälschlicherweise total übersieht/ignoriert.
Variationen
Solltet Ihr verschiedene Fernbedienungen für die Produktfamilie besitzen oder so wie ich eine die 8 Rolllädenmotoren bedienen kann, könnt Ihr bei nicht dokumentierten Protokollen trotzdem die Funktion der einzelnen Bytes herausarbeiten.
Spielt jede Tastenkombination durch, extrahiert die Meldungen aus dem FHEM-Log und legt sie in separaten Dateien ab die ihr z.B. mit Motor, Richtung, Fernbedienung kennzeichnet.
Signal analysieren
Habt Ihr nun den Punkt erreicht an dem Ihr reproduzierbar (hinreichend stabil erfasste) (Teil-)Code-Sequenzen (oft in mehrfacher, identischer Wiederholung) im FHEM-Log seht, geht es ans Entschlüsseln. Auch hier wieder der einfache Fall: SIGNALduino kennt den Hersteller bzw. Device-Typ schon und legt automatisch ein FHEM-Device an (da das aber öfter nicht der Fall sein wird, muss man hier weiterarbeiten).
Wenn ein Signal demoduliert wurde ist man den Bits und Bytes schon einen Schritt näher gekommen.
Gehen wir wieder von unserem Beispiel aus:
P0=-13020;P1=15916;P2=-398;P3=415;P4=4008;P5=-794;P6=812;D=01232323232323232323232324532653265353532653262653265326 26262626265353532653265326532653535326265353535353265353532653262653265353265353535353535353265326;
Wie ist diese Sequenz zu interpretieren?
Anhand der anfänglich gelisteten Puls-Beschreibungen Px= (Aktiv-Indikator/Dauer):
- Es startet mit einer Pause D=0123232323232
- gefolgt von einem Signal D=0123232323232 in der Länge von ca. 16 ms (15916 µs).
- danach folgt ein Sync-Block D=0123232323232... bei dem jeweils Pärchen von 400 µs Pause/400 µs Signal wiederholt werden.
- Sync- und Datenteil sind durch einen Puls von 4 ms [P4=4008] getrennt D=0123232323232323232323232453265
- gefolgt vom Datenteil D=0123232323232323232323232453265....
Beim Datenteil wird es etwas komplizierter. Hier sind immer ein kurzer (2 oder 3) und ein langer (5 oder 6) Wert kombiniert. Folglich muss man bei der Interpretation zwischen Aktiv-Indikator (Vorzeichen) und Dauer differenzieren. Ein Pärchen ist immer 1.200 µs lang. In der Mitte dieser Zeitscheibe kann der übertragene Wert folglich eine Pause oder ein Signal sein.
Beispiel: Den Vorspann
P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324
(bestehend aus Puls-Beschreibungen und initialer Puls-Aktivität) lassen wir mal außen vor und konzentrieren uns auf den nachfolgenden echten Nutz-Daten-Teil (hinsichtlich dessen logischer Protokoll-Umformung hin zur finalen Nutz-Datenwort-Sequenz):
53265326535326535326265353262653265353535326265353265326262653265326265353535353532653535353262653265353265353535353535353532626 (rohe Abfolge der Puls-Typen)
lSsLlSsLlSlSsLlSlSsLsLlSlSsLsLlSsLlSlSlSlSsLsLlSlSsLlSsLsLsLlSsLlSsLsLlSlSlSlSlSlSsLlSlSlSlSsLsLlSsLlSlSsLlSlSlSlSlSlSlSlSlSsLsL (als sSlL-Notation)
1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 (als Bitfolge)
10101101 10011001 01111001 10100010 10011111 10111100 10110111 11111100 (Gruppierung auf Bit-Datenworte)
AD99 79A2 9FBC B7FC (als Hex-Datenworte)
Die Analyse basiert auf folgenden Annahmen (mit Beispiels-Werten)
- Mapping von Puls-Werten auf logische Zustände: wenn 800-ter Pulse: Wert kleiner 0 (z.B. -800) ist ein l (long low), größer 0 ist L (long high), wenn 400-ter Pulse: analog, gemapped auf sS (short low/high) - "sSlL-Notation"...
- Weiter angenommen es werden immer 2 Frequenzen/Zustände verglichen (lS => 1 und sL => 0) (ein Gerät hat ja salopp gesagt nicht mehr zu tun als nur 2 Zustände - 0er und 1er Daten-Bits - robust codiert über Funk zu vermitteln - aus diesen Bits ergibt sich dann zusammengefügt ein gesamtes Geräte-Datenwort, welches anschließend in Bit-Bereiche wie Temperatur, Feuchte, Wind zerlegungs-analysiert werden muss, anhand charakteristischer Werte-Veränderungen, die man idealerweise auch direkt in z.B. einem Sensor-LCD-Display erkennen kann)
Abseits-Bemerkung: Sollte man mit dem SIGNALduino ein FSK-Signal empfangen/interpretieren (im Gegensatz zu "normaleren" ASK, OOK), so hängt die Bewertung davon ab, ob man die Sendefrequenz+Frequenzhub oder Sendefrequenz-Frequenzhub empfängt. Die Bedeutung von 0/1 wird dann negiert. FIXME diese Beschreibung ist (mir) zu unklar, eine Verbesserung sollte erarbeitet werden.
Weitere wichtige Tips:
- es ist wohl sinnvoll, zu versuchen, sich evt. an einem längsten Puls (das ist nämlich evt. eine Sync-Pause) zu orientieren, um nachfolgende Bereiche evt. als startendes Bit-Datenpaket identifizieren zu können
- man sollte die Pulsfolge per Textsuche analysieren, in einem Editor/Reader, der Such-Texte in einer Zeile mehrfach farbig markieren kann (less, ...) - bei markiertem Suchtreffer kann man dann Teil-Folgen identifizieren, welche sich deterministisch wiederholen - diese sind dann wohl offensichtlich codierte Bit-Daten, welche es passend zu entschlüsseln gilt
- die identifizierten Merkmale sind dann als ein neues Protokoll (falls kein bereits existierendes Protokoll zu unpräzise formuliert sein sollte!) in
FHEM/lib/signalduino_protocols.hash
hinzuzufügen (Angabe präziser Durchschnittswerte von Basis-Takt, Gesamt-Patternlänge, Puls-Pause-Verhältnisse, ... - Details dieses Protokolls siehe Header dieser Datei), und dann muss einreload 00_SIGNALduino
gemacht werden, um dies zu testen (hier: beim sduino-Device temporär(!! - hoher Platzbedarf...) Attribute verbose 5 und debug 1 setzen!) - für Beispiele einer Protokoll-Implementierung sollte man sich wohl auch die History (entsprechende Commits) im RFFHEM git repository ansehen
- es ist evt. sinnvoll, sich die Verarbeitungskette anhand von Empfang/Senden bereits funktionsfähiger Protokolle / Geräte zu verdeutlichen, bevor man selber loslegt, neue Geräte (Protokolle) zu unterstützen
- richtige Verarbeitung von empfangenen Funk-Pattern (oder in leicht abgeänderter Form derselben) kann man wohl besonders effizient debuggen, indem man sich einen Dummy-SIGNALduino anlegt:
define sduino_dummy SIGNALduino none
In diesen kann man dann die gewünschten zu unterstützenden Pattern einimpfen:
get sduino_dummy raw MC;;LL=-653;;LH=665;;SL=-317;;SH=348;;D=D55B58;;C=330;;L=21;;
Alle Strichpunkte (Semikolon) müssen hierbei jeweils escaped werden (durch Wiederholung), vermutlich da sie in FHEM's Perl-Code-Umgebung sonst als normale sequence points interpretiert würden.
Weitere für einen Test verwendbare Beispiel-Pattern siehe RFFHEM git repository, in Datei: FHEM/14_SD_BELL.pm
.
Wenn alles richtig läuft (weil man es richtig implementiert hat), dann sollte die gesamte Kette von Pattern-Fingerprinting bis hin zu Dispatch an Datenwort-Modul und dortige Verarbeitung bis hin zu einem entsprechend sichtbaren Auftauchen der Device-Aktivitäten/-Autocreate in FHEMWEB Event Monitor page und/oder Log durchlaufen werden.
Steuern
Die empfangenen, im Log ausgewiesenen Sequenzen könnt Ihr als Basis für das Senden verwenden. Relevant sind dabei Puls-Beschreibungen P0...P7 sowie D (Data). Die RSSI-Empfangsstärke wird beim Empfang als R= ausgewiesen. Beim Senden steht R jedoch für die Anzahl der Wiederholungen. Entnehmt die Details und Möglichkeiten bitte der Dokumentation Commands.
Signal-Protokoll-Beschreibung verfeinern
Sobald man bei einem Gerät initial erfolgreich empfangen / dekodieren (/ senden?) konnte, sollte man folgendes noch beachten:
Es ist recht wichtig, dass jede Protokoll-Beschreibung eines Geräte-Signals möglichst präzise Geräte-konforme Werte aufführt:
wenn mehrere Protokoll-Beschreibungen aufgrund von zu ungenauen Werten jeweils als passend betrachtet werden, dann landet das Signal-Pattern (auch) bei falschen Protokoll-Beschreibungen - die weitere Zuordnung (dies ist eine Routing-Entscheidung!) hin zu spezifischen Geräte-Datenwort-FHEM-Modulen ist also gefährdet / sinnlos:
- evt. ganz fehlgeschlagen aufgrund von Falsch-Zuordnung
- viel sinnlose Noise im Log, weil gleich mehrere Pfade angeblich passen und dann "noch nicht supported"-Fehlermeldungen werfen
Mit stark steigender Anzahl von bekannten Protokoll-Beschreibungen dürfte dieses Problem immer schlimmer werden.
Daher sollte man folgendes beachten:
- sicherstellen, dass nicht eine andere - also bereits existierende! - Protokoll-Beschreibung eigentlich die richtige gewesen wäre, welche nur aufgrund von Impräzisionen das aktuelle völlig Protokoll-gleiche Gerät NICHT erkannt hat (zudem: "ähnlich" aussehende Protokolle, die allerdings von klar unterschiedlichen Geräte-Familien erzeugt werden, sollten NICHT in der gleichen Protokoll-Beschreibung zusammengemischt werden, und man sollte diese Abgrenzung dort auch klarstellen: durch Referenz-Hinweise auf entsprechende fast gleiche Protokoll-Beschreibungen dort)
- length_min , length_max möglichst passend restriktiv spezifizieren (also z.B. 12 , 12)
- clockabs-Basistakt-Mittelwert möglichst präzise ermitteln
- ((die Perl-Demodulations-Implementierung - in
00_SIGNALduino.pm
etc. - ebenfalls auf möglichst restriktive Checks / Wertebereiche trimmen))
Ermittlung eines präzisen clockabs-Basistakt-Mittelwerts dürfte folgendermaßen gut machbar sein:
- einige Geräte-Pattern aus dem Log fischen
- dort die clockabs-Werte suchen (
CP=x
verweist darauf) - aus diesen dann einen Mittelwert bilden, damit man die größte Präzision erreicht
- evt. sogar längere (Sync-)Pulse (z.B.: 15x clockabs Low, 1x clockabs High) heranziehen, um durch Mittelung (+ Teilung) über viele dieser z.B. 15x wiederholten Pulslängen einen daraus resultierend maximal präzisen clockabs-Basistakt-Mittelwert zu ermitteln
- evt. ist es auch hilfreich, den im Gerät verbauten Quarz zu berücksichtigen - u.U. lässt sich hieraus (falls eine solche Verarbeitung im Gerät tatsächlich Timer-mäßig relevant sein sollte!) ein sehr präziser da "mechanisch" passender Puls-Takt-Wert ermitteln (Pseudo-Beispiel:
(1 / 8MHz) * 2048 [digitaler Teiler] = 0.256ms == 256us
); wobei der mechanische Gerätetakt evt. doch erstaunlich anders sein könnte als die von SIGNALduino erfassten Werte (inwiefern das dann hinsichtlich Rx-/Tx-Präzision relevant ist - wer weiß...)
Development / patch submission
Es ist evt. empfehlenswert, auf github einen eigenen Fork des RFFHEM-Upstream-Repositories zu erstellen - dann kann man dort seine Entwicklung durchführen:
- Änderungen durchführen (im korrekten Branch)
- alles committen
controls_signalduino.txt
updaten (wird via github actions automatisch aktualisiert), sonst kann nicht über den update Befehl installiert werden!- mit dem üblichen FHEM-Befehl (
update all ...
, aber eben sinnigerweise unter Angabe der URL seines eigenen Repositories!) seine eigenen Änderungen jeweils korrekt verwaltend und updatend austesten - evt. hier jeweils
reload BEARBEITETES_MODUL
nötig - wenn das alles passt, hat man bereits seinen eigenen Fork fix und fertig (und authentisch getestet) und kann somit direkt - evt. nach einem bereinigenden
git rebase -i @{u}
- einen Pull Request daraus machen (anders ausgedrückt: "direkt kontext-integrierte Entwicklung", "am Puls der Zeit", "mit voller Tool-Unterstützung"). Dies am besten vollständig Automatisierungs-gekapselt durch ein Shell-Script (FIXME: am besten hier einfach direkt hier präsentieren?), welches an FHEM denupdate all ...
request schickt (über telnet, Port 7072) und denreload BEARBEITETES_MODUL
durchführt.
SIGNALduino - FSK
Dieses Kapitel geht davon aus, dass ihr einen SIGNALduino für alle weiteren Schritte nutzt.
Aktuell laufen Bestrebungen, den SIGNALduino FSK-fähig zu machen: siehe FSK mit SIGNALduino (vormals https://forum.fhem.de/index.php/topic,82379.0.html)
Die Summary der CC1101-Settings findet ihr hier.
FSK Senden
Die ersten Bits des CC1101-Register 12 MDMCFG2 bestimmen die Übertragungsweise: 000 = 2-FSK 001 = GFSK 011 = ASK/OOK 100 = 4-FSK
Schaut Euch den aktuellen Registerinhalt an, bevor Ihr ihn ändert. Am einfachsten geht das über
get <mysduino> ccreg 99
Ihr müsst beim angezeigten Wert die ersten drei Bits entsprechend abändern, also z.B. aus 0x30 dann 0x10 für GFSK statt OOK machen.
Das Register wird über
set <mysduino> raw W1410
abgeändert (bitte beachtet das Offset von 0x02 für das Beschreiben eines Registers, 14 adressiert Register 12).
Nun könnt Ihr FSK senden. Das im URH angezeigte Spektrum sollte nun zwei Spitzen aufweisen. Ihr seht daneben vermutlich auch weitere kleine links und rechts daneben. Das liegt daran, dass es Oberwellen gibt. Bei 2-FSK sind dies mehr als bei dem geglätteten GFSK.
Sendefrequenz und Frequenzhub
Bei OOK wird das Funksignal ein- und ausgeschaltet, um die bits als 0 und 1 darzustellen. Bei FSK sieht das anders aus. Zur Übertragung wird ein permanentes Signal ausgestrahlt; die Darstellung der bits 0 und 1 erfolgt durch Erniedrigung bzw. Erhöhung der Frequenz. Folglich gilt es sowohl die Trägerfrequenz als auch den Frequenzhub zu ermitteln. Das bit 0 wird i.d.R. durch Trägerfrequenz minus Hub, das bit 1 durch Trägerfrequenz plus Hub dargestellt.
In diesem Beispielspektrum eines FSK-Signals ist ersichtlich, dass die untere Frequenz bei ca. 868,233 Mhz und die obere bei ca. 868,281 Mhz liegt. Die Trägerfrequenz liegt folglich in der Mitte bei 868,257 MHz und der Frequenzhub beträgt ca. 24 kHz.
Ermittlung der Frequenzen
Wie im OOK-Kapitel bereits angesprochen, ist eine Messung mit Hilfe eines SDR-Sticks hilfreich. Doch Vorsicht - diese Sticks sind oftmals nicht geeicht und die angezeigte Frequenz wird "relativ" genau gemessen. Was aber hilft ist ein Vergleich Original/Kopie. Messt mit dem SDR-Stick unter Nutzung eines Programms wie URH die Frequenzen, sendet mit dem SDUINO ebenfalls ein Signal auf einer von Euch vorgegebenen Frequenz. Nehmt als Basis für den Ver- bzw. Abgleich die von Euch im SDUINO vorgegebene Frequenz. Die ist für die weiteren Aktivitäten relevant. Die Abweichung könnt Ihr in der URH-Software zur Frequenzkorrektur vorgeben, dann werden identische Werte angezeigt.
Hub
Da hilft Euch das RF Studio für den CC1101. Der darin ermittelte Wert ist in das Register 15 DEVIATN zu übertragen. Bei 25 kHz Hub ist das der Wert 40, der mittels
set <mysduino> raw W1740
an den CC1101 des SDUINO übermittelt wird.
Wenn Ihr soweit seid, sollten die Funksignale der Original-Fernbedienung und Eures SDUINO ähneln.
Baudrate
Beim SDUINO übernimmt der CC1101 die Funktion eines Modems. Die Signalaufbereitung bzw. -erzeugung erfolgt im Arduino. Das können wir auch für das Senden von FSK Signalen nutzen. Der CC1101 bietet eine Fülle weiterer Optionen (Sync, FIFO etc.), die aber eher für Spezialisten geeignet sind.
Welche Baudrate soll/muss ich angeben? Zunächst mal gilt es folgende Teilstrecken zu unterscheiden: FHEM <-> Arduino <-> CC1101 <-> Sendesignal
Die Baudrate zwischen FHEM und dem Arduino wird in FHEM vorgegeben. Die für den CC1101 angegebene und mittels get <myduino> ccconf
ausgegebene Baudrate ist die zwischen dem Arduino und dem CC1101. Mit dieser Baudrate wird das Funksignal gesampled.
Beim Empfang interpretiert der Arduino den Signalpegel und erkennt die Übergänge zwischen 0 und 1. Es wird die Dauer des jeweiligen Signals ermittelt und einem Parameter (Puls?) 0-7 zugeordnet. Auf diese Weise wird die gesamte empfangene Codesequenz beschrieben.
Die Baudrate lässt sich im CC1101 nur bedingt präzise einstellen, da dafür nur ein Byte zur Verfügung steht.
Ich habe bei der obigen Sequenz die Baudrate bzw. SCLK aus dem Vorspann (Preamble) ermittelt und bin auf 2.482 Baud gekommen. Für die Übertragung habe ich aber die 10fache Rate verwendet, um die Steuerung des Zustandes 0/1 dem Arduino und nicht dem CC1101 zu überlassen. Statt einer 0 werden dann halt 10x 0 übertragen. Auf Sendeseite ändert sich dadurch nichts. Die Software URH arbeitet ähnlich. Das Signal wird z.B. mit 1 MHz gesampled. Um auf die ermittelte Baudrate und eine reale Darstellung zu kommen, gebe ich 402 Samples/Symbol (Symbol=bit) ein.
Das Ergebnis:
Codesequenzen
Die Interpretaion des low- und high-Zustandes hängt von der Sende- und Empfangsfrequenz ab. Wenn Ihr im OOK-Modus Sequenzen mitgeschnitten habt werden die möglicherweise anders interpretiert als die mittels FSK empfangenen. Deshalb: Sequenzen mit der Original-Fernbedienung neu erzeugen und mitschneiden. Achtet dabei darauf, dass diese lang genug sind, um das komplette Steuerungssignal mitzuschneiden. Die Preamble ist recht auffällig (bei mir 01232323 ...). Die wiederholt sich nach dem eigentlichen Steuerungssignal. Ab hier könnt Ihr also abschneiden. Ferner empfiehlt sich, das mitgeschnittene Signal zu dekodieren und in Hex darzustellen. Dann erkennt Ihr, ob identische Inhalte/Sequenzen mitgeschnitten wurden. Das trennt die Spreu vom Weizen.
Damit konnte ich mein Problem meines unbekannten Funkprotokolls (RIO-Fernbedienung) letztendlich lösen.
Konfiguration
Last but not least meine Konfiguration: SDUINO Firmware war die Version v3.4.1_dev_21.12
Register-Settings:
- Trägerfrequenz: 868.302 MHz
- Deviation: 25 kHz
- Bandwidth: 58 kHz
- Baudrate: 24.795 kBaud
- Modulation: GFSK
ccregAll: ccreg 00: 0D 2E 2D 47 D3 91 3D 04 32 00 00 06 00 21 65 6F ccreg 10: F9 F4 18 23 B9 40 07 00 18 14 6C 07 00 91 87 6B ccreg 20: F8 56 11 EF 2D 12 1F 41 00 59 7F 3F 88 31 0B Configuration Register Detail (address, name, value): 0x00 IOCFG2 - 0x0D 0x01 IOCFG1 - 0x2E 0x02 IOCFG0 - 0x2D 0x03 FIFOTHR - 0x47 0x04 SYNC1 - 0xD3 0x05 SYNC0 - 0x91 0x06 PKTLEN - 0x3D 0x07 PKTCTRL1 - 0x04 0x08 PKTCTRL0 - 0x32 0x09 ADDR - 0x00 0x0A CHANNR - 0x00 0x0B FSCTRL1 - 0x06 0x0C FSCTRL0 - 0x00 0x0D FREQ2 - 0x21 0x0E FREQ1 - 0x65 0x0F FREQ0 - 0x6F 0x10 MDMCFG4 - 0xF9 0x11 MDMCFG3 - 0xF4 0x12 MDMCFG2 - 0x18 0x13 MDMCFG1 - 0x23 0x14 MDMCFG0 - 0xB9 0x15 DEVIATN - 0x40 0x16 MCSM2 - 0x07 0x17 MCSM1 - 0x00 0x18 MCSM0 - 0x18 0x19 FOCCFG - 0x14 0x1A BSCFG - 0x6C 0x1B AGCCTRL2 - 0x07 0x1C AGCCTRL1 - 0x00 0x1D AGCCTRL0 - 0x91 0x1E WOREVT1 - 0x87 0x1F WOREVT0 - 0x6B 0x20 WORCTRL - 0xF8 0x21 FREND1 - 0x56 0x22 FREND0 - 0x11 0x23 FSCAL3 - 0xEF 0x24 FSCAL2 - 0x2D 0x25 FSCAL1 - 0x12 0x26 FSCAL0 - 0x1F 0x27 RCCTRL1 - 0x41 0x28 RCCTRL0 - 0x00 0x29 FSTEST - 0x59 0x2A PTEST - 0x7F 0x2B AGCTEST - 0x3F 0x2C TEST2 - 0x88 0x2D TEST1 - 0x31 0x2E TEST0 - 0x0B
Finale
Nach Aktivierung der vormals ausgeschalteten Message-Typen im SIGNALduino werden nunmehr SD_Keeloq-Devices angelegt.
Der SIGNALduino erkennt
2020.01.12 14:33:03 4: mySIGNALduino: Parse_MS, Decoded matched MS Protocol id 88 dmsg P88#74D21B18008B48058 length 68 RSSI = -32 2020.01.12 14:33:03 5: mySIGNALduino: Dispatch, P88#74D21B18008B48058, test ungleich: disabled 2020.01.12 14:33:03 5: mySIGNALduino: Dispatch, P88#74D21B18008B48058, -32 dB, dispatch 2020.01.12 14:33:03 5: mySIGNALduino: dispatch P88#74D21B18008B48058 2020.01.12 14:33:04 2: mySIGNALduino: SD_Keeloq_Parse Unknown device unknown with Code 012D100 detected, please define (rawdate=74D21B18008B48058) 2020.01.12 14:33:04 2: autocreate: define SD_Keeloq_012D100 SD_Keeloq 012D100 2020.01.12 14:33:04 2: autocreate: define FileLog_SD_Keeloq_012D100 FileLog ./log/SD_Keeloq_012D100-%Y.log SD_Keeloq_012D100 2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, Matched MS Protocol id 91.1 -> Atlantic security 2020.01.12 14:33:04 5: mySIGNALduino: Parse_MS, Starting demodulation at Position 3 2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, last part pair=2 reconstructed, last bit=0 2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, Matched MS Protocol id 87 -> JAROLIFT 2020.01.12 14:33:04 5: mySIGNALduino: Parse_MS, Starting demodulation at Position 2 2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, last part pair=1 reconstructed, last bit=1 2020.01.12 14:33:04 4: mySIGNALduino: Parse_MS, Matched MS Protocol id 88 -> HCS300/HCS301 2020.01.12 14:33:04 5: mySIGNALduino: Parse_MS, Starting demodulation at Position 2
und routet die Requests an das Modul SD_Keeloq weiter. Der Hinweis auf HCS301 führt auf die richtige Spur. Das analysierte Protokoll KeeLoq ist im Data Sheet des Microchip HCS301 (KeeLoq Code Hopping Encoder) beschrieben. Somit wurde aus einem unbekannten Funkprotokoll letztlich ein bekanntes.
Mittlerweile ist das Protokoll als model enjoy_motors_HS in das Modul SD_Keeloq aufgenommen.
CUL - FSK und Co.
Dieses Kapitel geht davon aus, dass ihr einen CUL für alle weiteren Schritte nutzt.
Es befindet sich aber noch im Aufbau....
FAQ
Woran genau wird erkannt ob ein Signal ShortHigh, bzw ShortLow ist?
Diese Begriffe kommen nur bei der Manchester Codierung zum Einsatz.
Die Bestimmung short High / Low erfolgt einfach dadurch, ob gesendet wird oder ob gerade eine Pause eingelegt wird.
Short und Long wird einfach durch die Kalkulation der Dauer ermittelt.
Die Dauer eines short Intervalles ist in der Regel halb so lang wie die von einem long und entspricht der Taktrate. Bei der ganzen Berechnung müssen natürlich Toleranzen berücksichtigt werden.
Beispiel einer empfangenen Sequenz
P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324
P0, P2 + P5 haben ein negatives Vorzeichen. Damit ist gemeint, dass für eine Zeit von 762µs (P5) kein Signal empfangen wurde (Low). Die positiven sind dann High.
Generell sind die absoluten, gemessenen low-Werte bei Signalduino kürzer als die high-Werte.
Wie bereits ausgeführt, werden für die Daten die Pulse P2, P3, P5 und P6 genutzt. Der Mittelwert [ (P2 + P3 + P5 + P6) / 6 ] der absoluten Werte ergibt 404µs für ein Short und 808µs ein Long (2xShort). Idealisiert werden 400µs angenommen.
Das Umwandeln der Pulse in den Daten in eine "sSlL-Notation" vereinfacht die Erkennung von Mustern (in mehreren Nachrichten variieren auch die Pulse). Dass ein lS=1 und sL=0 entspricht, ist nur eine willkürlich angenommene Arbeitshypothese, die bis dato ganz gute Ergebnisse produziert hat.