[gelöst] Upload von Parametern an Arduino (JeeLink).

Begonnen von JWRu, 29 Februar 2020, 13:18:43

Vorheriges Thema - Nächstes Thema

JWRu

Ich habe mehrere Arduino Nano über JeeLink an meine FHEM-Systeme angebunden. Diese erledigen verschiedene Aufgaben, wie z.B. Strom- Gas und Wasserzähler auszulesen oder meine Funk-Rauchmelder zu überwachen.
Die Messwerte werden über KeyValueProtocol übertragen.
Wenn ich jetzt aber irgendwelche Parameter (Erkennungsschwellen, Transmitzeiten ...) ändern will, muss ich jedesmal den entsprechenden Arduino abhängen und mit der Arduino-IDE den geänderten Sketch neu flashen.

Jetzt ist bei mir die Idee entstanden, ob ich nicht die entsprechenden Parameter in FHEM verwalte und nach dem Initialisieren an den Arduino schicke.
Dazu habe ich einen kleinen Probeaufbau gemacht: An einem Test-FHEM-System auf dem Raspberry hängt ein Arduino Nano über USB. Auf letzterem habe ich SoftwareSerial installiert, so dass ich über einen TTL<->USB Adapter alles überwachen kann, was FHEM über die im Arduino eingebaute USB-Schnittstelle schickt.

Den Arduino habe ich als JeeLink-Device definiert:
Internals:
   Clients    :PCA301:EC3000:RoomNode:LaCrosse:ETH200comfort:CUL_IR:HX2272:FS20:AliRF:Level:EMT7110:KeyValueProtocol
   DEF        /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AL03ZR46-if00-port0@9600
   DeviceName /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AL03ZR46-if00-port0@9600
   FD         4
   FUUID      5e598369-f33f-6a44-afad-05e749d78830d637
   NAME       Test_JeeLink
   NR         14
   PARTIAL   
   STATE      opened
   TYPE       JeeLink
   MatchList:
     1:PCA301   ^\S+\s+24
     2:EC3000   ^\S+\s+22
     3:RoomNode ^\S+\s+11
     4:LaCrosse ^(\S+\s+9 |OK\sWS\s)
     5:AliRF    ^\S+\s+5
     6:EMT7110  ^OK\sEMT7110\s
     7:KeyValueProtocol ^OK\sVALUES\s
   READINGS:
     2020-02-29 11:25:09   state           opened
Attributes:
   flashCommand avrdude -p atmega328P -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]
   verbose    5


Wenn ich jetzt manuell "set Test_JeeLink raw XXX" ausführe, taucht wunderbar "XXX" auf dem Arduino auf.

Um die Sache zu automatisieren, habe ich ein notify definiert:
Internals:
   CFGFN     
   DEF        Test_JeeLink:CONNECTED.* sleep 5; set Test_JeeLink raw XXX
   FUUID      5e5a35f8-f33f-6a44-dee0-10537cd8a3293336
   NAME       notify_Test_JeeLink
   NOTIFYDEV  Test_JeeLink
   NR         23
   NTFY_ORDER 50-notify_Test_JeeLink
   REGEXP     Test_JeeLink:CONNECTED.*
   STATE      2020-02-29 12:59:58
   TRIGGERTIME 1582977598.66129
   TYPE       notify
   READINGS:
     2020-02-29 12:59:25   state           active
Attributes:


Das notify löst aus, wenn ich "set Test_JeeLink reset" ausführe - im Log steht auch
2020.02.29 13:00:00 4: set Test_JeeLink raw XXX
2020.02.29 13:00:00 5: SW: XXX

Im Arduino kommt aber nichts an.

Ich habe noch einen zweiten Versuch unternommen:
Wenn ich "define at_Test at +00:00:05 set Test_JeeLink raw XXX" ausführe, kommt nach 5 Sekunden "XXX" im Arduino an.

Wenn ich das Notify so definiere: "define notify_Test_JeeLink notify Test_JeeLink:CONNECTED.* define at_Test at +00:00:05 set Test_JeeLink raw XXX", löst das Notify bei einem Reset des Arduino aus, das at wird nach 5 Sekunden ausgeführt, aber auf dem Arduino kommt nichts an.

Jetzt komme ich irgendwie nicht mehr weiter.
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter

JWRu

Ich schiebe das Thema nochmal hoch.
Meine Frage ist, warum FHEM-Kommandos, die von einem Notify ausgelöst werden, anders ausgeführt werden, als wenn ich sie händisch im Kommandofeld ausführe.
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter

Panik

probier es doch mal statt mit Notify mit einem DOIF oder MSwitch.

Ich habe bei mir fast 95% auf MSwitch umgestellt - ist sehr empfehlenswert,
da sich Trigger und auszuführende Befehle vorab auch getrennt testen lassen.
Raspberry3+,  CUL USB V3 mit V 1.66 CUL868, TRXRFX433, HM-MOD-UART, Phoscon-GW

frank

da greift eventuell der sicherheitsmechanismus, um endlosschleifen zu verhindern.
trigger und set cmd sind vom selben device.

mit userreading sollte es dann funktionieren.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

JWRu

@Panik: Von DOIF habe ich bisher die Finger gelassen - die Syntax ist mir im Vergleich zu Perl etwas schräg.
@frank: Wie ist das gemeint? Ein userreading für das JeeLink-Device einrichten, auf dieses triggern und dann das notify ein set ... ausführen lassen?
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter

frank

userreading statt notify.

ein userreading ist quasi ein spezielles notify, dass ein reading im selben device erzeugt/befüllt.
im "ausführungsteil" wird der wert des userreadings mit perlcode erzeugt und an das reading übergeben.

dort könnte man zusätzlich den set cmd mit der perlfunktion "fhem("set cmd")" einbauen.

ich habe es noch nicht probiert, könnte aber funktionieren.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

JWRu

Ah, verstanden. Ich bin unterwegs und probiere das nächste Woche mal aus.
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter

JWRu

Mit userreadings geht es auch nicht.
Ich habe jetzt auch versucht, mit dem notify auf Test_JeeLink:CONNECTED.* ein Dummy-Device zu schalten - das funktioniert.
Der Dummy löst dann ein weiteres notify aus, das "set Test_JeeLink raw XXX" ausführt. Auch mit dieser Variante kommt nichts an.
Wenn ich den Dummy manuell schalte, funktioniert es.
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter

JWRu

Es funktioniert jetzt. Nach einem Reset kann anscheinend der Arduino eine Zeitlang keine Daten empfangen.
Ich habe das Notify jetzt mit global:INITIALIZED.* getriggert und eine Wartezeit von 5 Sekunden eingebaut.
Jetzt kommen die Daten an.
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter

JWRu

#9
Für alle, die es mal nachmachen wollen, poste ich hier mal meine endgültige Lösung:

So sieht mein JeeLink-Device für den Arduino aus:
Internals:
   Clients    :PCA301:EC3000:RoomNode:LaCrosse:ETH200comfort:CUL_IR:HX2272:FS20:AliRF:Level:EMT7110:KeyValueProtocol
   DEF        /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AL05RIDZ-if00-port0@9600
   Detector_01_MSGCNT 602
   Detector_01_TIME 2020-03-15 11:36:51
   DeviceName /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AL05RIDZ-if00-port0@9600
   FD         28
   FUUID      5e57901f-f33f-c1fa-f170-3cf56638bd8420db
   NAME       Detector_01
   NR         303
   PARTIAL   
   RAWMSG     OK VALUES Detector 01 A=0,P=47.00,L=48
   STATE      opened
   TYPE       JeeLink
   Helper:
     DBLOG:
       UNKNOWNCODE Parameter:
         myDbLog:
           TIME       1584268015.11332
           VALUE      90 40 20 1000 100 10
       state:
         myDbLog:
           TIME       1584268015.08035
           VALUE      UNKNOWNCODE Sound- und LED-Detektor 1.6
   MatchList:
     1:PCA301   ^\S+\s+24
     2:EC3000   ^\S+\s+22
     3:RoomNode ^\S+\s+11
     4:LaCrosse ^(\S+\s+9 |OK\sWS\s)
     5:AliRF    ^\S+\s+5
     6:EMT7110  ^OK\sEMT7110\s
     7:KeyValueProtocol ^OK\sVALUES\s
   READINGS:
     2020-03-15 11:36:51   state           opened
Attributes:
   alias      Arduino LED und Geräusch
   comment    Parameter im Attribut initCommands (Trennung mit Leerzeichen):
LED Erkennung: 1 obere Schwelle, 2 untere Schwelle,  3 Alarmlimit,
Geräuscherkennung: 4 Sammelzeit (ms), 5 Alarmlimit, 6 Übertragungsintervall (min.)
   flashCommand avrdude -p atmega328P -c arduino -P [PORT] -D -U flash:w:[HEXFILE] 2>[LOGFILE]
   initCommands 90 40 20 1000 100 10
   room       System->Main,System->Protokolle->KeyValueProtocol

im Attribut initCommands stehen durch Leerzeichen getrennt die Parameter.

Die Übertragung zum Arduino erledigt ein Watchdog:
Internals:
   CMD        { my $Parameters = AttrVal("Detector_01","initCommands",""); fhem("set Detector_01 raw $Parameters") }
   DEF        global:INITIALIZED.*|Detector_01:CONNECTED.* 00:00:05 SAME { my $Parameters = AttrVal("Detector_01","initCommands",""); fhem("set Detector_01 raw $Parameters") }
   FUUID      5e6dfdc0-f33f-c1fa-1a43-b6cd461bc2a60854
   NAME       watchdog_Detector_01
   NOTIFYDEV  Detector_01,watchdog_Detector_01,global
   NR         60918
   NTFY_ORDER 50-watchdog_Detector_01
   RE1        global:INITIALIZED.*|Detector_01:CONNECTED.*
   RE2        global:INITIALIZED.*|Detector_01:CONNECTED.*
   STATE      defined
   TO         5
   TYPE       watchdog
   Helper:
     DBLOG:
       state:
         myDbLog:
           TIME       1584267010.12895
           VALUE      defined
   READINGS:
     2020-03-15 11:26:50   Activated       activated
     2020-03-15 11:26:55   Reset           reset
     2020-03-15 11:26:55   Triggered       triggered
     2020-03-15 11:10:10   state           defined
Attributes:
   autoRestart 1
   comment    sendet nach den Start oder nach dem Reset Parameter an den Arduino Detector_01 (LED und Geräuschüberwachung)
   room       System->Protokolle->KeyValueProtocol


Der Arduino-Code, der die Daten empfängt, steht im setup()-Teil des Sketches:
parameter[0] = 90;                           // set all parameters to default values
parameter[1] = 40;
parameter[2] = 20;
parameter[3] = 1000;
parameter[4] = 100;
parameter[5] = 10;
actualTime = millis();
while ((inChar != 10) && (((unsigned long)(millis() - actualTime)) < 15000) && (i < 6)) {       // read parameters until newline is received or time limit of 15 sec. is exceeded
   while (Serial.available() > 0) {
       inChar = Serial.read();
       if (isDigit(inChar)) {                // convert the incoming byte to a char and add it to the string:
      inString += (char)inChar;
       }

    if ((inChar == 32) || (inChar == 10)) {  // if you get a space or a newline store the string's value:
      parameter[i] = inString.toInt();
      i++;     
      inString = "";                         // clear the string for new input:
      }
    } 
  }

ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon-Sensoren; TFA-Sensoren; Steuerung Viessmann-Heizung; Arduinos für Strom-, Wasser-, Gaszähler, Rauchmelder und FI-Schutzschalter