Spontaneously received ECMD

Begonnen von NeuFehm, 15 November 2016, 21:03:50

Vorheriges Thema - Nächstes Thema

Dr. Boris Neubert

Du hast eine mit M_Adresse und M_Relais parameterisierte Klassendefinition.

Du baust diese beiden Parameter in den regulären Ausdruck (match) ein, damit dieser nur zutrifft, wenn das Datagramm von M_Adresse und M_Relais kommt.

... match "!M%M_Adresse%M_Relais.\r\n"

Dann hast Du ein Reading, nennen wir es Relaisschaltzustand. Der Wert im Datagramm, der den Schaltzustand wiedergibt, extrahierst Du im postproc und schreibst ihn auf on oder off um, z.B.

reading Relaisschaltzustand postproc { /^!M..(.)\r\n$/; $_= ( $1 ? "on" : "off" ) }

(alles ungetestet, Perl für Fortgeschrittene)



Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

NeuFehm

#31
Ich wollte Dir gerade mein UNLOGISCHES Experiment präsentieren, da lese ich, dass meine Gedanken hierzu gar nicht so falsch sind :)
Schau mal mein Experiment, welches zunächst funktioniert:
reading on match "!M.*\00%M_Relais\001\r\n"
# reading on postproc {ProcessmyECMD($_);}
reading on postproc {}

reading off match "!M.*\00%M_Relais\000\r\n"
# reading off postproc {ProcessmyECMD($_);}
reading off postproc {}


ISt das vlt. sogar richtig richtig?
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

Dr. Boris Neubert

Dran denken, dass \00%M_Relais zu \001 bis \003 auflöst. Das geht so bis \007.

Der Match .* ist zu pauschal, würde daraus .. für zwei Zeichen machen (oder so, habe die Zeichenfolge nicht parat, die Deine Geräte senden).

Im postproc würde ich dann das dritte Zeichen wie in meinem Beispiel rauspopeln und in ein Reading schreiben. Du willst vermutlich nicht zwei Readings on und off, die irgendwelche Werte enthalten, sondern eines, das Dir sagt, ob das Relais on oder off ist.
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

NeuFehm

Bin immer noch etwas schockiert, dass es tatsächlich nur an der classdef und "2 Zeilchen" liegt. Wenn ich mir überlege, wieviele Versuche ich unternommen hab, hier im Forum Hilfe zu erhalten und über welchen Zeitraum. Das hat fast ein Jahr gedauert und bestimmt 50 Stunden verschlungen - auch die der Helfer.

Ich würde manche Mythen in der commandref ausräumen, wie zum beispiel, dass das regex EXAKT mit dem Reading übereinstimmen muss. Das ist falsch. In der classdef werden immer nur REGEX-Vorlagen gespeichert, die dann erst zu den finalen Regex zusammengesetzt werden. Die Vorlagen unterliegen anderen Kriterien, wie die finalen Regex. So kann man beispielsweise das Vorlagen-Regex grundsätzlich nicht mit einem Online-Regex-Tester prüfen. Um nur ein Irrtum zu nennen.

Ich bin froh, dass Du mir geholfen hast! Das Verständnis der vorgenannten 3 Zeilen hilft mir zunächst zu verstehen, warum das Einbinden von PARAMS in ein Regex überhaupt möglich ist. Die nächste Herausforderung besteht nun darin den Antwortstring "!M(E\001\001\001\r\n" für "on" und "!M(E\001\001\000\r\n" für "off" aufzulösen. Die roten Bereiche sind die PARAMS, die grünen die Antwort für "on" "off".

Wie Du schon an meinem on-match gesehen hast: "!M.*\00%M_Relais\001\r\n" konnte ich nicht schreiben: "!M.*%M_Relais\001\r\n"
Da das Zeichenformat nicht kompatibel ist. Eine Möglichkeit wäre, die PARAMS entsprecchend zu gestalten.

Hier bräuchte ich Dein Tipp: Soll ich statt "40 1" lieber schreiben "( \001"?

Wenn ja, sähe der match so aus:"!M%M_AdresseE.%M_Relais\001\r\n". Außerdem müsste wahrscheinlich das on/off nur gematcht werden also:
"!M%M_AdresseE.%M_Relais.\r\n" und dann später über das postproc ausgewertet werden.
Ich weiß nicht, ob der Punkt für den Octalwert \001 reicht... das wäre dann das nächste Problem.

Kannst Du mir helfen?
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

NeuFehm

#34
So, habe die fhem.cfg umgeschrieben:
define myMModul ECMD serial /dev/ttyUSB0@9600
attr myMModul classdefs MModul=/opt/fhem/MModul.classdef
attr myMModul logTraffic 5
attr myMModul partial 2
attr myMModul split \r\n
attr myMModul verbose 5
define 40Relais1 ECMDDevice MModul ( \001
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero
define 40Relais2 ECMDDevice MModul ( \002
attr 40Relais2 IODev myMModul
attr 40Relais2 room Buero
define 40Relais3 ECMDDevice MModul ( \003
attr 40Relais3 IODev myMModul
attr 40Relais3 room Buero


Dann habe ich in der classdef die "set on"- und "set off"-Befehle entsprechend angepasst:
]
params M_Adresse M_Relais
set on cmd {chr(35).chr(77)."%M_Adresse".chr(69).chr(1)."%M_Relais".chr(1).chr(13).chr(10)}
set off cmd {chr(35).chr(77)."%M_Adresse".chr(69).chr(1)."%M_Relais".chr(0).chr(13).chr(10)}

und auch das match angepasst:

reading on match "!M\%M_AdresseE.%M_Relais\001\r\n"
reading on postproc {}

reading off match "!M\%M_AdresseE.%M_Relais\000\r\n"
reading off postproc {}


Diese Variante funktioniert bereits :)
Wenn Du mir nun noch hlefen könntest, wie ich aus den 2 reading für on und off ein einziges mache,
das wäre super!!!

Folgender Versuch ist gescheitert (die letzten 4 Zeilen gelöscht und dafür diese 2 Zeilen eingefügt):

reading Relaisschaltzustand match "!M\%M_AdresseE.%M_Relais.\r\n"
reading Relaisschaltzustand postproc { /^!M..(.)\r\n$/; $_= ( $1 ? "on" : "off" ) }

Aber verstehe ich auch irgendwie, weil man muss ja sicher noch die \000 und  \001 auswerten,
also wenn  \000 dann off und wenn \001 dann on....
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

NeuFehm

Hallo Boris,

kannst Du mir mal ein Beispiel schreiben, wie man für ein on/off mit einem Reading sorgt?
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

Dr. Boris Neubert

Hallo,

dadurch, dass der eine Parameter jetzt eine öffnende Klammer ist, kannst Du das nicht so im Match verwenden, weil die Klammer als Gruppierungssymbol interpretiert wird. Du kannst stattdessen aber den Oktalkode der Klammer verwenden.

Danach bitte wieder das Log hier posten.

Und bitte kurz beschreiben, aus welchen Zeichen die Antwort besteht und was diese bedeuten. Dann kann ich die passende Regex vorschlagen.

Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

NeuFehm

Hallo Boris, zunächst die Erklärung der Antwort:
"!M(E\001\001\r\n"
! = "Antwort", Befehle erkennt man am "#"
M = Identifikations-Buchstabe vom M-Modul (Relaiskarten mit 8 Relais)
( = Adresse des M-Moduls, könnte man auch so ändern, dass keine ( vorkommt
E = Betriebsart, hier ein/aus
\001 = Relaisnummer, hier Relais 1
\001 = Relaiskontaktstatus 001=an, 000 ist aus
\r = erster Teil des Befehlabschlusses
\n = zweiter Teil des Befehlabschlusses

Beispiel: 4. Relais von M-Modul mit der Adresse ( an schalten:
#M(E\004\001\r\n... darauf antwortet das M-Modul
!M(E\004\001\r\n
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

Dr. Boris Neubert

Konfiguration:

define myMModul ECMD serial /dev/ttyUSB0@9600
attr myMModul classdefs MModul=/opt/fhem/MModul.classdef
attr myMModul logTraffic 5
attr myMModul partial 2
attr myMModul split \r\n
attr myMModul verbose 5
define 40Relais1 ECMDDevice MModul \050 \001
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero
define 40Relais2 ECMDDevice MModul \050 \002
attr 40Relais2 IODev myMModul
attr 40Relais2 room Buero
define 40Relais3 ECMDDevice MModul \050 \003
attr 40Relais3 IODev myMModul
attr 40Relais3 room Buero


Klassendefinition:

params M_Adresse M_Relais
set on cmd { "#M%M_AdresseE\001%M_Relais\001\r\n" }
set off cmd { "#M%M_AdresseE\001%M_Relais\000\r\n" }
reading onoff match "!M%M_AdresseE%M_Relais.\r\n"
reading onoff postproc { /^!M%M_AdresseE%M_Relais(.)\r\n$/; $_= ( $1 eq "\001" ? "on" : "off" ) }



ungetestet
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!