Datenaustausch per LAN

Hallo,

ich möchte gerne verscheidene LAN devices (Raspberry, Arduino etc.) mit der IP Symcon bi-directional über LAN kommunizieren lassen. Wie habt Ihr das Problem gelöst ?
Ich bin auf der Suche nach einer Lösung die man leicht auf verschiedenen Plattformen einsetzen kann. Ich dachte an XML oder evtl. direkt per client socket. Ich bin mir sicher da gibt es schon gute Lösungen wobei ich im Forum noch nichts wirklich passendes gefunden habe.

Danke für Eure Hilfe!

Martin

Servus

Gegenfrage: was gefällt dir denn an den verschiedenen im Forum verwendeten Ansätzen nicht ?
Da ist ja für jeden Geschmack etwas dabei.

bb

ich habe nichts gefunden wie ich z.B. eine XML datei an IP Symcon senden kann oder zumindest eine URL aufrufen kann in der ich variablen an IP Symcon übergeben kann. z.B. in der art http://ip-syncon/cgi?variable=1.
Ich würde eine kommunikation über http bevorzugen, weil ich das am universellsten finde und auch über WAN funktionieren sollte.

vielleicht habe ich ja auch nur noch nicht richtig gesucht, darum bin ich fuer jeden Tipp dankbar.

Martin

Wenn du eh per http arbeiten willst solltest du den Begriff „Webseite“ mal in deine Suche mit einfließen lassen. Gibt gefühlte 1001 Lösungen um irgendwelche infos per http von irgendwelchen webseiten zu lesen. Es gibt diesbezüglich keinen Unterschied zwischen einem XML und einer html Datei. XML ist sogar einfacher weil das parsen weg fällt.

Edit:

file_get_content dürfte auch aufschlussreich sein

Gruß,

Toni

Danke Toni, aber was du beschreibst (URLs auslesen) mache ich schon.

was ich machen möchte ist daten AN die IP Symcon zu senden. d.h. auf der IP Symcon eine URL aufrufen und damit daten übergeben. dazu habe ich leider nichts gefunden.

Also konkretes Beispiel. Derzeit steuere ich meine VU+ über diverse URLs von der IP Symcon aus. Jetzt möchte ich den spiess aber umdrehen und von der VU+ aus z.b. über die IP Symcon das licht einschalten lassen. D.h. ich muss diesen befehl von der VU+ an die IP Symcon senden und das würde ich am liebsten per http machen. ich hoffe ich hab mich jetzt klar ausgedrückt :wink:

Danker fuer eure Hilfe!

Martin

Http funktioniert im einfachsten Fall nach dem Client Server Prinzip. Das heisst du brauchst einen Server und einen Client. BiDi braucht 2 Server und 2 Clients. Logisch.

Deine VU+ hat ein Webinterface. Dieses stellt einen Server dar, den du über PHP als Client bedienst. Das selbe passiert bei IPS. Das IPS-Webinterface ist ja auch nur eine Webseite. Wenn du von deiner VU+ aus die IP des Servers ausließt bist du schon auf dem Webserver von IPS. Über die JSON Schnittstelle kannst du direkt IPS steuern. Bissi weniger flexibel, aber einfacher wenn man noch nicht mit JSON gearbeitet hat, kannst du aber auch direkt PHP Seiten aufrufen, die in IPS irgendwas steuern. Das ist in beiden Richtungen der selbe Vorgang.

Toni

Erstelle Dir einfach über den Explorer ein PHP-Skript in IPS\webfront\user. Zum Beispiel: webfront/user/mein_empfaenger.php. Dieses Skript ist dann per http://ips:82/user/mein_empfaenger.php per HTTP erreichbar. Diesem Skript kannst Du per GET oder POST Daten übergeben und im Skript dann verarbeiten. Es stehen Dir dort alle IPS-Funktionen zur Verfügung.

Ich hoffe das war es was Du suchtest.

Vielen Dank Titus!

Das ist ja viel einfacher als gedacht :slight_smile: Mir war zwar klar, dass ich dort Seiten ablegen kann und auch XML Dateien zur Verfügung stellen kann, dass ich aber auch gleich IPS Skripte ausführen kann wusste ich nicht.

Hat vielleicht noch wer ein beispielscript, wie man variablen aus der URL parsen kann ?

Vielen Dank!

Martin

Beispielprojekt:
falls Du den DB-Analyzer im Einsatz hast (was nicht ist kann ja noch werden): dort werden verschiedene Methoden paktiziert. Die Empfangs-Scripte (um u.A. Variablen anzusteuern) liegen im Ordner „webfront\user\RSDB_Analyzer“. Die Übergabe von Daten/Anforderungen realisere ich (je nach Situation) vie Get/Post.
Man kann (wie im DB-Analyzer realisiert) z.B. aus dem sendenden (IPS-)Script die Variablen-ID und den Wert übergeben , das Empfangsscript nimmt beide Werte auf und setzt die Anforderung innerhalb der Laufzeitumgebung von IPS um.

nur der Vollständigkeit halber, falls ein anderer User auch mal das problem haben sollte:

mit dem explorer unter webfront/user/ ein script „test.php“ anlegen

Script mit folgendem inhalt (47966 nat. mit der passenden variable ersetzen) füllen (kann man z.B. mit notepad machen):

<?
SetValue(47996 , $_SERVER[‚QUERY_STRING‘]);
?>

und schon wird beim Aufruf von:

http://ip-symcon-IP:82/user/test.php?testwert

alles hinter dem „?“ in die IP-Symcon variable geschrieben.

Danke noch mal für eure Hilfe!

Martin

Hallo zusammen,

bislang ließ ich IPS mit Arduino per MOD-Bus kommunizieren in beide Richtungen.
Da es nur um Messwerte und Steuerungsaufgaben ging war das trotz Polling auch brauchbar.

Die oben gezeigte Lösung ist aber derart genial dass ich das zumindest beim Weg Arduino --> IPS umstellen werde.

Aber Frage:
Hätte schon jemand ein Beispiel fertig für die Strecke IPS --> Arduino? (insbesondere Sketch)?

Alexander

Die Frage ist zwar schon was länger her, als Arduino-Neuling bin ich erst jetzt auf den Thread aufmerksam geworden und stelle mal meine Bastelarbeit vor:

Als „proof-of-concept“ einer „eierlegende Arduino-Ethernet Wollmilchsau“ habe ich einen Sketch für einen HTTP-Server und HTTP-Client auf einen Arduino Ethernet geschoben. Es ist als Versuchsbeispiel für eine eigene „HTTP-API“ bzw. zum Ansteuern jedes anderen Servers mit HTTP-API und PUT-Befehlen (wie z.B. die Mobotix-Kameras oder eben eine Web-Server-Instanz in IP-Symcon)

Im Beispiel habe ich ein Modellbau-Servo, einen Taster und 3 Dallas 1-Wire Temperatur-Sensoren angeschlossen.

Je nach aufgerufener Seite und PUT-Parametern kann das Servo verfahren werden, Taster/Schalter-Position oder Temperaturen ausgelesen werden oder durch Seitenaufruf oder Taster-Ereignis wiederum ein anderer WEB-Server aufgerufen werden - was das Pollen spart.


/*
  Proof of concept "HTTP-API" Web Server und Client
  Beispiel:
  WEB-SERVER: - per HTTP-GET Aufruf:
   Drei 1-Wire Temp. Sensoren Auslesen
   Die 1-Wire Temp. Sensoren periodisch mit Browser auslesen 
   Alle angeschlossenen 1-Wire Adressen auslesen 
   Taster/Schalterposition auslesen
   Einen Servo in die per PUT übergebene Position (0-180°) fahren
  WEB-CLIENT:
  ereignisgesteuert einen HTTP-Server mit erignisabhängiger Parameterübergabe von HTTP-Seite und PUT
   Ereignisse werden im LOOP-Teil des Sketches abgefragt oder
   durch Seitenaufruf auf dem SERVER ausgelöst   
*/

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h> 

Servo myservo;  // Servo Objekt 
int svo; // Sollwert (0-180) für den anzufahrenden Servowinkel 

// 1-Wire an PIN 3:
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
// Dallas Temperatur - Sensoren: 
DallasTemperature sensors(&oneWire);

// Adressen der Temp-Sensoren 
DeviceAddress aThermo = { 0x10, 0x3C, 0x7F, 0xAD, 0x02, 0x08, 0x00, 0x64 };
DeviceAddress bThermo = { 0x10, 0x41, 0x1E, 0xAD, 0x02, 0x08, 0x00, 0x6A };
DeviceAddress cThermo = { 0x10, 0x27, 0xD6, 0xAD, 0x02, 0x08, 0x00, 0x07 };

float tempC; // Variable zur Zwischenspeicherung der Temperaturen


String stringOne; // Variable zum extrahieren der GET-Parameter eines HTTP-Aufrufes

// MAC Addresse und IP Addresse des Arduino HTTP-Servers hier eingeben:
byte mac[] = { 0xDE, 0xDE, 0xBF, 0xEF, 0xEE, 0xED };
IPAddress ip(192,168,2,22);
EthernetServer server(80); // Port 80

// HTTP-Client:
EthernetClient httpclx;
char hpserver[] = "192.168.2.124"; // IP-Adresse des HTTP-Servers, der vom Arduino-Client aufgerufen wird

// Taster/Schalter an PIN 5
int pushButton = 5; // Taster oder Schalter an PIN 5
int buttonAlt = 1; // letzter Status des Schalters ( 0 oder 1)

unsigned long previousMillis;  // Variable zur Zeitmessung für die Software-Tasterentprelllung

void setup() {
  // HTTP Server starten:
  Ethernet.begin(mac, ip);
  server.begin();

  // 1-Wire-Temp.Sensoren 
  sensors.begin();
  // Auflösung auf 10 bit setzen
  sensors.setResolution(aThermo, 10);
  sensors.setResolution(bThermo, 10);
  sensors.setResolution(cThermo, 10);
  
  myservo.attach(7);  // Das Servo ist an pin 7 angeschlossen 

  pinMode(pushButton, INPUT_PULLUP); // internen Pull-Up-Widerstand für den Taster verwenden
}


// ***** Auslesen der Adressen der angeschlossenen 1-Wire-Geräte und Ausgabe an den HTTP-Server 
void discoverOneWireDevices(EthernetClient clx) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  clx.print("1-Wire Adressen werden ausgelesen....<br>");
  while(oneWire.search(addr)) {
    clx.print("<p>\'1-Wire\' mit der Adresse: ");
    for( i = 0; i < 8; i++) {
      clx.print("0x");
      if (addr[i] < 16) {
        clx.print('0');
      }
      clx.print(addr[i], HEX);
      if (i < 7) {
        clx.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        clx.print("CRC falsch!!!<br>");
        return;
    }
  }
  clx.print("<p>fertig<br>");
  oneWire.reset_search();
  return;
}

// ****** Temperatursensor auslesen und über HTTP-Server ausgeben 
void printTemperature(DeviceAddress deviceAddress, EthernetClient clx)
{
  float tempi = sensors.getTempC(deviceAddress);
  if (tempi == -127.00) {
    clx.print("Error getting temperature");
  } else {
    clx.print(": ");
    clx.print(tempi);
  }
  //clx.print("<br />");
}

// **** HTTP-GET Aufruf  
void httpRequest(EthernetClient sender, String seite) {
  // if there's a successful connection:
  if (sender.connect(hpserver, 8081)) {
    sender.println(seite);
    sender.println("Host: www.arduino.cc");
    sender.println("User-Agent: arduino-ethernet");
    sender.println("Connection: close");
    sender.println();
    sender.stop();
  } 
  else {
    sender.stop();
  }
}

void loop() {
  // Tastaturabfrage bearbeiten und wenn Taste gedrückt wurde Seite auf anderen HTTP-Server aufrufen
  int buttonState = digitalRead(pushButton);
  unsigned long currentMillis = millis();
  if (buttonState==0) { // Taster gedrückt 
    if (buttonAlt==1) {
    // nur bei wechsel auf 0 httprequest aufrufen
    httpRequest(httpclx, "GET /lichter_schalten.php?id=48 HTTP/1.1"); // z.B. die Seite lichter_schalten.php mit dem PUT Parameter
    // id=48 aufrufen
    }
    buttonAlt=0;
    previousMillis = millis();
  }else{ // Zur Tastenentprellung kann erst nach 0,5 sekunden ein nochmaliges Drücken registriert werden
     if(currentMillis - previousMillis > 500) {
       buttonAlt = 1;
     }
     
  }
  // Wird unser HTTP-Server aufgerufen ????:
  EthernetClient client = server.available();
  if (client) {
    
    boolean currentLineIsBlank = true;
    String buffer = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        buffer+=c;
	// In buffer steht der ankommende HTTP-GET-Header 
        if (c == '
' && currentLineIsBlank) {
          // Üblicher Response-Header zurückschicken
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    
          if (buffer.indexOf("GET /t.php")>=0) {
	    // wenngewünscht, eine Meta-Refresh, damit der Browser periodisch eine Seite mit z.B. Messwerten aufruft 
            client.println("<meta http-equiv=\"refresh\" content=\"3\">");
          }
          
          if(buffer.indexOf("GET /a.php")>=0) { // wenn die Seite a.php aufgerufen wurde
            client.print("Mögliche Seitennaufrufe a.php, t.php, w.php, nr.php?a=9999 oder irgendeine andere Seite");
	    // 1-Wire Adressen werden angezeigt
            discoverOneWireDevices(client);
          }else if(buffer.indexOf("GET /w.php")>=0) { // wenn w.php aufgerufen wurde
            client.println("Die Anfrage wurde weitergeleitet");
            httpRequest(httpclx, "GET /lichter_schalten.php?id=48 HTTP/1.1");
          }else if(buffer.indexOf("GET /pin.php")>=0) {
            client.print("Status PIN 5: ");
            client.print(buttonState);
          }else if(buffer.indexOf("GET /nr.php")>=0) { // mit /nr.php?a=0000 bis 9999 wird das Servo gesteuert
	    // Werte kleiner 0 oder größer 180 werden gekappt
            stringOne=buffer.substring(14,18); 
                        
            svo=stringOne.toInt();
            
            // nur werte von 0-180 an das Servo
            svo = min(svo, 180); 
            svo = max(svo, 0);
            client.print("Servo auf ");
            client.print(svo); 
            myservo.write(svo);  
          }else{
            // Anzeige der Temperaturen , falls ein anderer Seitenname verwendet wurde        
            sensors.requestTemperatures();
            client.println("Sensor A ");
            printTemperature(aThermo,client);
            client.println("<br /> Sensor B ");
            printTemperature(bThermo,client);
            client.println("<br /> Sensor C ");
            printTemperature(cThermo,client);
          }
          buffer="";
          client.println("</html>");
          break;
        }
        if (c == '
') {
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    Schliessen der Verbindung:
    client.stop();
    
  }
}


Jetzt bin ich noch auf der Sucher nach einer Möglichkeit, den Arduino über das Ethernet mit neuen/geänderten Sketchen zu versorgen.

Rolf