FHEM Forum

FHEM - Hausautomations-Systeme => Sonstige Systeme => Thema gestartet von: NeuFehm am 15 November 2016, 21:03:50

Titel: Spontaneously received ECMD
Beitrag von: NeuFehm am 15 November 2016, 21:03:50
Ich möchte gern den "spontanen Empfang", verursacht durch einen Schalter im BUS auf den das ECMD lauscht, verarbeiten.

Zunächst der Auszug aus dem Logfile


# Zunächst sendet der Schalter (Hardware) "#M(E\001\001\001\r\n" und das ECMD empängt:
2016.11.15 20:50:35 5: myMModul: Spontaneously received "#"
2016.11.15 20:50:35 5: myMModul dispatch #
2016.11.15 20:50:35 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.15 20:50:35 5: myMModul dispatch M(E

# außerdem meldet das Relais im Bus (Hardware) die Bestätigung, statt # ein !, also "!M(E\001\001\001\r\n" welches ECMD gleichzeitig empfängt
2016.11.15 20:50:35 5: myMModul: Spontaneously received "!"
2016.11.15 20:50:35 5: myMModul dispatch !
2016.11.15 20:50:35 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.15 20:50:35 5: myMModul dispatch M(E


und hier die dazugehörige Definition in der fhem.cfg
define myMModul ECMD serial /dev/ttyUSB0@9600
attr myMModul classdefs MModul=/opt/fhem/MModul.classdef
attr myMModul partial 2
attr myMModul verbose 5


Nun ist meine Grundüberlegung die, in der MModul.classdef zunächst ein reading zu eröffnen und dieses anschließend mit postproc zu verarbeiten:

reading TModul match "!M.*\n"
postproc TModul {}


Ist mein Ansatz richtig?
Wenn ja, wie müsste das dazugehörige Perl aussehen?

Kann mir jemand eine Richtung geben, damit ich gezielter unterwegs bin?
Vielen lieben Dank vorab.

PS.: Die "Teilung" am # oder ! ist zufällig. Es ist auch schon bei "!M" oder "!M(E" geteilt wurden. Nie waren es allerdings mehr als 2 "Fragmente"

Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 15 November 2016, 21:47:12
Mir fiel soeben auf

attr myMModul partial 2
hat NUR Auswirkung auf die Antworten des "set on cmd/set off cmd" und leider NICHT auf die spontanen Empfänge.

Logfile:

# Ohne "attr myMModul partial 2" und der Schalterbetätigung (FHEM-Software)
2016.11.15 21:33:20 5: myMModul: sending command "#M(E\001\001\001\r\n"
2016.11.15 21:33:20 5: myMModul: write "#M(E\001\001\001\r\n", expect !M.*\n
2016.11.15 21:33:20 5: SW: 234d28450101010d0a
2016.11.15 21:33:20 5: myMModul: read "!"
2016.11.15 21:33:20 1: myMModul: unexpected answer "!" received (wrote "#M(E\001\001\001\r\n", expected !M.*\n)
2016.11.15 21:33:20 5: myMModul: received answer "!"
2016.11.15 21:33:20 5: myMModul: read "M(E\001\001\001\r\n"
2016.11.15 21:33:20 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.15 21:33:20 5: myMModul dispatch M(E
# mit "attr myMModul partial 2" und der Schalterbetätigung (FHEM-Software)
2016.11.15 21:34:34 5: myMModul: sending command "#M(E\001\001\000\r\n"
2016.11.15 21:34:34 5: myMModul: write "#M(E\001\001\000\r\n", expect !M.*\n
2016.11.15 21:34:34 5: SW: 234d28450101000d0a
2016.11.15 21:34:34 5: myMModul: read "!M(E\001\001\000\r\n"
2016.11.15 21:34:34 5: myMModul: received answer "!M(E\001\001\000\r\n"
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 20 November 2016, 10:59:49
Hallo,

partial funktioniert grundsätzlich auch für spontan empfangene Datagramme - im Code wird gar kein Unterschied gemacht.

Ich habe das Problem jedoch nachstellen können. Die Ursache ist, dass der Anfang des Datagramms auf den regulären Ausdruck hinter expect passt:

2016.11.20 10:53:43 5: myServer: match regex !M.*\n for reading TModul of device myMModul with class MModul

Das irritiert mich sehr: ich verstehe nämlich nicht, warum !M auf den regulären Ausdruck ^!M.*\n$ passt. Hier der Code aus 67_ECMDDevice.pm:

 
if($msg =~ m/^$regex$/) {
    # we found a match
    Log3 $IOhash, 5, "$name: match regex $regex for reading $r of device $d with class $classname";
            ...


Wer gibt mir bitte Nachhilfe?

Viele Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 20 November 2016, 21:12:15
Hallo Boris,
da kann ich Dir noch zu wenig sagen.
Aber ich habe mal als Dateianhang zunächst einmal die Hardware skizziert, damit man alles leichter nachvollziehen kann.

Wenn ich in Fhem ein "set 40Relais1 on" sende, schaltet das Relais 1 vom M-Modul mit M-Modul-Adresse 40.
Analog dazu ein "set 40Relais1 off". Ohne die folgende Anweisung, wird die Antwort des M-Moduls als "spontan" gelistet.
Mit dem Code gibt es keine Fehler, auch wenn vlt. der Code suboptimal ist, da ich den nur blind kopiert habe.

set on expect "!M.*\n"
set on postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}


Meine jetzige Herausforderung besteht in der Erfassung der Anweisung und der Antwort des T-Moduls, wenn ich den Hardware-Taster betätige.
Dann wird der gleiche Code über den Bus gesendet, aber ich habe keine Idee, wie ich den "erfassen/wegordnen" kann.

Meine Idee war zunächst ein fast "identisches" Regex der an/aus-Befehle zu kopieren und daraus ein "reading off" zu machen,
welches am Bus lauscht- Ich schalte über Fhem das Relais an und dachte für den ersten Test das dann per Hardwaretaster auszuschalten.

reading off match "!M.*\n"
reading off postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}


Hier das dazugehörige Log von per Fhem anschalten und per Hardware ausschalten:

2016.11.20 21:06:08 5: myMModul: sending command "#M(E\001\001\001\r\n"
2016.11.20 21:06:08 5: myMModul: write "#M(E\001\001\001\r\n", expect !M.*\n
2016.11.20 21:06:08 5: SW: 234d28450101010d0a
2016.11.20 21:06:08 5: myMModul: read "!M(E\001\001\001\r\n"
2016.11.20 21:06:08 5: myMModul: received answer "!M(E\001\001\001\r\n"

2016.11.20 21:06:30 5: myMModul: read "#"
2016.11.20 21:06:30 5: myMModul: Spontaneously received "#"
2016.11.20 21:06:30 5: myMModul dispatch #
2016.11.20 21:06:30 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.20 21:06:30 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.20 21:06:30 5: myMModul dispatch M(E

2016.11.20 21:06:30 5: myMModul: read "!"
2016.11.20 21:06:30 5: myMModul: Spontaneously received "!"
2016.11.20 21:06:30 5: myMModul dispatch !
2016.11.20 21:06:30 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.20 21:06:30 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.20 21:06:30 5: myMModul dispatch M(E



Auf die Idee, dass partial hier keine Anwendung findet, bin ich gestoßen, als ich mir die Log-Zeiten anschaute.
Laut Partiallogik müsste doch wenigsten 2 Sekunden später geloggt werden. Also er empfängt, wartet 2 Sekunden und
verwirft, wenn er kein Match hat. Aber da alle Fragmente zur gleichen Zeit geloggt werden, denke ich dass hier das Partial nicht greift.


Außerdem ist mir aufgefallen, dass ich nach jedem Neustart den "deleteattr myMModul requestSeparator" immer wieder per fhem-commandozeile setzen muss,
trotz "safe config". Offensichtlich überschreibt eine Routine speziell diesen Wert. Nach evtl. folgender Logik: "wenn "attr requestSeparator" nicht vorhanden, dann füge es in die fhem.cfg ein.... was jedoch nicht berücksichtigt, dass es schon mal vorhanden sein konnte, aber nicht gewünscht ist.

Titel: Antw:Spontaneously received ECMD
Beitrag von: kaihs am 20 November 2016, 22:36:09
Zitat von: Dr. Boris Neubert am 20 November 2016, 10:59:49
if($msg =~ m/^$regex$/) {
       # we found a match
       Log3 $IOhash, 5, "$name: match regex $regex for reading $r of device $d with class $classname";
            ...

Ich bin zwar auch kein Experte, aber wie soll in

m/^$regex$/


zwischen dem $ für Variablensubstitution und dem $ als Regulärenausdruck unterschieden werden?

Evtl. hilft

$regex = qr/!M.*\n/;
if($msg =~ m/^${regex}$/) {
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 21 November 2016, 18:54:14
Hallo,

ich wurde in die Irre geführt von meinem eigenen Testsetup, welches ein LF hinterherschickt.

Ich denke, dass Deine Device-Konfiguration falsch ist. Bitte poste sie hier (ECMD und ECMDDevice). Es sollte darin ein

deleteattr DeinECMD replySeparator
attr DeinECDM partial 2

enthalten sein.

Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 21 November 2016, 19:58:08
Hallo Boris,
deleteattr myMModul requestSeparator und
deleteattr myMModul replySeparator

werden NIE gespeichert und wenn ich die per Hand in die fehm.cfg reinzwinge,
werden sie beim nächsten "save config" wieder entfernt

Aktuelle komplette fhem.cfg

attr global userattr cmdIcon devStateIcon devStateStyle icon sortby webCmd widgetOverride
attr global autoload_undefined_devices 1
attr global logfile ./log/fhem-%Y-%m.log
attr global modpath .
attr global motd Error messages while initializing FHEM:\
attr global statefile ./log/fhem.save
attr global statefile ./log/fhem.save
attr global updateInBackground 1
attr global verbose 3

define telnetPort telnet 7072 global

define WEB FHEMWEB 8083 global
attr WEB JavaScripts codemirror/fhem_codemirror.js
attr WEB editConfig 1

define WEBphone FHEMWEB 8084 global
attr WEBphone JavaScripts codemirror/fhem_codemirror.js
attr WEBphone stylesheetPrefix smallscreen

define WEBtablet FHEMWEB 8085 global
attr WEBtablet JavaScripts codemirror/fhem_codemirror.js
attr WEBtablet stylesheetPrefix touchpad

# Fake FileLog entry, to access the fhem log from FHEMWEB
define Logfile FileLog ./log/fhem-%Y-%m.log fakelog

define autocreate autocreate
attr autocreate filelog ./log/%NAME-%Y.log

define eventTypes eventTypes ./log/eventTypes.txt

# Disable this to avoid looking for new USB devices on startup
define initialUsbCheck notify global:INITIALIZED usb create
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 verbose 5
define 40Relais1 ECMDDevice MModul 40 1
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero

Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 21 November 2016, 20:35:34
Zitat von: NeuFehm am 21 November 2016, 19:58:08
deleteattr myMModul requestSeparator und
deleteattr myMModul replySeparator

werden NIE gespeichert und wenn ich die per Hand in die fehm.cfg reinzwinge,
werden sie beim nächsten "save config" wieder entfernt

Ich kläre nebenan, ob dass ein Bug oder ein Feature ist.

Bitte behilf Dir damit, die Separatoren auf irgendwas zu setzen, was nie vorkommt, z.B.

attr myMModul requestSeparator workaround
attr myMModul replySeparator workaround



Der Rest sieht OK aus. Wenn Du bitte dann wieder einen Auszug aus dem Log posten könntest.

Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 21 November 2016, 20:49:47
myMModul: unknown attribute replySeparator. Type 'attr myMModul ?' for a detailed list.

HAbe ich vlt. keine aktuelle 66_ecmd?
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 21 November 2016, 20:53:28
Upsi, das Attribut heißt responseSeparator.
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 21 November 2016, 21:28:04
Beide Werte drin:
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 requestSeparator workaround
attr myMModul responseSeparator workaround
attr myMModul verbose 5
define 40Relais1 ECMDDevice MModul 40 1
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero


Hier die Log. Erst an/aus mit FHEM, dann an aus mit Hardware:
2016.11.21 21:25:08 5: myMModul: sending command "#M(E\001\001\001\r\n"
2016.11.21 21:25:08 5: myMModul: write "#M(E\001\001\001\r\n", expect !M.*\n
2016.11.21 21:25:08 5: SW: 234d28450101010d0a
2016.11.21 21:25:08 5: myMModul: read "!M(E\001\001\001\r\n"
2016.11.21 21:25:08 5: myMModul: received answer "!M(E\001\001\001\r\n"
2016.11.21 21:25:13 5: myMModul: sending command "#M(E\001\001\000\r\n"
2016.11.21 21:25:13 5: myMModul: write "#M(E\001\001\000\r\n", expect !M.*\n
2016.11.21 21:25:13 5: SW: 234d28450101000d0a
2016.11.21 21:25:13 5: myMModul: read "!M(E\001\001\000\r\n"
2016.11.21 21:25:13 5: myMModul: received answer "!M(E\001\001\000\r\n"
2016.11.21 21:25:20 5: myMModul: read "#"
2016.11.21 21:25:20 5: myMModul: Spontaneously received "#"
2016.11.21 21:25:20 5: myMModul dispatch #
2016.11.21 21:25:20 5: myMModul: read "M(E\001\001\001\r\n!M(E\001\001\001\r\n"
2016.11.21 21:25:20 5: myMModul: Spontaneously received "M(E\001\001\001\r\n!M(E\001\001\001\r\n"
2016.11.21 21:25:20 5: myMModul dispatch M(E
!M(E

2016.11.21 21:25:24 5: myMModul: read "#"
2016.11.21 21:25:24 5: myMModul: Spontaneously received "#"
2016.11.21 21:25:24 5: myMModul dispatch #
2016.11.21 21:25:24 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.21 21:25:24 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.21 21:25:24 5: myMModul dispatch M(E

2016.11.21 21:25:24 5: myMModul: read "!"
2016.11.21 21:25:24 5: myMModul: Spontaneously received "!"
2016.11.21 21:25:24 5: myMModul dispatch !
2016.11.21 21:25:24 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.21 21:25:24 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.21 21:25:24 5: myMModul dispatch M(E


Habe allerdings nur set-commands in der aktuellen classdef, falls das ne Rolle spielt:
]
params M_Adresse M_Relais
set on cmd {chr(35).chr(77).chr(%M_Adresse).chr(69).chr(1).chr(%M_Relais).chr(1).chr(13).chr(10)}
set on expect "!M.*\n"
set on postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
set off cmd {chr(35).chr(77).chr(%M_Adresse).chr(69).chr(1).chr(%M_Relais).chr(0).chr(13).chr(10)}
set off expect "!M.*\n"
set off postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}


Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 21 November 2016, 21:53:13
Aha. Als Antwort kommt eine Verkettung von Request und Response und diese auch noch unglücklich am ersten # gesplittet.

Da ja alle Kommandos und Antworten auf \r\n enden, schlage ich vor, dass Du als responseSeparator \n einsetzt. Bitte beim Match berücksichtigen, dass dann \n aus der Antwort herausgeschnitten wird.

Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 22 November 2016, 14:08:49
Dann habe ich das Problem, dass der Befehl nicht mehr ausgeführt wird...
Außerdem, schau Dir mal die Anwortzeiten an.

FHEM an: 14:03:40
FHEM aus: 14:03:51
Hardware an: 14:04:10
Hardware aus: 14:04:20


2016.11.22 14:03:40 5: myMModul: sending command "#M(E\001\001\001\r"
2016.11.22 14:03:40 5: myMModul: write "#M(E\001\001\001\r", expect !M.*\r
2016.11.22 14:03:40 5: SW: 234d28450101010d
2016.11.22 14:03:43 2: myMModul: first attempt to read timed out, trying to close and open the device.
2016.11.22 14:03:43 3: Opening myMModul device /dev/ttyUSB0
2016.11.22 14:03:43 3: Setting myMModul serial parameters to 9600,8,N,1
2016.11.22 14:03:43 3: myMModul device opened
2016.11.22 14:03:43 5: SW: 234d28450101010d
2016.11.22 14:03:46 2: myMModul: second attempt to read timed out, this is an unrecoverable error.
2016.11.22 14:03:48 1: myMModul: no answer received (wrote "#M(E\001\001\001\r", expected !M.*\r)
2016.11.22 14:03:48 5: myMModul: received answer ""
2016.11.22 14:03:51 5: myMModul: sending command "#M(E\001\001\000\r"
2016.11.22 14:03:51 5: myMModul: write "#M(E\001\001\000\r", expect !M.*\r
2016.11.22 14:03:51 5: SW: 234d28450101000d
2016.11.22 14:03:54 2: myMModul: first attempt to read timed out, trying to close and open the device.
2016.11.22 14:03:54 3: Opening myMModul device /dev/ttyUSB0
2016.11.22 14:03:54 3: Setting myMModul serial parameters to 9600,8,N,1
2016.11.22 14:03:54 3: myMModul device opened
2016.11.22 14:03:54 5: SW: 234d28450101000d
2016.11.22 14:03:57 2: myMModul: second attempt to read timed out, this is an unrecoverable error.
2016.11.22 14:03:59 1: myMModul: no answer received (wrote "#M(E\001\001\000\r", expected !M.*\r)
2016.11.22 14:03:59 5: myMModul: received answer ""
2016.11.22 14:04:10 5: myMModul: read "#M("
2016.11.22 14:04:10 5: myMModul: Spontaneously received "#M("
2016.11.22 14:04:10 5: myMModul dispatch #M(
2016.11.22 14:04:10 5: myMModul: read "E\001\001\001\r\n"
2016.11.22 14:04:10 5: myMModul: Spontaneously received "E\001\001\001\r\n"
2016.11.22 14:04:10 5: myMModul dispatch E

2016.11.22 14:04:10 5: myMModul: read "!"
2016.11.22 14:04:10 5: myMModul: Spontaneously received "!"
2016.11.22 14:04:10 5: myMModul dispatch !
2016.11.22 14:04:10 5: myMModul: read "M(E\001\001\001\r\n"
2016.11.22 14:04:10 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.22 14:04:10 5: myMModul dispatch M(E

2016.11.22 14:04:20 5: myMModul: read "#"
2016.11.22 14:04:20 5: myMModul: Spontaneously received "#"
2016.11.22 14:04:20 5: myMModul dispatch #
2016.11.22 14:04:20 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.22 14:04:20 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.22 14:04:20 5: myMModul dispatch M(E

2016.11.22 14:04:20 5: myMModul: read "!"
2016.11.22 14:04:20 5: myMModul: Spontaneously received "!"
2016.11.22 14:04:20 5: myMModul dispatch !
2016.11.22 14:04:20 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.22 14:04:20 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.22 14:04:20 5: myMModul dispatch M(E



Wenn das Partial bei "spontan" arbeiten würde, müsste es doch wenigstens 2 Sekunden dauern, bis er checkt, dass nix passt....
Es müsste quasie so aussehen wie der Bereich von "FHEM geschaltet"...

Ich vermute daher immer noch, dass Partial nur für set und get und nicht für sonstige Antworten funktioniert....?
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 22 November 2016, 18:47:07
Ich glaube, nun habe ich einen Denkfehler.
Wenn ich nicht das Richtige "matche" dann ist alles was er findet ein Treffer...
Ich muss mal mein regex-match überarbeiten...

Mh... das sollte aber was finden:
reading TModul match "[#!].*\n" bzw. reading TModul match "[#!].*\\n"
Also ich erwarte entweder ein # oder ein ! und dann kommt irgendwas, allerdings am Schluss ein \n
Trozdem sieht (\n in Seperator wieder zu "workaround" geändert) das log so aus.
Auffällig, dass immer am ! # oder !M und #M getrennt wird.


2016.11.22 18:43:40 5: myMModul: read "#M"
2016.11.22 18:43:40 5: myMModul: Spontaneously received "#M"
2016.11.22 18:43:40 5: myMModul dispatch #M
2016.11.22 18:43:40 5: myMModul: read "(E\001\001\001\r\n"
2016.11.22 18:43:40 5: myMModul: Spontaneously received "(E\001\001\001\r\n"
2016.11.22 18:43:40 5: myMModul dispatch (E

2016.11.22 18:43:40 5: myMModul: read "!M"
2016.11.22 18:43:40 5: myMModul: Spontaneously received "!M"
2016.11.22 18:43:40 5: myMModul dispatch !M
2016.11.22 18:43:40 5: myMModul: read "(E\001\001\001\r\n"
2016.11.22 18:43:40 5: myMModul: Spontaneously received "(E\001\001\001\r\n"
2016.11.22 18:43:40 5: myMModul dispatch (E

2016.11.22 18:43:41 5: myMModul: read "#"
2016.11.22 18:43:41 5: myMModul: Spontaneously received "#"
2016.11.22 18:43:41 5: myMModul dispatch #
2016.11.22 18:43:41 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.22 18:43:41 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.22 18:43:41 5: myMModul dispatch M(E

2016.11.22 18:43:41 5: myMModul: read "!"
2016.11.22 18:43:41 5: myMModul: Spontaneously received "!"
2016.11.22 18:43:41 5: myMModul dispatch !
2016.11.22 18:43:41 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.22 18:43:41 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.22 18:43:41 5: myMModul dispatch M(E


Und ich habe noch einen weiteren Test gemacht.
Habe das set on cmd geleert: set on cmd {}
und dann set 40Relais1 gesendet und sofort den Hardwaretaster gedrückt, in der Hoffnung, dass das expect:

set on expect "#M.*\r\n"

das Ganze erfasst ;)
Leider nicht....

2016.11.22 19:10:59 5: myMModul: sending command "HASH(0x104ca18)"
2016.11.22 19:10:59 5: myMModul: write "HASH(0x104ca18)"
2016.11.22 19:10:59 5: SW: 484153482830783130346361313829
2016.11.22 19:11:00 5: myMModul: read "#"
2016.11.22 19:11:00 5: myMModul: Spontaneously received "#"
2016.11.22 19:11:00 5: myMModul dispatch #
2016.11.22 19:11:00 5: myMModul: read "M(E\001\001\001\r\n"
2016.11.22 19:11:00 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.22 19:11:00 5: myMModul dispatch M(E

2016.11.22 19:11:00 5: myMModul: read "!"
2016.11.22 19:11:00 5: myMModul: Spontaneously received "!"
2016.11.22 19:11:00 5: myMModul dispatch !
2016.11.22 19:11:00 5: myMModul: read "M(E\001\001\001\r\n"
2016.11.22 19:11:00 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.22 19:11:00 5: myMModul dispatch M(E



Und hier der nächste Test in der classdef...:
reading TModul1 match "#"
reading TModul2 match "!"
reading TModul3 match "#M"
reading TModul4 match "!M"

gibt in der Log beim starten einen wichtigen Hinweis???:
2016.11.22 19:28:06 3: Opening myMModul device /dev/ttyUSB0
2016.11.22 19:28:07 3: Setting myMModul serial parameters to 9600,8,N,1
2016.11.22 19:28:07 3: myMModul device opened
2016.11.22 19:28:07 1: myMModul: match for reading TModul1 is not enclosed in double quotes.
2016.11.22 19:28:07 1: myMModul: match for reading TModul3 is not enclosed in double quotes.


Und kein MATCH im log:

2016.11.22 19:30:54 5: myMModul: read "#"
2016.11.22 19:30:54 5: myMModul: Spontaneously received "#"
2016.11.22 19:30:54 5: myMModul dispatch #
2016.11.22 19:30:54 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.22 19:30:54 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.22 19:30:54 5: myMModul dispatch M(E

2016.11.22 19:30:54 5: myMModul: read "!"
2016.11.22 19:30:54 5: myMModul: Spontaneously received "!"
2016.11.22 19:30:54 5: myMModul dispatch !
2016.11.22 19:30:54 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.22 19:30:54 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.22 19:30:54 5: myMModul dispatch M(E

Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 25 November 2016, 20:02:50
Hallo,

hast Du nur den responseSeparator auf \n gesetzt (sollst Du) oder auch den requestSeparator (sollst Du nicht)?

In der classdef musst Du immer noch bei den cmds das \n mitsenden und bei den expect rauslassen.

Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 25 November 2016, 20:48:46
Hast mich erwischt ;)

also hier meine classdef:
]
params M_Adresse M_Relais
set on cmd {chr(35).chr(77).chr(%M_Adresse).chr(69).chr(1).chr(%M_Relais).chr(1).chr(13).chr(10)}
set on expect "!M.*\r\n"
set on postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
set off cmd {chr(35).chr(77).chr(%M_Adresse).chr(69).chr(1).chr(%M_Relais).chr(0).chr(13).chr(10)}
set off expect "!M.*\r\n"
set off postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
reading Test1 match "M.*\r"


und der aktuelle fhem.cfg-Bereich:
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 requestSeparator workaround
attr myMModul responseSeparator \n
attr myMModul verbose 5
define 40Relais1 ECMDDevice MModul 40 1
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero



und hier das log. Zunächst per Fhem geschaltet:

2016.11.25 20:42:07 5: myMModul: sending command "#M(E\001\001\001\r\n"
2016.11.25 20:42:07 5: myMModul: write "#M(E\001\001\001\r\n", expect !M.*\r\n
2016.11.25 20:42:07 5: SW: 234d28450101010d0a
2016.11.25 20:42:07 5: myMModul: read "!M(E\001\001\001\r\n"
2016.11.25 20:42:07 5: myMModul: received answer "!M(E\001\001\001\r\n"
2016.11.25 20:42:12 5: myMModul: sending command "#M(E\001\001\000\r\n"
2016.11.25 20:42:12 5: myMModul: write "#M(E\001\001\000\r\n", expect !M.*\r\n
2016.11.25 20:42:12 5: SW: 234d28450101000d0a
2016.11.25 20:42:13 5: myMModul: read "!M(E\001\001\000\r\n"
2016.11.25 20:42:13 5: myMModul: received answer "!M(E\001\001\000\r\n"


und nun per Hardware:
2016.11.25 20:44:43 5: myMModul: read "#"
2016.11.25 20:44:43 5: myMModul: Spontaneously received "#"
2016.11.25 20:44:43 5: myMModul dispatch #
2016.11.25 20:44:43 5: myMModul: read "M(E\001\001\001\r\n"
2016.11.25 20:44:43 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.25 20:44:43 5: myMModul dispatch M(E

2016.11.25 20:44:43 5: myMModul: read "!"
2016.11.25 20:44:43 5: myMModul: Spontaneously received "!"
2016.11.25 20:44:43 5: myMModul dispatch !
2016.11.25 20:44:43 5: myMModul: read "M(E\001\001\001\r\n"
2016.11.25 20:44:43 5: myMModul: Spontaneously received "M(E\001\001\001\r\n"
2016.11.25 20:44:43 5: myMModul dispatch M(E

2016.11.25 20:44:45 5: myMModul: read "#"
2016.11.25 20:44:45 5: myMModul: Spontaneously received "#"
2016.11.25 20:44:45 5: myMModul dispatch #
2016.11.25 20:44:45 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.25 20:44:45 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.25 20:44:45 5: myMModul dispatch M(E

2016.11.25 20:44:45 5: myMModul: read "!"
2016.11.25 20:44:45 5: myMModul: Spontaneously received "!"
2016.11.25 20:44:45 5: myMModul dispatch !
2016.11.25 20:44:45 5: myMModul: read "M(E\001\001\000\r\n"
2016.11.25 20:44:45 5: myMModul: Spontaneously received "M(E\001\001\000\r\n"
2016.11.25 20:44:45 5: myMModul dispatch M(E


Ich werde das Gefühl immer noch nicht los, dass die spontanen Antworten gar nicht erst durch Deine gewünschte Routine laufen,
also weder am \n separiert, noch per partial 2 zusammengesetzt werden... aber ich habe leider zu wenig Ahnung ob die IODEV
oder die zusammenhängenden Dateien nicht schon vorher die Daten "abzweigen"....?

P.S.: ich starte vor dem Test mit /etc/init.d/fhem stop und /etc/init.d/fhem start, anschließend
tail -f /opt/fhem/log/fhem-2016-11.log um das log zu verfolgen....

Kann auch gern mal eine debugg-Datei von Dir einbinden, die Testausgaben ins log schreibt.
Ist eh mein Testsystem...
Vlt so, dass der Eintrag:
2016.11.25 20:44:43 5: myMModul: read "!"
geprüft wird, ob an der Stelle "$partial" verfügbar und den richtigen Inhalt hat, also das Ganze dann so aussieht:
2016.11.25 20:44:43 5: myMModul: read "!" [partial:2]




Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 25 November 2016, 21:25:06
Hallo,

in dem expect muss das \n weg. Aber dann geht es vermutlich immer noch nicht, weil ich meine, dass in attr requestSeparator \n das \n nicht als Steuerzeichen sondern als literales Backslash+n verstanden wird. Außerdem versteht eh kein Mensch, wie er das Modul in diesen Situationen konfigurieren soll.

Ich breche daher den Support an dieser Stelle ab und mache mich am Sonntag ausgeschlafen an eine Überarbeitung des Moduls. Testfälle habe ich aus Deinen Logs genug.

Ich melde mich wieder, wenn ich fertig bin. Dann komme ich auf Dein Angebot zurück, es zu testen.

Viele Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 25 November 2016, 21:29:23
Boris, echt lieb von Dir.
Ich kann Dir auch die Hardware schicken, wenn das für Dich ok ist.....
Ich mache es so, wie Du es magst...
DANKE!!!
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 27 November 2016, 17:07:07
Hallo,

bitte finde anbei überarbeitete Versionen von ECMD, ECMDDevice und der dazugehörigen Commandref.

changes as of 27 Nov 2016:
- if split is used, the string at which the messages are split are still part of the messages
- no default attributes for requestSeparator and responseSeparator
- input of raw data as perl-encoded string (for setting attributes)
- be more verbose and explicit at loglevel 5
- documentation corrected and amended


Bitte setze das Attribut split auf \r\n und das Attribut partial auf 2. Die Attribute requestSeparator und responseSeparator werden nicht gesetzt (das war ein Irrweg).

Bitte lies Dir auch in der Commandref den Abschnitt zu diesen Attributen und den Abschnitt "Separators" durch.

Viele Grüße
Boris
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 28 November 2016, 19:01:42
Hallo Boris,

Ergebnisse:
1. der "attr myMModul requestSeparator �" schreibt sich immer noch von alleine rein. (stört aber nicht)

2. Schaltung per FHEM sieht sehr gut aus!

# Anschalten
2016.11.28 18:51:53 5: myMModul: sending command #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012)
2016.11.28 18:51:53 5: myMModul: write #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012), expect !M.*\r\n
2016.11.28 18:51:53 5: SW: 234d28450101010d0a
2016.11.28 18:51:53 5: myMModul: read !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012)
2016.11.28 18:51:53 5: myMModul: received answer !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012)

# Ausschalten
2016.11.28 18:52:47 5: myMModul: sending command #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012)
2016.11.28 18:52:47 5: myMModul: write #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012), expect !M.*\r\n
2016.11.28 18:52:47 5: SW: 234d28450101000d0a
2016.11.28 18:52:47 5: myMModul: read !M(E\001\001\000\r\n (\041\115\050\105\001\001\000\015\012)
2016.11.28 18:52:47 5: myMModul: received answer !M(E\001\001\000\r\n (\041\115\050\105\001\001\000\015\012)


Das ist ja schon mal topp!!! Auch schön, dass Du den String gleich zerlegt hast.

Hardware-Schalter an:
2016.11.28 18:56:53 5: myMModul: read #M (\043\115)
2016.11.28 18:56:53 5: myMModul: Spontaneously received #M (\043\115)
2016.11.28 18:56:53 5: myMModul dispatch #M
2016.11.28 18:56:53 5: myMModul: partial message !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012) expired.
2016.11.28 18:56:53 5: myMModul: trying to match message #M (\043\115)
2016.11.28 18:56:53 5: myMModul: partial message #M (\043\115) kept
2016.11.28 18:56:53 5: myMModul: read (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: Spontaneously received (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul dispatch (E

2016.11.28 18:56:53 5: myMModul: merging partial message #M (\043\115) and (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: trying to match message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: partial message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012) kept
2016.11.28 18:56:53 5: myMModul: read ! (\041)
2016.11.28 18:56:53 5: myMModul: Spontaneously received ! (\041)
2016.11.28 18:56:53 5: myMModul dispatch !
2016.11.28 18:56:53 5: myMModul: merging partial message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012) and ! (\041)
2016.11.28 18:56:53 5: myMModul: #M(E\001\001\001\r\n! (\043\115\050\105\001\001\001\015\012\041) split into 2 parts
2016.11.28 18:56:53 5: myMModul: trying to match message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: trying to match message ! (\041)
2016.11.28 18:56:53 5: myMModul: partial message ! (\041) kept
2016.11.28 18:56:53 5: myMModul: read M(E\001\001\001\r\n (\115\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: Spontaneously received M(E\001\001\001\r\n (\115\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul dispatch M(E

2016.11.28 18:56:53 5: myMModul: merging partial message ! (\041) and M(E\001\001\001\r\n (\115\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: trying to match message !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012)
2016.11.28 18:56:53 5: myMModul: partial message !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012) kept


Hardwareschalter aus:
2016.11.28 18:59:18 5: myMModul: read # (\043)
2016.11.28 18:59:18 5: myMModul: Spontaneously received # (\043)
2016.11.28 18:59:18 5: myMModul dispatch #
2016.11.28 18:59:18 5: myMModul: partial message !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012) expired.
2016.11.28 18:59:18 5: myMModul: trying to match message # (\043)
2016.11.28 18:59:18 5: myMModul: partial message # (\043) kept
2016.11.28 18:59:18 5: myMModul: read M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: Spontaneously received M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul dispatch M(E

2016.11.28 18:59:18 5: myMModul: merging partial message # (\043) and M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: trying to match message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: partial message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012) kept
2016.11.28 18:59:18 5: myMModul: read ! (\041)
2016.11.28 18:59:18 5: myMModul: Spontaneously received ! (\041)
2016.11.28 18:59:18 5: myMModul dispatch !
2016.11.28 18:59:18 5: myMModul: merging partial message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012) and ! (\041)
2016.11.28 18:59:18 5: myMModul: #M(E\001\001\000\r\n! (\043\115\050\105\001\001\000\015\012\041) split into 2 parts
2016.11.28 18:59:18 5: myMModul: trying to match message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: trying to match message ! (\041)
2016.11.28 18:59:18 5: myMModul: partial message ! (\041) kept
2016.11.28 18:59:18 5: myMModul: read M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: Spontaneously received M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul dispatch M(E

2016.11.28 18:59:18 5: myMModul: merging partial message ! (\041) and M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: trying to match message !M(E\001\001\000\r\n (\041\115\050\105\001\001\000\015\012)
2016.11.28 18:59:18 5: myMModul: partial message !M(E\001\001\000\r\n (\041\115\050\105\001\001\000\015\012) kept


Das sieht doch schon mal gut aus oder?
Manchmal scheint der Response vertauscht...?
Aber es fühlt sich trotzdem super an...

So und jetzt lese ich mir noch die commandref durch... ;)
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 28 November 2016, 22:03:49
1. deleteattr myMModul requestSeparator
Save.

2. Bitte classdef und Definition von myMModul zeigen (aktuell). Da ist das regex nicht okay, es kommt kein Match.
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 29 November 2016, 13:02:40
ja, ich glaube das waren noch Altlasten und tests: reading Test1 match "M.*\r"

aktuell geändert auf:
]
params M_Adresse M_Relais
set on cmd {chr(35).chr(77).chr(%M_Adresse).chr(69).chr(1).chr(%M_Relais).chr(1).chr(13).chr(10)}
set on expect "!M.*\r\n"
set on postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
set off cmd {chr(35).chr(77).chr(%M_Adresse).chr(69).chr(1).chr(%M_Relais).chr(0).chr(13).chr(10)}
set off expect "!M.*\r\n"
set off postproc {s/([!M.*|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
reading Test1 match "!M.*\r\n"


und hier das log:
Hardwareschalter an:

2016.11.29 12:58:43 5: myMModul: read #M (\043\115)
2016.11.29 12:58:43 5: myMModul: Spontaneously received #M (\043\115)
2016.11.29 12:58:43 5: myMModul dispatch #M
2016.11.29 12:58:43 5: myMModul: trying to match message #M (\043\115)
2016.11.29 12:58:43 5: myMModul: partial message #M (\043\115) kept
2016.11.29 12:58:43 5: myMModul: read (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: Spontaneously received (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul dispatch (E

2016.11.29 12:58:43 5: myMModul: merging partial message #M (\043\115) and (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: trying to match message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: partial message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012) kept
2016.11.29 12:58:43 5: myMModul: read !M (\041\115)
2016.11.29 12:58:43 5: myMModul: Spontaneously received !M (\041\115)
2016.11.29 12:58:43 5: myMModul dispatch !M
2016.11.29 12:58:43 5: myMModul: merging partial message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012) and !M (\041\115)
2016.11.29 12:58:43 5: myMModul: #M(E\001\001\001\r\n!M (\043\115\050\105\001\001\001\015\012\041\115) split into 2 parts
2016.11.29 12:58:43 5: myMModul: trying to match message #M(E\001\001\001\r\n (\043\115\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: trying to match message !M (\041\115)
2016.11.29 12:58:43 5: myMModul: partial message !M (\041\115) kept
2016.11.29 12:58:43 5: myMModul: read (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: Spontaneously received (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul dispatch (E

2016.11.29 12:58:43 5: myMModul: merging partial message !M (\041\115) and (E\001\001\001\r\n (\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: trying to match message !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012)
2016.11.29 12:58:43 5: myMModul: !M(E\001\001\001\r\n (\041\115\050\105\001\001\001\015\012) matches regex !M.*\r\n for reading Test1 of device 40Relais1 with class MModul


offensichtlich mit gefundener richtiger Antwort ;)

und hier Hardware aus:

2016.11.29 12:59:49 5: myMModul: read # (\043)
2016.11.29 12:59:49 5: myMModul: Spontaneously received # (\043)
2016.11.29 12:59:49 5: myMModul dispatch #
2016.11.29 12:59:49 5: myMModul: trying to match message # (\043)
2016.11.29 12:59:49 5: myMModul: partial message # (\043) kept
2016.11.29 12:59:49 5: myMModul: read M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: Spontaneously received M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul dispatch M(E

2016.11.29 12:59:49 5: myMModul: merging partial message # (\043) and M(E\001\001\000\r\n (\115\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: trying to match message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: partial message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012) kept
2016.11.29 12:59:49 5: myMModul: read !M (\041\115)
2016.11.29 12:59:49 5: myMModul: Spontaneously received !M (\041\115)
2016.11.29 12:59:49 5: myMModul dispatch !M
2016.11.29 12:59:49 5: myMModul: merging partial message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012) and !M (\041\115)
2016.11.29 12:59:49 5: myMModul: #M(E\001\001\000\r\n!M (\043\115\050\105\001\001\000\015\012\041\115) split into 2 parts
2016.11.29 12:59:49 5: myMModul: trying to match message #M(E\001\001\000\r\n (\043\115\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: trying to match message !M (\041\115)
2016.11.29 12:59:49 5: myMModul: partial message !M (\041\115) kept
2016.11.29 12:59:49 5: myMModul: read (E\001\001\000\r\n (\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: Spontaneously received (E\001\001\000\r\n (\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul dispatch (E

2016.11.29 12:59:49 5: myMModul: merging partial message !M (\041\115) and (E\001\001\000\r\n (\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: trying to match message !M(E\001\001\000\r\n (\041\115\050\105\001\001\000\015\012)
2016.11.29 12:59:49 5: myMModul: !M(E\001\001\000\r\n (\041\115\050\105\001\001\000\015\012) matches regex !M.*\r\n for reading Test1 of device 40Relais1 with class MModul


und auch hier die richtige Antwort separiert :)
Jetzt sieht es aber gut aus oder?

ach und hier mein fhem.cfg

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 40 1
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 29 November 2016, 22:29:42
Jupp. Und wenn es dann auch klappt... Werde das Modul zunächst zum allgemeinen Test stellen nebst Warnungen und dann nach einer Karenzzeit einchecken.
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 29 November 2016, 22:46:55
Oh, das sieht gut aus...
habe meine fhem.cfg mit einem 2. Relais erweitert:
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 40 1
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero
define 40Relais2 ECMDDevice MModul 40 2
attr 40Relais2 IODev myMModul
attr 40Relais2 room Buero


außerdem die classdef mit einem postproc:

reading Test1 match "!M.*\r\n"
reading Test1 postproc {ProcessmyECMD($_);}


und dann auch die 99_Utils.pm:
zu Beginn:
my $myECMDString="off";
my $a7status = "leer";

und weiter unten bei den SUBs:
sub ProcessmyECMD($)
{
my $Modulname = "Relais";
my $answer = $_;
print "Antwort: ".$answer."\n";
my $a1 = chr(ord(substr $answer,0,1));
my $a2 = chr(ord(substr $answer,1,1));
my $a3 = ord(substr $answer,2,1);
my $a4 = ord(substr $answer,3,1);
my $a5 = ord(substr $answer,4,1);
my $a6 = ord(substr $answer,5,1);
my $a7 = ord(substr $answer,6,1);
my $a8 = ord(substr $answer,7,1);
my $a9 = ord(substr $answer,8,1);

# Vorbereitung Status
if ($a7 == 1) {
    $a7status = "on";
}
elsif ($a7 == 0) {
    $a7status = "off";
}

# Debug
print "Antwort: ".$answer."\n";
print "a1:".$a1."\n";
print "a2:".$a2."\n";
print "a3:".$a3."\n";
print "a4:".$a4."\n";
print "a5:".$a5."\n";
print "a6:".$a6."\n";
print "a7:".$a7."\n";
print "a8:".$a8."\n";
print "a9:".$a9."\n";
print "\n";

# Testausgabe für FHEM
my $Befehm = "setstate ".$a3.$Modulname.$a6." ".$a7status;
print "generierter Befehl für FHEM:".$Befehm."\n";
fhem ("$Befehm");
}


Im log gibt er schon aus:
generierter Befehl für FHEM:setstate 40Relais1 on (HURRAAA!!!! :))
auch das Schalten des 2. Relais wird richtig ausgewertet:
generierter Befehl für FHEM:setstate 40Relais2 on
Das ist alles schon mal SUPER :)

Allerdings habe ich noch einen kleinen Denkfehler irgendwo in der letzten Zeile mit dem fhem-Befehl??,
weil der Status nicht richtig gesetzt wird.
Außerdem steht im Frontend:
---------------------
ECMDDevice
40Relais1 Test1 on off
40Relais2 Test1 on off
--------------------
Das ist bestimmt ne Kleinigkeit, wahrscheinlich stimm die classdef noch nicht und müsste einen Rückgabewert verarbeiten?
oder doch in der 99_Utils ein Fehler...., kann jemand helfen?
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 01 Dezember 2016, 19:37:30
Liebe Freunde...mir raucht der Kopf:

Das PERL setzt nun den Status, aber irgenwer hackt mir noch dazwischen:
Wenn alle Relais per Fhem Status auf an gesetzt werden (setstate 40Relais1 on, usw.) (siehe Bild)
und ich dann das 2 Relais ausschalte dann geht die Lampe weg und ein "answerMModul" steht da (siehe 2. Bild)

Hat jemand eine Erklärung?

Hier meine MModul.classde:

reading answerMModul match "!M.*\r\n"
reading answerMModul postproc {ProcessmyECMD($_);}


Und hier das Programm, gespeichert in den 99_Utils.pm:
sub ProcessmyECMD($)
{
my $Modulname = "Relais";
my $answer = $_; # hier !M(E\005\002\000\r\n
my $a7status = "leer";

my $a3 = ord(substr $answer,2,1); # hier 40
my $a6 = ord(substr $answer,5,1); # hier 2
my $a7 = ord(substr $answer,6,1);# hier 0

# Vorbereitung Status
if ($a7 == 1) {
    $a7status = "on";
}
elsif ($a7 == 0) {
    $a7status = "off";
}

# Status-Befehl zusammensetzen
my $Befehm = "setstate ".$a3.$Modulname.$a6." ".$a7status; # hier "setstate 40Relais2 off"

# Status Befehl ausführen
fhem ("$Befehm");
}


Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 01 Dezember 2016, 21:28:47
Für mich Problemursache auch nicht offensichtlich.

Tipps:
In Deiner Routine mit Debug "bla" gesprächig werden.
Die Matches spezifischer auf das einzelne Relais machen (%M_Relais ins Regex einbauen)
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 02 Dezember 2016, 15:19:00
Muss ich bei 10 Relais 10 readings machen?
Ich dachte ich kann ein Reading machen, das übergibt das Matching an das Programm, dieses wertet das Matching aus, erzeugt den entsprechenden FHEM-Befehl und löst sich dann selber auf ;).
Oder anders, weißt Du warum fhem sich veranlasst fühlt den Name des Readings in den Status des Devices zu schreiben? (hier "answerMModul")

PS.: Ich kann nicht das %M einbauen, da ich ja noch gar nicht weiß, welches Relais geschaltet wird aus der Sicht von Fhem. Ich muss also auf dem Bus lauschen und das gehörte auswerten und danach sagen, welches Relais geschaltet wurde...

DEBUG habe ich im Post rausgelassen.
Also der gematchte Befehl wird einwandfrei übergeben, in einzelne Teile zerlegt und der FHEM-Befehl wird richtig erzeugt, abgeschickt und in der letzten Zeile stimmt was nicht.
also ich denke entweder das
return() ist falsch, und hier muss was anderes hin, oder das postprog muss fhem sagen, dass es nichts gefunden hat weil das ja schon das eigene Programm dies erledigt hat.

Gibt es also eine Möglichkeit in der classdef oder dem Programm das so zu gestalten, dass zwar der gematchte Parameter ans Programm übergeben wird, aber dann das postproc keine weitere Aktion macht?
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 03 Dezember 2016, 19:43:44
10 Relais = 10 ECMDDevice (Standard) oder 10 Readings an einem Device (Exotenoption)

Das ganze setstate-Zeug ist überflüssig und ich weiß nicht, wer diesen Overhead im Wiki verbreitet. Das postprocessing alleine genügt, aus dem Wert, den das Gerät liefert, ein Reading nach Geschmack zu machen. In der Commandref ist ein Beispiel.
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 04 Dezember 2016, 16:11:25
aber mache ich das nicht schon?
hier die aktuelle fhem.cfg
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 40 1
attr 40Relais1 IODev myMModul
attr 40Relais1 room Buero
define 40Relais2 ECMDDevice MModul 40 2
attr 40Relais2 IODev myMModul
attr 40Relais2 room Buero
define 40Relais3 ECMDDevice MModul 40 3
attr 40Relais3 IODev myMModul
attr 40Relais3 room Buero


Oder ich versuche mal zu übersetzen:

1. meine fhem.cfg ist richtig
2. da lt. commandref "A spontaneous data transmission from the physical device that matches the Perl regular expression <regex> is evaluated to become the value of the named reading. All ECMDDevice devices belonging to the ECMD device with readings with matching regular expressions will receive an update of the said readings. <regex> must match the entire reply, as in m/^<regex>$/." bedeutet, dass ein reading namens "answerMModul" als Status in alle ECMDDEvices geschrieben wird, ist es mir also nicht möglich, das Regex so zu gestalten, dass es nur für ein Device passt, denn sobald es für irgendein Device passt wird es in alle Devices geschrieben.
Oder gibt es irgendeine Idendifikationsmöglichkeit der Devices, also eine interne ID oder sonst irgendetwas. Aber auch die würde mir ja nicht helfen.
Denn angenommen ich schreibe das Regex exact der Antwort von Device 2. Woher will denn Fhem wissen, dass das die Antwort von Device 2 ist.
Ich müsste also die Möglichkeit haben dem Regex noch die Info mitzugeben oder zurückzugeben, dass das match für device 2 galt.

Oder ich definiere ein dummy ECMD mit oder ohne einem ECMD-Device, deren Status mir egal ist und schreibe vom Programm aus, welches vom Reading der dummyclassdef gestartet wurde, dann die Statusbefehle für das "reale" Device. Das scheint mir aber umständlich...
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 04 Dezember 2016, 19:12:50
Oder brauche ich einfach nur ein reading "on" und ein reading "off"?
Aber das ist zu banal...
Außerdem schaltet das reading ja dann eh wieder alle Relais auf on oder off...

gerade getestet, wie prognostiziert und den Weg wieder verworfen. :(
Komme nicht weiter.
Das war die entsprechende classdef:
0
reading on match "!M.*\001\r\n"
reading on postproc {ProcessmyECMD($_);}
reading off match "!M.*\000\r\n"
reading off postproc {ProcessmyECMD($_);}
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 04 Dezember 2016, 19:37:11
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)



Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 04 Dezember 2016, 19:49:44
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?
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 04 Dezember 2016, 21:12:16
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.
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 05 Dezember 2016, 08:27:46
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?
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 05 Dezember 2016, 14:51:02
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....
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 10 Dezember 2016, 11:33:12
Hallo Boris,

kannst Du mir mal ein Beispiel schreiben, wie man für ein on/off mit einem Reading sorgt?
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 11 Dezember 2016, 12:45:16
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
Titel: Antw:Spontaneously received ECMD
Beitrag von: NeuFehm am 12 Dezember 2016, 08:40:18
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
Titel: Antw:Spontaneously received ECMD
Beitrag von: Dr. Boris Neubert am 14 Dezember 2016, 18:44:40
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