Gladys 4 - Entwicklung des Arduino-Dienstes

Bild Docker verfügbar hier !

Ich bin nicht einverstanden :slight_smile: Viele Nutzer der v3 haben Arduino aus Kostengründen verwendet, meinen Tutorials Buchstabe für Buchstabe gefolgt, ohne alles zu verstehen, und waren froh, nur ein Stück Code auf den Arduino hochladen zu müssen!

Toll!

@billona Was macht der Arduino-Service also bisher? :slight_smile: Ist die Sende-/Empfangsfunktion bei 433 MHz funktionsfähig?

Aktuell noch gar nichts :sweat_smile: Im Moment baue ich gerade das Frontend.

Ich arbeite gerade daran, die Geräte zu formatieren, aber ich habe noch ein paar Probleme. Ich kann meine POST-API-Anfrage nicht ausführen, um das Gerät in der Datenbank zu speichern.

Ich weiß, dass mein Code Fehler enthält. Auch wenn ich immer besser werde, bin ich noch in der Lernphase von Preact. Sobald das Frontend richtig funktioniert, kümmere ich mich um das Backend. Zuerst:

  • Ein js, um Daten an den Arduino zu senden
  • Die Arduino-API muss verbessert werden.

Zusätzlich habe ich mir erlaubt, einige kleine Änderungen vorzunehmen:

  • Ich habe den Parameter Hersteller in der USB-API hinzugefügt, um die Verbindung des Arduino in Zukunft zu automatisieren
  • Ich habe eine kleine Ergänzung im Gerätemodell vorgenommen, um die Arduino-Unterdienste hinzuzufügen (433Mhz-Senden, 433Mhz Chacon-Senden, IR-Senden, …), sowie ein Daten-Pin-Feld, um zu definieren, wohin die Information gesendet werden soll
  • Ich habe die FR-Übersetzung des Arduino-Dienstes erstellt.

Wenn du Feedback zu meinem Code hast, zögere nicht :smile:

Können wir darüber sprechen? Ich denke, das ist die eigentliche Frage! :slight_smile:

Edit: Beim Zurückblättern habe ich deinen Beitrag gefunden, entschuldige, ich hatte die Nachricht vorher nicht gesehen, wegen der Flut an Nachrichten hier, ich poste sie noch einmal:

Die Geschichte des Sub-Dienstes überzeugt mich nicht. Könntest du hier erklären, wie dein Ansatz funktioniert? Wie funktioniert das für den Benutzer?
Und was ist diese Geschichte mit dem Code?

Die Definition der API ist das Wichtigste. Denn sobald die API definiert ist, kann sie nicht mehr geändert werden, bis zur nächsten großen Version von Gladys, da Benutzer von dieser API abhängen werden. Wir wollen sicherstellen, dass diese API für die langfristige Nutzung geeignet ist.

Mmm warum kannst du den Arduino nicht in Form eines Geräts speichern? Ein Arduino = ein Gerät. Du kannst den comPath als Identifikator verwenden und beim Starten den/die Arduino(s) abrufen.

Für den Moment kannst du die UI so codieren, dass sie zunächst nur einen Arduino unterstützt, wenn du nicht zu viel Aufwand betreiben und eine v0.1 relativ schnell herausbringen willst, aber beim Speichern würde ich das eher bei den Geräten als bei den Variablen sehen :slight_smile:

Da ich viel mit den 433-Modulen herumgespielt habe, habe ich diese verwendet

https://github.com/GladysAssistant/gladys-radioemitter

Hallo. Gute Unterhaltung, bis es funktioniert…

Mein Erfahrungsbericht:
Für den SEND-Teil:
Man braucht eine Variable, die angibt, wie oft der Code gesendet werden soll: Manchmal ist es zu viel, manchmal zu wenig. Beispiel: Wenn ich den Code 433 viermal sende, wird der Code nicht in 100% der Fälle von meinem Gerät empfangen (wegen vorübergehender Störungen oder Hintergrundgeräuschen). Wenn ich ihn 15 Mal sende, ertönt mein Alarm zweimal, er hat Zeit, den Code zweimal zu lesen, das ist zu viel. Das könnte ein Gerät mit einem einzigen Senden ein- und ausschalten.

RECEIVER:
Etwas anderes für den Receiver: Manchmal wird der RF433-Code falsch empfangen. Gladys interpretiert den von der Arduino gesendeten Code und erstellt ein Gerät mit einem völlig nutzlosen Code (z.B. « E53F »).
Dadurch kann man die zu kurzen Folgen abschneiden, was die Anzahl der falschen Geräte verringert, aber man muss die Möglichkeit behalten, einen Dialog mit einem kurzen Code vorzusehen. Daher eventuell im Setup parametrisierbar.
Ein weiterer Vorschlag: Du kannst die Arduino in den Lernmodus versetzen (ein Code = ein erstelltes Gerät), dann schaltest du sie aus (ein unbekannter empfangener Code, na und?).

Allgemeiner gesagt, alle im Arduino-Code verwendeten Variablen könnten in das SETUP des Moduls übertragen werden, um alles anzupassen. Wie ich dir am Telefon gesagt habe, für den großen Newbie wie mich, der nicht 1000 Jahre damit verbringen will, alle Variablen zu definieren, muss eine « nicht dumme » Variable standardmäßig eingestellt werden. Oder du kannst einen « Advanced »-Button einfügen, der die Werte anzeigt, die normalerweise nicht vom erfahrenen Benutzer verändert werden.

Aus Nutzersicht sah ich etwas wie dies:

Der Nutzer wählt aus, wie er das Gerät funktionieren lassen möchte, gibt den Daten-Pin und die Nachricht ein. Anschließend sähe es auf Code-Ebene so aus:

Damit kann ein Parameter in der Datenbank gespeichert werden, der sozusagen der Funktion entspricht, die im Arduino aufgerufen wird.

Beispiel:

  • Subservice: emit_ir
  • Data Pin: 3
  • Code: 0xF7C03F

Ich sah einige Komplikationen in Bezug darauf. Aber ich glaube, wir verwechseln etwas unsere Definitionen von Geräten. Also hier ist, was ich mir vorgestellt habe:

Ein einzelner Arduino, der per USB angeschlossen ist, sein Pfad und sein Modell in den Variablen. Anschließend ermöglicht jedes Gerät eine Aktion auf dieser Karte durchzuführen.

Zunächst fand ich keine einfache Möglichkeit, zwei Arduinos in der Datenbank zu verwalten, aber am Ende, wenn wir es ähnlich wie das Serial-Modul von Gladys 3 machen, dann kann es funktionieren :wink:

Ich werde das ändern. :slightly_smiling_face:

Für mich ändert sich der Daten-Pin nicht jedes Mal. Beim Setup beim Anschließen würde es reichen, wie die Anzahl der Wiederholungen. Allerdings ändern sich Protokoll, Pulslänge je nach Gerät.

Na gut, nach etwas Arbeit… Die Arduinos sind jetzt als Geräte implementiert :smile:

So sieht es im Moment aus:

Okay, im Moment ist die UI recht einfach, das gebe ich zu :stuck_out_tongue: Aber sie funktioniert. Ich habe vor, das Design zu verbessern, sobald alles so funktioniert, wie ich es mir wünsche.

Was die Datenbank angeht, sieht es so aus:

@pierre-gilles, um dir ein wenig über meine Ausgangsidee zu erklären, habe ich mich zunächst auf das Datenbankmodell gestützt, das in der API-Dokumentation verfügbar ist. Dieses Modell erwähnt jedoch nicht die Tabelle t_device _param, dieselbe Tabelle, die die RTSP-Kameras verwenden, um die URLs zu speichern. Ich habe also alles so geändert, dass jede Eigenschaft des Arduinos (comPath, Modell) an dieser Stelle gespeichert wird.

Jetzt, wo die Arduinos problemlos gespeichert sind (und vor allem jetzt, wo ich mich mit der Erstellung von Geräten über die Frontend-Oberfläche vertraut gemacht habe :sweat_smile: ), werde ich mich daran machen, andere „Typen“ von Geräten zu erstellen. Für mich würden diese mit einem Arduino verbunden sein und die berühmten Eigenschaften enthalten, die früher erwähnt wurden:

  • Ein Sub-Service, um die Rolle zu spezifizieren (433-Senden, 433-Empfangen, IR-Senden, …)
  • Ein Daten-Pin, um zu wissen, über welchen Weg die Daten auf dem Arduino übertragen werden,
  • Eventuelle Codes, die das Senden betreffen.

Ich denke also den ganzen Tag darüber nach, kläre das auf Papier und sobald alle Zweifel ausgeräumt sind, widme ich mich der Entwicklung :slightly_smiling_face:

Übrigens @pierre-gilles, ich wollte dir eine Bemerkung mitteilen, die ich mir gemacht habe: Ich hatte enorme Probleme, als ich die Löschaktion für Geräte erstellt habe. Dabei habe ich mich an der action.js des RTSP-Camera-Dienstes orientiert.

Das Problem liegt in der Bedingung:

In RTSP Camera ist die Bedingung wie folgt geschrieben:

if(device.created_at)

Doch bei console.log stelle ich fest, dass die Variable

device.createdAt

ist. Und nur deshalb verschwinden meine Kameras nicht aus meiner Datenbank, wenn ich auf Löschen klicke :stuck_out_tongue:

Eine Ausrichtung für die API-Struktur: Offen oder geschlossen:
API geschlossen:
Das Arduino-Modul führt nur einen Code .ino aus, der speziell für das Gladys-Modul entwickelt wurde. Er ist perfekt und hat keine Fehler.
Das Problem ist, wenn ich einen Arduino-Code aus einer anderen Quelle übernommen habe, kann er nicht integriert werden.

API offen: Ein Subservice ist eine Funktion, ein Copy-Paste von beliebigem funktionierendem Arduino-Code. Man muss nur die für den Subservice notwendigen Argumente übergeben.

{
« service »: « MyFunctionTrouveeSurInternet »,
« message »: {
« ARG1 »: PinDeDonnee ,
« ARG2 »: Le_code_à_envoyer
« ARG3 »: « Ich weiß nicht, welcher Parameter für die Funktion nützlich ist »
… 5 Argumente wären ausreichend?
}
}
Im Code .ino:
Void loop()
On serial event: Wenn « Service » = « MyFunctionTrouveeSurInternet » dann führe MyFunctionTrouveeSurInternet (ARG1, ARG2, ARG3..) aus;

Copy/Paste aus dem Internet
MyFunctionTrouveeSurInternet (int PinDeDonnee, Le_code_à_envoyer, etc..)
{ bla, bla, bla }
Meine anderen Subservices
SendRadioCode(PinDeDonnee, Le_code_à_envoyer, protocole, etc) {}
SendIRcode (){}

Wenn man es so macht, und der Typ sich vertut und « A » als Argument für den Pin angibt, dann stürzt es ab.

Schließlich kann in einem Tutorial jeder « seinen » Arduino-Code erstellen, indem er die Argumente in Gladys ersetzt.

@benPi ehrlich gesagt sind deine beiden Vorschläge nicht unvereinbar… Auf gewisse Weise.

Was ich mir vorgestellt habe: eine .ino-Datei, die speziell für das Gladys-Modul entwickelt, ausgereift und fehlerfrei ist. Allerdings würde dieser Code aus bestimmten Funktionen bestehen, die selbst als Subservices fungieren, wie du es beschrieben hast.

Zum Beispiel wird der erste Subservice zunächst die 433-MHz-Ausgabe sein. Danach werde ich den 433-MHz-Ausgang für Chacon hinzufügen. Danach die IR-Ausgabe. Jede dieser Funktionen wird ihre eigene Funktion im Arduino haben, die bei einer Interaktion mit dem Gerät aufgerufen wird.

Man sollte Schritt für Schritt vorgehen, solange man bei den Grundlagen ist.

Zumal nichts dagegen spricht, dass diese .ino-Datei evolvierbar ist. Eine erste Version kann veröffentlicht werden, und wenn der Bedarf entsteht, wird der Service mit den neuen Funktionen aktualisiert und eine neue Version des Arduino-Codes vorgeschlagen.

Hier ist ein Beispiel (ist nicht sauber, entschuldige), von mehreren Unterdiensten im Arduino
Man sendet die für die jeweilige Funktion notwendigen Argumente als JSON.
Ich habe so viel wie möglich kommentiert, damit du den Denkprozess siehst.

/*
 * Receiver ist nicht zwingend erforderlich !!
 * Du kannst einfach nur einen Sender haben.
 * 
 * Konfiguration  
 * Pin D2 => Unterbrechung 0 => Funkempfänger
 * Pin D10 => 433Mhz-Sender
 * 
 * Warten auf ein JSON am seriellen Port. Wenn ein JSON empfangen wird, wird die richtige Funktion aufgerufen
 * Code-Beispiel: (das % ist für das Ende des Befehls). Füge diesen Code in die serielle Schnittstelle ein, um zu testen
 * 
 * {"function_name":"SendRadioCode","ARG1":"5502227","ARG2":1,"ARG3":218}% 
 * => ruft die Funktion SendRadioCode mit dem Code "5502227" CANAL 1 PULSELENGTH 218 auf
 */
 /*
 * IRrecord: Aufzeichnen und Wiedergeben von IR-Signalen als Minimalversion
 * Ein IR-Detektor/Demodulator muss mit dem Eingangs-Pin RECV_PIN verbunden sein.
 * Eine IR-LED muss mit dem Ausgangs-PWM-Pin 3 verbunden sein.
 * Ein Knopf muss mit dem Eingangs-Pin BUTTON_PIN verbunden sein; dies ist der
 * Sende-Knopf.
 * Eine sichtbare LED kann mit STATUS_PIN verbunden werden, um den Status anzuzeigen.
 *
 * Die Logik ist:
 * Wenn der Knopf gedrückt wird, wird der IR-Code gesendet.
 * Wenn ein IR-Code empfangen wird, wird er aufgezeichnet.
 *
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */
 /*PHOTOCELL einfaches Test-Sketch.
Verbinde ein Ende der Photodiode mit 5V, das andere Ende mit Analog 0.
 Dann verbinde ein Ende eines 10K-Widerstands von Analog 0 mit Masse
Für weitere Informationen siehe http://learn.adafruit.com/photocells */

// DIENSTE: RF_433_COM, SERVO_MVT, IR_COM, PHOTOCELL,PIR MVT Detektor

#include <ArduinoJson.h> // SERIAL_COM
#include <RCSwitch.h> // RF_433_COM
#include <Servo.h> // SERVO_MVT
#include <IRremote.h> // IR_COM


//DEFINITION PINS

//PHOTOCELL
int pinPhotoCell = 0; // A0 die Zelle und 10K Pulldown sind mit A0 verbunden
//PIR
int pinPIR = A1; //PIN 15 = A1
//SERVO
int pinServo = 9;//PWM PIN ONLY check TODO: http://....
//RF_433_COM
int pinRF_433_COMrcv = 0;
int pinRF_433_COMsend = 10;
// IR_COM
int RECV_PIN = 11; // VERBINDEN MIT DATEN IR RCVR
int BUTTON_PIN = 12; // KNOPF ZUM DRÜCKEN ZUM SENDEN DES IR-CODES: nur für Tests
int STATUS_PIN = 13; // UNIVERSAL-LED RÜCKMELDUNG STATUS = ARDUINO FUNKTIONIERT

// OBJEKTE UND VARIABLEN

//PHOTOCELL
int photocellReading; // die Analoglesung vom analogen Widerstandsteiler A0
int luminosite; // PHOTOCELL INTENSITÄT VON 0 BIS 1024
//SERVO
int angle;   // Variable zum Halten des Winkels für den Servomotor 0-180°
int i; // Inkrement Servomotor
Servo myServo;  // SERVO
//RF_433_COM
RCSwitch mySwitch = RCSwitch(); //RF_433_COM 
//IR_COM
IRrecv irrecv(RECV_PIN);//IR_COM
IRsend irsend;          //IR_COM
decode_results results; //IR_COM  

//                         SERVICES
//                  SERVICE SEND RF_433_COM:
void SendRadioCode(long code, int canal, int pulseLength) {
      // PulseLength und Kanal werden in Gladys Modul eingestellt.
      // Standardmäßig 1 & 100. Funktioniert auf den meisten Geräten. Überprüfen Sie die Gerätetyp-Konfiguration, um Ihre Bedürfnisse anzupassen.
      
    mySwitch.setProtocol(canal, pulseLength);
    mySwitch.send(code, 24);
}

//                  SERVICE SEND IR_COM:
void sendIRCode(int repeat,unsigned long codeValue,int codeType,int codeLen,unsigned int rawCodes[RAWBUF],int toggle ) {
  
  /* ZUR INFORMATION
   *  Der Codetyp codeType Standard ist -1
    unsigned long codeValue; // Der Codewert, wenn nicht roh
    unsigned int rawCodes[RAWBUF]; // Die Dauer, wenn roh
    int codeLen; // Die Länge des Codes
    int toggle = 0; // Der RC5/6-Toggle-Zustand
   **/
   
  if (codeType == NEC) {
    if (repeat) {
      irsend.sendNEC(REPEAT, codeLen);
      Serial.println("Sent NEC repeat");
    } 
    else {
      irsend.sendNEC(codeValue, codeLen);
      Serial.print("Sent NEC ");
      Serial.println(codeValue, HEX);
    }
  } 
  else if (codeType == SONY) {
    irsend.sendSony(codeValue, codeLen);
    Serial.print("Sent Sony ");
    Serial.println(codeValue, HEX);
  } 
  else if (codeType == PANASONIC) {
    irsend.sendPanasonic(codeValue, codeLen);
    Serial.print("Sent Panasonic");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == JVC) {
    irsend.sendJVC(codeValue, codeLen, false);
    Serial.print("Sent JVC");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == RC5 || codeType == RC6) {
    if (!repeat) {
      // Flip das Toggle-Bit für einen neuen Tastendruck
      toggle = 1 - toggle;
    }
    // Setze das Toggle-Bit in den Code zum Senden
    codeValue = codeValue & ~(1 << (codeLen - 1));
    codeValue = codeValue | (toggle << (codeLen - 1));
    if (codeType == RC5) {
      Serial.print("Sent RC5 ");
      Serial.println(codeValue, HEX);
      irsend.sendRC5(codeValue, codeLen);
    } 
    else {
      irsend.sendRC6(codeValue, codeLen);
      Serial.print("Sent RC6 ");
      Serial.println(codeValue, HEX);
    }
  } 
  else if (codeType == UNKNOWN /* d.h. roh */) {
    // Angenommen 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    Serial.println("Sent raw");
  }
}
 //                  SERVICE SERVO:

void setServo(int angle,int pin) {
  // setze die Servoposition
  myServo.attach(pin); // verbindet den Servo am Pin 9 mit dem Servo-Objekt
  myServo.write(angle);
}

//                  SERVICE PIR MVT:
void pirMvt(){
    if (analogRead (A1)>200){
      Serial.println(analogRead (A1));
      
    angle = map(i, 0, 1023, 0, 179);
    Serial.print("angle: ");
    Serial.println(angle);
    // setze die Servoposition
    myServo.write(angle);
      
    }
    else 
    {
        digitalWrite(7,HIGH);
    }
}


//                  SERVICE PHOTOCELL: 
void photocell (){
      // CODE PHOTOCELL
      photocellReading = analogRead(pinPhotoCell);
            
      // Wir werden einige Schwellenwerte haben, qualitativ bestimmt
      if (photocellReading < 10 ) {
          Serial.println(" - Noir");
        } else if (photocellReading < 200) {
          Serial.println(" - Sombre");
        } else if (photocellReading < 500) {
          Serial.println(" - Lumiere");
        } else if (photocellReading < 800) {
          Serial.println(" - Lumineux");
        } else {
          Serial.println(" - Tres lumineux");
      }
  }

// READ serial: MAIN XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Serial buffer
String command = "";

// End of command marker
char endMarker = '%';

/**SEND SERIAL TO ARDUINO
 * Diese Funktion wird automatisch aufgerufen, wenn Daten am seriellen Port empfangen werden /WÄHLEN SIE DEN RICHTIGEN SERVICE
 */
void serialEvent() {
    //liest alle Daten (leert den Empfangspuffer)
    char last_readed_char = Serial.read();
    if ( last_readed_char == endMarker ) { // Wenn letzter Charakter % ist, dann ist es ein Befehl => executeFunction
      executeFunction(command);
      command = "";
    } else {
      command += last_readed_char;
    }
}
/*
 * Führe die richtige Funktion aus = Befehl empfangen über serielle Schnittstelle {"function_name":"SendRadioCode","ARG1":"5502227","ARG2":1,"ARG3":218}% 
 *                                                  DAS IST {"function_name":"SendRadioCode","ARG1":ARG[1],"ARG2":ARG[2],"ARG3":ARG[3],"ARG4":ARG[4]}% 
 */
void executeFunction(String json_data) {
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& v = jsonBuffer.parseObject(json_data);//zerlegt die Zeichenkette
 
  // TODO: int ARG[]=[v["ARG1"],v["ARG2"],v["ARG3"],v["ARG4"]]; // ARRAY MIT ALLEN GLADYS ARGUMENTEN, DIE MIT DEM BEFEHL KOMMEN
  
  long ARG1=v["ARG1"]; //USW. DER CODE?
  int ARG2=v["ARG2"]; //USW. KANAL?
  int ARG3=v["ARG3"]; //USW. PULSELENTH? TODO: als unsigned definieren, um mit IR_COM zu arbeiten
  unsigned int ARG4=v["ARG4"]; //USW. PIN-NUMMER?
  
  // BEFEHL "SENDRADIOCODE"=> RF_433_COM
  if ( v["function_name"] == String("SendRadioCode") ) 
  {
    SendRadioCode( ARG1,  ARG2,  ARG3);
    // Serial.println("ARG1: " & kanal, "ARG2: " & pulselength, "ARG3: " & code);
  } 
  //BEFEHL "sendIRCode" => IR_COM
  if ( v["function_name"] == String("sendIRCode") )
  {
    sendIRCode(1,ARG1,ARG3, ARG2,ARG4,0);
  }
  //BEFEHL "setServo" => SERVO
  if ( v["function_name"] == String("setServo") )
  {
    setServo(ARG1,ARG2);
  }
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void setup() {
    
  // Open serial communications and wait for port to open: 
  Serial.begin(9600);

  // Receiver RF_433_COM is connected on Arduino Pin #2 by default
  mySwitch.enableReceive(pinRF_433_COMrcv);
  // Transmitter RF_433_COM is connected to Arduino Pin #10  by default
  mySwitch.enableTransmit(pinRF_433_COMsend);
  // Optional set pulse length.
  mySwitch.setPulseLength(385);
  // Optional set protocol (default is 1, will work for most outlets)
  mySwitch.setProtocol(1);
  // Optional set number of transmission repetitions.
  mySwitch.setRepeatTransmit(15);

  
  //PIRPIN A1 = 15
  pinMode (A1, INPUT); // PIR-Ausgang an A1
  pinMode (7,OUTPUT); // AUSGANG D7 = LED TEST
  digitalWrite(7,HIGH);
  delay(1000);

  // SERVICE IR_COM/
  irrecv.enableIRIn(); // Empfänger starten
  pinMode(BUTTON_PIN, INPUT);
  pinMode(STATUS_PIN, OUTPUT); // BETRIEBSANZEIGE?

}

/*
 * <IR_COM> SERVICE
 */
// Speicher für den aufgezeichneten Code
//int codeType = -1; // Der Typ des Codes
//unsigned long codeValue; // Der Codewert, falls nicht roh
//unsigned int rawCodes[RAWBUF]; // Die Dauer, falls roh
//int codeLen; // Die Länge des Codes
//int toggle = 0; // Der RC5/6-Toggle-Zustand

// Speichert den Code für die spätere Wiedergabe
// Die meisten dieser Codes sind nur Protokollierung
/*
void storeCode(decode_results *results) {

  int codeType = results->decode_type;
  int count = results->rawlen;
  if (codeType == UNKNOWN) {
    Serial.println("Empfangener unbekannter Code, wird als Rohdaten gespeichert");
    codeLen = results->rawlen - 1;
    // Zum Speichern von Rohdaten:
    // Ersten Wert (Lücke) entfernen
    // Von Ticks in Mikrosekunden umwandeln
    // Markierungen kürzer und Räume länger anpassen, um die Verzerrung des IR-Empfängers auszugleichen
    for (int i = 1; i <= codeLen; i++) {
      if (i % 2) {
        // Markierung
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
        Serial.print(" m");
      } 
      else {
        // Raum
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
        Serial.print(" s");
      }
      Serial.print(rawCodes[i - 1], DEC);
    }
    Serial.println("");
  }
  else {
    if (codeType == NEC) {
      Serial.print("Empfangener NEC: ");
      if (results->value == REPEAT) {
        // Nicht einen NEC-Wiederholungswert aufzeichnen, da dieser nutzlos ist.
        Serial.println("wiederholt; ignoriert.");
        return;
      }
    } 
    else if (codeType == SONY) {
      Serial.print("Empfangener SONY: ");
    } 
    else if (codeType == PANASONIC) {
      Serial.print("Empfangener PANASONIC: ");
    }
    else if (codeType == JVC) {
      Serial.print("Empfangener JVC: ");
    }
    else if (codeType == RC5) {
      Serial.print("Empfangener RC5: ");
    } 
    else if (codeType == RC6) {
      Serial.print("Empfangener RC6: ");
    } 
    else {
      Serial.print("Unerwarteter codeType ");
      Serial.print(codeType, DEC);
      Serial.println("");
    }
    Serial.println(results->value, HEX);
    codeValue = results->value;
    codeLen = results->bits;
  }
  
}
**/
int lastButtonState;

// </IR_COM>

void loop() {

// PIR-Sensor
pirMvt();
 
// FOTOZELLE 
photocell ();


// <RF_433_COM_RCV>
 
  if (mySwitch.available()) {
    int value = mySwitch.getReceivedValue();

    // AKTIVIEREN SIE DIESE, UM DIE BITLÄNGE, VERZÖGERUNG UND PROTOKOLL ZU ERFAHREN, UM DIESE BEIM LERNEN EINZUSTELLEN
    /*int lenght = mySwitch.getReceivedBitlength();
    int delais = mySwitch.getReceivedDelay();
    int protocol= mySwitch.getReceivedProtocol();*/
    
    if (value == 0) {
      Serial.print("Unbekannte Kodierung");
    } else {
      Serial.print("{\"action\":\"received\",\"value\":");
      Serial.print( mySwitch.getReceivedValue() );
      Serial.println("}");

      // AKTIVIEREN SIE DIESE, UM DIE BITLÄNGE, VERZÖGERUNG UND PROTOKOLL ZU ERFAHREN, UM DIESE BEIM LERNEN EINZUSTELLEN
     /* Serial.print(mySwitch.getReceivedBitlength());
      Serial.print(mySwitch.getReceivedDelay());
      Serial.print (mySwitch.getReceivedProtocol());*/       
    }
    delay(200); 
    mySwitch.resetAvailable();
    }
// </RF_433_COM_RCV>

// <IR_COM SERVCE>

     // Wenn die Taste gedrückt wird, wird der Code gesendet.
  int buttonState = digitalRead(BUTTON_PIN);
  
  if (lastButtonState == HIGH && buttonState == LOW) {
    Serial.println("Freigegeben");
    irrecv.enableIRIn(); // Empfänger wieder aktivieren
  }

  if (buttonState) { // WENN SIE DIE TASTE DRÜCKEN
    Serial.println("Gedrückt, senden");
    digitalWrite(STATUS_PIN, HIGH);
    //sendIRCode(lastButtonState == buttonState, ,,,); Beispiel IR-Code zum Ausprobieren
    digitalWrite(STATUS_PIN, LOW);
    delay(100); // Warten Sie etwas zwischen den erneuten Übertragungen
  } 
  /*
  else if (irrecv.decode(&results)) { // WENN DATEN EMPFANGEN WERDEN
    digitalWrite(STATUS_PIN, HIGH);
    storeCode(&results);
    irrecv.resume(); // Empfänger fortsetzen
    digitalWrite(STATUS_PIN, LOW);
  }
  */
  lastButtonState = buttonState;
  // </IR_COM SERVCE>
  
}

Ich habe ein kleines Problem, das ich nicht lösen kann und das die Geräte-Seite betrifft.

Ich habe die Funktionsweise der Setup-Seite dupliziert, um sie an die Geräte-Seite anzupassen. Die Geräte-Hinzufügung basiert auf demselben Code. Ich kann also so viele Arduino-Geräte hinzufügen, wie ich möchte, in die Datenbank. Aber wenn ich Geräte über die Geräte-Seite hinzufügen möchte, erhalte ich einen Fehler 422.

422 Fehler

Das im Parameter der POST-API-Anfrage übergebene JSON ist korrekt, da es im console.log genauso angezeigt wird wie bei den Arduino-Geräten. Aber ich kann nicht sehen, wo mein Fehler liegt. Könnten Sie mir bitte helfen?

Vielen Dank :smile:

du musst die Erkennung von chinesischen Arduino-Klonen in setup.js hinzufügen

Verdammt, ich beginne zu verstehen, wie das Chaos funktioniert

// foreach port we test if it is an arduino ports.forEach(function(port) { if (port.manufacturer && port.manufacturer.toLowerCase().search("arduino") != -1) { arduinos.push(port); } **else if (port.manufacturer && port.manufacturer.toLowerCase().search("qinheng") != -1){** arduinos.push(port);

Das ist bereits geplant, ich habe es auf meiner Roadmap notiert. Wenn du meinen Code ansiehst, wirst du eine erste Liste von Herstellern sehen, die chinesische Klone umfasst. Außerdem kannst du in der Konfigurationsseite den Hersteller des an den ComPath angeschlossenen Geräts in der Liste sehen (Beispiel: /dev/TTYUSB0 - 1a86).

Aber im Moment hat die Behebung des Problems, das ich früher erwähnt habe, Vorrang, der Fehler 422 POST API, obwohl die Syntax korrekt ist.

Sobald das erledigt ist, werde ich diese Geräte verbessern, um die Arduino-Dienste bereitzustellen.

Ja! Ich habe immer noch keinen Zugriff auf deinen Code, ich melde nur die Probleme der Version 3 weiter. Nur für den Fall. Wenn du das berücksichtigt hast, ist das super, für dein anderes Problem kann ich dir nicht helfen.

Top danke vielmals :wink:

Du kannst meinen Code hier sehen:

Die Liste der Hersteller ist in der action.js der Seite definiert:

Aktuell habe ich das in meinem Arduino mit Gladys, V3, gemacht, das ist nicht kompliziert, ich habe einen Knopf in Gladys, um es zu aktivieren/deaktivieren. Wenn du Hilfe brauchst, lass es mich wissen.

Wie verwaltest du die Unterdienste? Ist das im Arduino-Dienst oder abhängig vom Arduino-Code?

Wenn es direkt im Dienst ist, warum spezifisch Chacon angeben? Was ist mit den anderen?

Eigentlich ist ein Service eine Arduino-Funktion, die den Code enthält. Wenn Gladys an den Arduino „service": « RF433_CHACON » sendet, wird diese Funktion aufgerufen.
Deinen persönlichen Arduino-Code rufst du « perso » auf und in deiner perso-Funktion setzt du deinen Arduino-Code ein.
daher kann jede Arduino-Funktion aufgerufen werden.

Also hängt es im Grunde genommen vom Arduino-Code ab.
Also von allem außer der Art und Weise, wie die Dienste abgerufen und angezeigt werden, sowie den möglichen Interaktionen mit Gladys, richtig?
In diesem Fall: Yeah, das ist super! :slight_smile: