Wie mehrere IPS-Server miteinander koppeln (Datenaustausch via JSONRPC)?

Hallo,

nachdem ich in die Verlegenheit kommen könnte, evtl. einen zweiten IPS-Server für einen Anwendungsfall (Broadlink RM Modul - Seite 7) zu installieren, interessiert mich vorher das grundsätzliche Zusammenspiel zwischen ihnen und das Handling mit einem solchen Konstrukt. Dafür habe ich zum Thema „Datenaustausch“ in der Doku gelesen (Datenaustausch — IP-Symcon :: Automatisierungssoftware). Die ersten Gehversuche zeigen schon mal Erfolge. Dennoch bleiben Fragen.

Was habe ich bereits getan?

Auf dem Master-IPS:

[ul]
[li]Boolean-Variable angelegt[/li][li]Zwei Scripts („Lampe lokal umschalten“ und „Trigger-Script“) angelegt[/li][li]Ereignis (auf Variablenänderung der lokalen Lampe) angelegt[/li][/ul]

Auf dem Slave-IPS:

[ul]
[li]Boolean-Variable angelegt[/li][/ul]

Script „Lampe lokal umschalten“:

<?

$id_local = 12305 /*[Scripte\Datenaustausch mit zweitem IPS\Lampe auf Master-IPS]*/;
SetValue($id_local, !GetValue($id_local));

?>

Script „Trigger-Script“:

<?

// Aufbauen einer Verbindung zum Slave-IPS
$rpc = new JSONRPC("http://user:password@99.99.99.99:3777/api/");

// ID der Boolean-Variable auf dem Slave-IPS
$id_remote = 46667;

if($_IPS['SENDER'] == "Variable")
	{
	$id_local = $_IPS['VARIABLE'];
	$rpc->SetValue($id_remote, GetValue($id_local));
	
	//Prüfen, ob das Ziel auch korrekt geschrieben wurde
	if ($rpc->GetValue($id_remote) == GetValue($id_local))
		{
		IPS_LogMessage("Script Datenaustausch (Trigger-Script)", "Hat alles geklappt!");
		// ... weitere Aktionen
		}
	}

?>

Beobachtung:
Wird die Lampe am Master umgeschaltet, ändert die auch die Variable auf dem Slave-System entsprechend mit - Erfolg:)

Fragen:

[ul]
[li]In diesem Setup muss die Struktur gedoppelt vorliegen, d.h. alle Variablen auf dem Slave müssen so auch auf dem Master angelegt sein. Gibt es stattdessen die Möglichkeit, mit Links auch serverübergreifend via JSONRPC zu arbeiten?[/li][li]So wie ich das Broadlink-Modul (Broadlink RM Modul) verstehe, legt es weitere Variablen (hier: auf dem Slave) an, sofern ihm eine neue Funksteckdose bzw. IR-Befehl bekannt gemacht worden ist. Wie kann man solche Variablen automatisch auch auf dem Master anlegen lassen?[/li][li]Wie läßt sich eine Art bidirektionale Kommunikation verwirklichen, sodass bei Änderungen (manuell, ausgelöst, automatisch, …) egal auf welcher Seite, beide Werte immer gleich sind?[/li][li]Kann man z.B. auf der Slave-Seite feststellen, ob die dortige Variable lokal oder remote via JSONRPC verändert worden ist? Das könnte in einem dortigen Trigger-Script hilfreich für weitere Aktionen sein. Habe bei den Systemvariablen Systemvariablen — IP-Symcon :: Automatisierungssoftware auf den ersten Blick nichts derartiges gefunden.[/li][/ul]

Ein interessantes Thema!
Ich betreibe neben einem IPS auf Windows inzwischen auch einen RASPI mit IPS in der Naehe meiner 1-wire Sensoren im Heizungskeller. Zur Visualisierung setze ich urspruenglich das Dashboard auf dem WIN System ein, inzwischen rueste ich Stueck fuer Sueck auf IPS-Studio um … habe also das Problem Informationen von beiden IPS Servern auf einer Visualisierung zu zeigen. Meines Wissens nach ist der Austausch ueber JSONRPC der einzige Weg da die Visualisierung immer nur an einen Server gekoppelt sein kann (sollte ich das falsch sehen so belehre man mich eines Besseren …waere dankbar!).
Der Austausch ueber JSONRPC funktioniert, ist aber viel Tipparbeit.

Da ich bidirektional Informationen austauschen moechte habe ich mir einen Mechanismus gebaut:

Ein Script ‚Datenaustausch_Define‘ <= hier sind in Arrays die notwendigen Informationen zu Ziel Server und Variablen hinterlegt.

Ein Script ‚Datenaustausch‘ bindet das Define Script ein und

  • prueft ob ‚entfernter‘ Server online ist
  • liest IP Adresse des entfernten Servers
  • ermittelt ID der Ursprungsvariablen (Link zur Variablen wird unter das Script gehaengt)
  • ermitteln der notwendigen Informationen um Zielvariable anzusprechen
  • schreibt Wert auf Zielvariable auf dem entfernten Server

Das Define liegt auf beiden Server und wird bei Aenderungen (ich baue staendig weiter am System) synchron gepflegt, das Script zum Datenaustausch ist ebenfalls identisch. Soll eine neue Information ausgetauscht werden lege ich nur einen Link der Variablen unter das Script und setze einen Trigger bei Variablenaenderung auf das Script.

Eigentlich recht umstaendlich … hat das jemand besser geloest? Vielleicht gibt es einen genialen Kopf der ein entsprechendes Modul programmieren kann?

Gruss, Michael

Falls jemand Interesse an meinen Scripten hat … einfach melden.

In PHP gibt es über „string serialize ( mixed $value )“ die Möglichkeit Arrays als String abzulegen. Mit „mixed unserialize ( string $str [, array $options ] )“ kann der String wieder in ein Array zurückverwandelt werden.

Also : Alle Variablen als String auf beiden System speichern und einmal pro Sekunde (oder was auch immer) Synchronsieren und schon ist das Problem gelöst.
Es hilft natürlich wenn es einen eindeutigen Master gibt. Falls nicht Zeitstempel der Änderung mitspeichern und auswerten

Dann müssen doch Variablen schon auf beiden Seiten vorhanden sein, oder? Und man prüft nur auf evtl. unterschiedliche Werte?

@Michael: würdest du deine Scripte mal online stellen?

Ich bastele gerade daran, die Variablenkonfigs auszulesen und dann auf den anderen Server zu übernehmen samt der aktuellen Werte.

Ja, Vorrausetzung ist auch bei mir, das auf beiden Seiten die Variablen existieren.
Stelle nachher meine Scripts zum Synchronisieren hier rein.
Gruss Michael

Ja, Vorrausetzung ist auch bei mir, das auf beiden Seiten die Variablen existieren.

Nützlich ist manchmal auch das Studium diverser Hilfe-Bereiche wie z.B. „IP-Symcon - Wie kann ich… 2.0“ zu diesem Thema.

Da bei mir neben dem Wirksystem auf Windows mit IPS noch 4 andere Raspis mit IPS und denselben Skripts zusammenarbeiten sollen, verwende ich diese Methode prinzipiell. Hatte ich auch mal hier und da beschrieben.

Meine Programmierstrategie für IPS:

  1. Alle Objekt werden nicht händisch erzeugt, sondern durch ein Konfigurationsskript, das entsprechend einer Konfigurationsliste die komplette Struktur anlegt und gleich die Idents einträgt. Das Konfigurationsskript läuft 1x lokal und wird dann an die anderen Raspis per JSON übertragen und ausgeführt.
    case 'Beispiel':    // ein Beispiel für eine Konfiguration
               // ($Position = '', $ParentId = '', $Ident = "", $Visable = '-', $Name )
        $KAT = CreateCategory (100, 0, 'Ident', '+', 'Name');    // Kategorie als Root
        if ($KAT) { // ($Position = 0, $ParentId, $Ident = "", $Visable = '-', $Name, $Type, $Profile = "", $Action = null, $ValueDefault = '', $Icon = '' )
            $VIS = CreateVariable (0, $KAT, "VIS", '+', 'Variable zur Visualisierung', 3, "~HTMLBox", null, '', '');
                    // ($Position = 0, $ParentId, $Ident = '', $Visable = '-', $Name, $Ext = 'ips.php', $File = '')
            $MON = CreaEmptScript (2, $KAT, 'MON', '-', 'Anzeige-Skript');    // Skript zur Anzeige, Position 2, Hidden
            $ACT = CreaEmptScript (3, $KAT, 'ACT', '-', 'Ausführungs-Skript');    // Skript zur Ausführung
            if ($ACT) {
                $DTA = CreateVariable (3, $ACT, "DTA", '+', 'Variable zur Datenspeicherung', 1, "~String", null, '', '');    // liegt unter 'ACT'
                $TRG = CreaTimerCyclM ('', $ACT, 'TRG', '+', 'Trigger', 8, '+');        // Timer, noch nicht aktiviert
                CreaEmptScript (2, $ACT, '', '+', 'Linux', 'sh');       // ein Batchfiles für Linux (Linux.sh) als Beispiel
            }
        }
        break;

  1. Da die ObjektIds willkürlich von IPS vergeben werden (warum auch immer) und damit auf den verschiedenen PCs garantiert unterschiedlich sind, adressiere ich Objekte nicht über die ObjektId, sondern über die Struktur, die auf allen Systemen gleich ist, siehe dieses Skript.

In meinem „Digitalen Testament“ hab ich u.a. folgendes hinterlassen:

// Verwendung von gleichbenannten Objekten auf allen PCs
// Skripte und andere Objekte werden meist durch 'IdentStrings' aufgerufen (statt mit der Objekt-Nummer, die in jedem PC anders ist), d.h. ihre Lage darf nicht verändert werden; 
// Prinzip: Unterhalb einer Kategorie mit einer im IPS uniquen Ident stehen Skripte, Variablen usw. Deren Ident kommen vielfach im System vor; sie werden 
// durch den 'IdentString' aufgerufen, der aus den Idents der untereinanderliegenden Objekte besteht. 
// Aufruf durch function GetObjectIDByIdentPath ($Path)
// diese steht in einem Skript 'ObjIDsIPS.ind.inc.php' (oder in "DefSemap.inc.php") das bei allen Skripten inkludiert wird und bei jedem PC individuell ist

/*
  $S = Skripte
  Idents:
 * VIS  String-Variable als HTML-Box (?-Anzeige)
 * DTA  String-Variable als Speicher (?-Daten)
 * MON  Skript zur Befüllung von VIS in Abhängigkeit von DTA (?_Mon.ips.php)
 * EVT  Skript zur Ereignisverarbeitung (?_Act.ips.php)
 * ACT  Skript zur Aktionsverarbeitung (?_Act.ips.php)
 * AKT  Skript zur Aktionsverarbeitung (?_Act.ips.php)
 */

// --------------------------------------------
// Kommunikation
// erfolgt zwischen den PCs mittels JSON, für Senden und Empfangen je ein Skript, das aufgerufen werden kann und dessen Absturz nicht schadet:
$ObjRX  = 34016 /*[Aktoren\JSON\JSON_RX]*/; // JSON-Receice (JSON_RX.ips.php) ObjID lokales Skript das per JSON von anderen IPS-Systemen zur Datenübergabe aufgerufen wird
$ObjTX  = 44644 /*[Aktoren\JSON\JSON_TX]*/; // JSON-Transmit(JSON_TX.ips.php) ObjID lokales Skript das per JSON an andere IPS-Systeme sendet

// --------------------------------------------
// Die Skripte für die Raspis werden auf dem Server entwickelt und stehen z.B. hier:
$ACT = 20653 /*[CONFIG\StrukturDefinitionen\Strukturen für Raspis\BLEscan\BLEscan_Act]*/;

// An die Raspis werden sie mit einem JSON-Skript transferiert:
$ACT = 29466 /*[Aktoren\JSON\JSON_Trans]*/;


Viele Grüsse
Harald

Hier wie ich es zur Zeit löse:

Ein ‚Define‘ File auf jedem Server (halte ich der Einfachheit halber auf allen gleich), exemplarisch:

 <?

 //Array der Variablen mit System, Name und ID
 #Achtung erstes Element des Arrays muss leer sein!
 
 
# Block für Variablem auf dem aktiven Server
    # Serverinformationen
    $server[] = array('Name' =>"",'IP' => "");
    $server[] = array('Name' =>"Demo Server", 'IP' => "194.160.98.50");
    $server[] = array('Name' =>"RASPI 1", 'IP' => "194.160.98.33");
    $server[] = array('Name' =>"RASPI 2 piVCCU", 'IP' => "194.160.98.32");
    $server[] = array('Name' =>"Raspberry Steuerung Keller", 'IP' => "194.160.98.26");    # Steuerung Keller

    # Variablen für Status LAN HW (online, offline, inaktiv)
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog LAN/Demo Server", 'ID' => 40981);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog LAN/RASPI 1", 'ID' => 24486);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog LAN/RASPI 2 piVCCU", 'ID' => 16241);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog LAN/Raspberry Steuerung Keller", 'ID' => 31715);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Watchdog LAN/Demo Server", 'ID' => 57351 /*[Watchdog\LAN HW\Watchdog LAN\Demo Server]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Watchdog LAN/RASPI 1", 'ID' => 34276 /*[Watchdog\LAN HW\Watchdog LAN\RASPI 1]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Watchdog LAN/RASPI 2 piVCCU", 'ID' => 11822 /*[Watchdog\LAN HW\Watchdog LAN\RASPI 2 piVCCU]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Watchdog LAN/Raspberry Steuerung Keller", 'ID' => 13860 /*[Watchdog\LAN HW\Watchdog LAN\Raspberry Steuerung Keller]*/);

    # Variablen für Fehler 
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog Status/Watchdog Status String", 'ID' => 39117);    
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog Status/Datenaustausch", 'ID' => 20412);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Watchdog Status/LAN HW", 'ID' => 33519);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Watchdog Status/Datenaustausch", 'ID' => 29938 /*[Watchdog\Watchdog Status\Watchdog Status\Datenaustausch]*/ );
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Notification Control Test/Notification Control Test", 'ID' => 30182 /*[Watchdog\Notification Control Test\Notification Control Test\Notification Control Test]*/ );

# Block für Datenaustausch zwischen den Servern
    # Variablen für Temperaturen
    $variable[] = array('Server' => "", 'Name' => "", 'ID' => "");
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18B20 Pool oben B1000006779B8C28/Temperatur", 'ID' => 55035);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18B20 Pool mitte A200000677F73328/Temperatur", 'ID' => 59059);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18B20 Pool unten 8E0000067802D628/Temperatur", 'ID' => 28399);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18B20 Pool Solar Dach 460416C1CE6DFF28/Temperatur", 'ID' => 15371);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Sauna 8400080215A5A10/Temperatur", 'ID' => 30406);
    #$variable[] = array('Server' => "Demo Server", 'Name' => "Temp Pool Filter In (28b84d78060000d8)/Temperatur", 'ID' => 34645);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18B20 Speicher 1 1000802E60710/Temperatur", 'ID' => 35896);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18B20 Speicher 2 CA000802157C410/Temperatur", 'ID' => 30268);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Speicher 3 3F000802A08F10/Temperatur", 'ID' => 46010);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Speicher 4 570008021514110/Temperatur", 'ID' => 11097);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Speicher 5 8E000802157B010/Temperatur", 'ID' => 16984);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Speicher 6 270008021445610/Temperatur", 'ID' => 21637);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Speicher 7 5C00080215F0510/Temperatur", 'ID' => 31989);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Speicher 8 23000802D7A610/Temperatur", 'ID' => 47028);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Heizung Aussentemp 4E000802142B210/Temperatur", 'ID' => 19083);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Solar Speicher oben 4200080215A9910/Temperatur", 'ID' => 56778);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Solar Speicher unten A5000802C83910/Temperatur", 'ID' => 39842);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Tim 9600080170A0F310/Temperatur", 'ID' => 43182);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Warmwasser D20008021589710/Temperatur", 'ID' => 25538);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_DS18S20 Zirk 2 D6000802161E210/Temperatur", 'ID' => 36065);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte & Parameter/Pool Temp AVG", 'ID' => 32042);

    # Analog In Hütte
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "GeCoS/Convert AD", 'ID' => 28708 /*[Steuerung\Pool\Soll Werte\GeCoS AD Wandlung triggern\Convert AD Solar Pool]*/);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_4AnalogIn Steuerung Hütte/Eingang X0", 'ID' => 53310);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_4AnalogIn Steuerung Hütte/Eingang X1", 'ID' => 35169);

    # Analog In Keller
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Ist Werte & Parameter/Convert AD Garagentore", 'ID' => 24248);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_4AnalogIn Steuerung Keller/Eingang X0", 'ID' => 35587);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_4AnalogIn Steuerung Keller/Eingang X1", 'ID' => 20889);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_4AnalogIn Steuerung Keller/Eingang X2", 'ID' => 12459);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_4AnalogIn Steuerung Keller/Eingang X3", 'ID' => 34202);

    # Sollwerte Digital Out
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_16Out Steuerung Hütte/Ausgang X2", 'ID' => 57767);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_16Out Steuerung Hütte/Ausgang X3", 'ID' => 14018);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_16Out Steuerung Hütte/Ausgang X4", 'ID' => 45868);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_16Out Steuerung Hütte/Ausgang X5", 'ID' => 52699);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_16Out Steuerung Hütte/Ausgang X6", 'ID' => 25014);
    $variable[] = array('Server' => "Demo Server", 'Name' => "GeCoS_16Out Steuerung Keller/Ausgang X0", 'ID' => 10007);

    
    # HW Health Status
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Hütte CPU AverageLoad", 'ID' => 10140);
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Hütte CPU Temperature", 'ID' => 11841);
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Keller CPU AverageLoad", 'ID' => 17423);
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Keller CPU Temperature", 'ID' => 51650);
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Hütte Reboot Counter", 'ID' => 15472 );
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Keller CPU Status", 'ID' => 12291 );
    $variable[] = array('Server' => "Demo Server", 'Name' => "RASPI Health Status/Raspberry Steuerung Hütte CPU Status", 'ID' => 33893 );
    
    #ebusd MQTT
    $variable[] = array('Server' => "Demo Server", 'Name' => "Dashboard Anpassung/Aussentemperatur_date", 'ID' => 44697);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Dashboard Anpassung/Aussentemperatur_time", 'ID' => 42363);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_Aussentemp_Anzeige", 'ID' => 53849);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_Raumtemp_eg_og", 'ID' => 14340);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_Vorlauf_EG_OG", 'ID' => 19651);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_Vorlauf_Keller_Soll", 'ID' => 18621);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_Brenner_Stufe", 'ID' => 35829);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_Brenner_Pumpe", 'ID' => 55290);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_HK_Pumpe_Bad", 'ID' => 20216);
    $variable[] = array('Server' => "Demo Server", 'Name' => "ebusd MQTT/K_HK_Pumpe_EG_OG", 'ID' => 21445);

    # Anwesenheit
    $variable[] = array('Server' => "Demo Server", 'Name' => "Parameter/Urlaub", 'ID' => 40427);

    # PV Anlage
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "PV Ist Werte/PV Gesamtenergie", 'ID' => 45437 /*[Steuerung\Energie\PV\PV Gesamtenergie]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "PV Ist Werte/PV Tagesenergie", 'ID' => 38250 /*[Steuerung\Energie\PV\PV Tagesenergie]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "PV Ist Werte/AC Leistung aktuell (KWh)", 'ID' => 41353 /*[Steuerung\Energie\PV\AC Leistung aktuell]*/);

    # Pool
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/PPumpe_Soll", 'ID' => 54352 /*[Steuerung\Pool\Soll Werte\PPumpe Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Pool Licht Soll", 'ID' => 46151 /*[Steuerung\Pool\Soll Werte\Pool Licht Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Pool_Wärmepumpe_Soll", 'ID' => 50055 /*[Steuerung\Pool\Soll Werte\Pool Wärmepumpe Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Pool_Wäremepumpe_aktiv", 'ID' => 28307 /*[Steuerung\Pool\Soll Werte\Pool Wäremepumpe aktiv]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Ist Werte & Parameter/Pool_Solar_Ist", 'ID' => 43955 /*[Steuerung\Pool\Ist Werte & Parameter\Pool_Solar_Ist]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Ist Werte & Parameter/Pool_Solar_Status", 'ID' => 41443 /*[Steuerung\Pool\Ist Werte & Parameter\Pool_Solar_Status]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Ist Werte & Parameter/Pool_Wärmepumpe_Status", 'ID' => 54504 /*[Steuerung\Pool\Ist Werte & Parameter\Pool Wärmepumpe Status]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "POWERMETER/ENERGY_COUNTER", 'ID' => 49669 /*[Steuerung\Pool\Ist Werte & Parameter\Wärmepumpe Energie Counter]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "POWERMETER/POWER", 'ID' => 39812 /*[Steuerung\Pool\Ist Werte & Parameter\Wärmepumpe Power]*/);

    # Brenner
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Masterregler 6320/0621 00 0x87  eBus ID 00-007 Vorlauftemp Kessel", 'ID' => 47628 /*[Steuerung\Energie\Heizung\Brenner Vorlauf (eBus)]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Brenner Überwachung/Brenner Vorlauf Temp Merker", 'ID' => 41663 /*[Steuerung\Energie\Heizung\Brenner Vorlauf Merker (eBus)]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Speichertemperaturen/Temp Speicher 11", 'ID' => 35664 /*[Steuerung\Energie\Heizung\Speicher oben (eBus)]*/);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Lüften => Heizkreise ausschalten/Lüften", 'ID' => 59462);

    # Licht Küche
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Küche/Esstisch_Level", 'ID' => 12175 /*[Steuerung\Küche\Esstisch Level]*/);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte/Terrasse Tür Licht Ist", 'ID' => 49529);
    
    # Licht Terrasse
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte/Terrasse Treppe Licht Ist", 'ID' => 42905);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Terrasse Treppe Licht Soll", 'ID' => 40112 /*[Steuerung\Garten\Spessartstrasse\Soll Werte\Terrasse Treppe Licht Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Terrasse Tür Licht Soll", 'ID' => 46447 /*[Steuerung\Garten\Spessartstrasse\Soll Werte\Terrasse Tür Licht Soll]*/);

    # Licht Wohnzimmer
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte/Licht Alle Ist", 'ID' => 34986);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte/Licht Fenster Ist", 'ID' => 48273);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte/Licht Glasschrank Ist", 'ID' => 17946);
    $variable[] = array('Server' => "Demo Server", 'Name' => "Ist Werte/Licht Klavier Ist", 'ID' => 41316);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Licht alle Soll", 'ID' => 36237 /*[Steuerung\Wohnzimmer\Soll Werte\Licht alle Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Licht Fenster Soll", 'ID' => 48184 /*[Steuerung\Wohnzimmer\Soll Werte\Licht Fenster Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Licht Glasschrank Soll", 'ID' => 12038 /*[Steuerung\Wohnzimmer\Soll Werte\Licht Glasschrank Soll]*/);
    $variable[] = array('Server' => "Raspberry Steuerung Keller", 'Name' => "Soll Werte/Licht Klavier Soll", 'ID' => 43742 /*[Steuerung\Wohnzimmer\Soll Werte\Licht Klavier Soll]*/);
                                
?> 

und ein Script für den Datenaustausch:

<?

 //Datenaustausch zwischen IPS Servern
 include 'Datenaustausch_Define.php';

 $fehler ="OK";

 # HW Online?
 # zuständige Variablen ID's auf diesem Server suchen
 # die für uns relevanten Zeilen aus dem Array filtern mit folgenden Suchkriterien:
 # 	- $search => Suchkriterium
 # 	- $myarray => Name der Array Variablen
 # 	- $column => die zu durchsuchende Spalte
 $search = IPS_GetName(0);
 $myarray = $variable; #wir kümmern uns um das Variablenarray 'LANstatus'
 $column = 'Server';
 $filtered = Array_filtern($search, $myarray, $column);
 #print_r($filtered);
 foreach($filtered as $key => $value){	#das neue Array, dass die nach Name ausgesiebten Rows enthält
 	if($value['Server'] == IPS_GetName(0)){
		switch ($value['Name']){
			case 'Watchdog LAN/Demo Server':
			$Demo_Server = GetValue($value["ID"]);
			break;
			case 'Watchdog LAN/Raspberry  Steuerung Hütte':
			$Demo_Pi_3_3 = GetValue($value["ID"]);
			break;
			case 'Watchdog LAN/Raspberry Steuerung Keller':
			$Demo_Pi_3_4 = GetValue($value["ID"]);
			break;
		}
		
		#SetValue($value["ID"], $fehler);
	}
 }
 
 #IP Adressen der fernen Server holen
 $RASPI_3_3_IP = $server[array_search('Raspberry Steuerung Hütte', array_column($server, 'Name'))]['IP'];
 $RASPI_3_4_IP = $server[array_search('Raspberry Steuerung Keller', array_column($server, 'Name'))]['IP'];
 $Demo_Server_IP = $server[array_search('Demo Server', array_column($server, 'Name'))]['IP'];
 #echo "IP: ".$Demo_Server_IP."
";
 switch ($_IPS['SENDER']){
	case "Variable":
	# die für uns relevanten Zeilen aus dem Array filtern mit folgenden Suchkriterien:
	# 	- $search => Suchkriterium <= Zusammengesetzt aus 'Parent' Name, einem '/' und dem Namen der Variablen (um auch bei gleichen Variablennamen eindeutige Ergebnisse zu liefern)
	# 	- $myarray => Name der Array Variablen
	# 	- $column => die zu durchsuchende Spalte
	#$search = IPS_GetObject($_IPS['VARIABLE'])['ObjectName']."
";	# Name der 
	$search = IPS_GetName(IPS_GetParent($_IPS['VARIABLE'])).'/'.IPS_GetObject($_IPS['VARIABLE'])['ObjectName'];
	#echo "search: ".$search."
";
	# Achtung: alle GECOS 1-wire Variablen heißen 'Temperatur' => den Namen der zugehörigen Parent Instanz verwenden
	#if (trim($search) == "Temperatur") $search = IPS_GetName(IPS_GetParent($_IPS['VARIABLE']));
	$myarray = $variable; #wir kümmern uns um das Variablenarray 'variable'
	$column = 'Name';
	$filtered = Array_filtern($search, $myarray, $column);
 	#print_r($filtered);
	foreach($filtered as $key => $value){	#das neue Array, dass die nach Name ausgesiebten Rows enthält
	#echo "Server: ".$value['Server']."
";
		switch ($value['Server']){	#für jeden gefunden Server (eine Variable kann auf mehreren Servern existieren)
			case IPS_GetName(0):
			# bin ich selber => nix tun
			break;
			case 'Demo Server':
			switch ($Demo_Server){	# if online
				case 1:
				#echo "Datenaustausch: IP =>  ".$Demo_Server_IP."
";
				#echo "ZielID: IP =>  ".$value["ID"]."
";
				#echo "Value: IP =>  ".GetValue($_IPS['VARIABLE'])."
";
				Datenaustausch($Demo_Server_IP,$value["ID"],GetValue($_IPS['VARIABLE'])); # Übergabe von Ip des entfernten Servers, ID der Zielvariablen, Value
				break;
				case 0:
				$fehler = "IP ".$Demo_Server_IP." not available";
				break;
			}
			break;
			case 'Raspberry Steuerung Keller':
			switch ($Demo_Pi_3_4){	# if online
				case 1:
				Datenaustausch($RASPI_3_4_IP,$value["ID"],GetValue($_IPS['VARIABLE'])); # Übergabe von Ip des entfernten Servers, ID der Zielvariablen, Value
				break;
				case 0:
				$fehler = "IP ".$RASPI_3_4_IP." not available";
				break;
			}
			break; 
		}
	}
 }

 function Array_filtern($search, $myarray, $column){
 # die für uns relevanten Zeilen aus dem Array filtern mit folgenden Suchkriterien:
 # 	- $search => Suchkriterium
 # 	- $myarray => Name der Array Variablen
 # 	- $column => die zu durchsuchende Spalte
		$filtered = array(); # hier wird ein neues Array gebildet welche die Rows  die alle den gleichen 'Namen' haben enthät (um mehrer Server anzusprechen)
	$rows = $myarray;
	foreach($rows as $index => $columns) {
 		foreach($columns as $key1 => $value) {
   		#if ($key1 == 'Name' && $value == trim($search)) {
   		if ($key1 == trim($column) && $value == trim($search)) {
      		$filtered[] = $columns;
      	}
  	 	}
	}
	return $filtered;
}

function Datenaustausch($ip, $id, $value){
	#echo "Datenaustausch: IP =>  $ip,  ZielID => $id,  Value => $value
";
	#echo "http: "."hier der http Aufruf@$ip:3777/api/"."
";
	$rpc = new JSONRPC("hier der http Aufruf@$ip:3777/api/");
	$rpc->SetValue($id, $value);# Variable im entfernten Server setzen
}
?>

Unter diesem Script hängen jetzt die Ereignisse der zu übertragenden Variablen.

Gruß, Michael

Hallo
Das sieht ziemlich kompliziert aus. Gibts zwecks Datenaustausch auch was für Nicht-PHP-Profis?:confused: Ich möchte eigentlich nur die Werte von ein paar Float-Variablen von Server A auslesen, um sie auf Server B weiter zu verarbeiten.

Hallo,

wenn es nur um einige Variablen geht, nimm doch das Beispiel von Post#1:


<?

// Aufbauen einer Verbindung zum Slave-IPS
$rpc = new JSONRPC("http://user:password@99.99.99.99:3777/api/");

// ID der Boolean-Variable auf dem Slave-IPS
$id_remote = 46667;

if($_IPS['SENDER'] == "Variable")
 {
    $id_local = $_IPS['VARIABLE'];
    $rpc->SetValue($id_remote, GetValue($id_local));
}

Weitere Details findest Du in https://www.symcon.de/service/dokumentation/entwicklerbereich/datenaustausch/

Grüße, Gerhard

Hallo
Das Beispiel funktioniert bei mir und würde mir auch so erstmal reichen. Ich hätte da aber noch eine Frage zum Skript.
Woher weiß das Skript, welche Variable gesendet werden soll? Ich geb doch nur die ID der Variable an, wo der Wert auf dem Slave ankommen soll.
Das ganze ist auch ziemlich zeitversetzt, teilweise dauert es bis 5s, bis sich die Variable auf dem Slave aktualisiert.

Hallo,

ich nehme mal an, Du willst nur Variablen weiterleiten, die sich gerade geändert haben. Also hast Du dafür ein Ereignis angelegt (Variablenänderung) und dieses mit der Variable und dem Script verknüpft. Der ‚Sender‘ in Deinem Script ist dann DIESE Variable und ‚Value‘ ist IHR Wert.
Schickst Du die Werte mit rpc oder mit curl? Bei mir geht es mit rpc eigentlich fix.

Grüße, Gerhard

Genau. Dem Script ein Ereignis hinzufügen, den Auslöser festlegen, auf Variablenänderung triggern. Ändert diese Variable (Auslöser) ihren Wert, wird das Script ausgeführt. Die ID des Auslösers wird ermittelt und sein derzeitiger Wert. Zweiterer wird in Remotevariable geschrieben.

Tempo per RPC auch bei mir recht flott. War sehr überrascht.

Script kann man auch umbauen auf IDENTs, damit man die Remotevariable darüber suchen kann.

#hrahlers, #GerhardBS, danke für eure Erklärung, jetzt hab ich das verstanden.
Das Problem mit dem zeitversetzten Senden habe ich allerdings noch nicht in den Griff bekommen.
#GergardBS, ich sende per rpc.

EDIT: Zeitproblem ist gelöst

Hallo,

Was war denn das Zeitproblem?

Grüße, Gerhard

Ich hätte nur in die Meldungen sehen müssen, da hätte ich es gleich sehen können. Ich hatte ein Problem (Fehlkonfiguration) mit einer ClientSocket-Verbindung. Das hat mein IPS, welches auf einem RPi läuft, so „eingebremst“,
dass es nicht nur bei dem Datenaustausch zwischen zwei IPS-Servern, sondern generell zu Zeitverzögerungen kam. Nachdem das Problem gelöst war, läuft alles wieder perfekt.

Welche Client-Socket-Verbindung war es denn, die dir die Wartezeit bescherte? Ich überlege, mein Windows-IPS auf zwei oder drei Pi-Installationen aufzuteilen. Und dann auf Windows ganz zu verzichten. Daher meine ursprüngliche Frage nach der Kommunikation untereinander.

Ich hatte auf meinem RPi ein Sonoff TH16 per Tasmota-Modul https://www.symcon.de/forum/threads/36262-Modul-Tasmota?highlight=tasmota hinzugefügt. Da hatte ich bei der Installation Fehler gemacht und mehrmals das Modul angelegt. Dadurch ist eine „Client-Socket-Leiche“ übrig geblieben. Ich nehme zumindest an, dass es an dieser Client-Socket Verbindung lag, weil seit Bereinigung alles wieder sehr flüssig läuft. Wie ich schon weiter oben sagte, der Fehler lag bei mir.

Hab das ganze etwas „Modulweise“ aufgebaut. Module kann ich leider nicht schreiben.

Daher mal meine Umsetzung. Evtl kann es jemand gebrauchen

<?php
// Grundvariablen holen
$IDScript       = $_IPS['SELF'];
$IDMaster       = IPS_GetParent (IPS_GetParent ($IDScript));
$Sender         = $_IPS['SENDER'];



//IDs Settings holen
$IDSettings     = IPS_GetInstanceIDByName ('Settings', $IDMaster);
$IDTargetConn	= IPS_GetVariableIDByName ('Target Connected', $IDSettings);

$TargetIP		= getvalue(IPS_GetVariableIDByName ('Target Adress', $IDSettings));
$TargetUsername	= getvalue(IPS_GetVariableIDByName ('Target Username', $IDSettings));
$TargetPasswort	= getvalue(IPS_GetVariableIDByName ('Target Password', $IDSettings));
$TargetPort     = getvalue(IPS_GetVariableIDByName ('Target Port', $IDSettings));


// Abfragen ob Ziel erreichbar
@$ErrorCheck = fsockopen($TargetIP, $TargetPort, $errno, $errstr, 1);
	if (!$ErrorCheck) {
		SetValue ($IDTargetConn, false);
		// Ablauf abbrechen
		fclose($ErrorCheck); 
        goto Programmende;
	}else{
		SetValue ($IDTargetConn, true);
		}



// JSON Verbindung aufbauen
$rpc = new JSONRPC("http://$TargetUsername:$TargetPasswort@$TargetIP:$TargetPort/api/");


 if ($Sender == 'Variable') {
	$IDEreignis     = $_IPS['EVENT'];
	$IDEventQuelle  = IPS_GetEvent($IDEreignis)['TriggerVariableID'];
	$EventValue     = getvalue ($IDEventQuelle);
	$IDEventZiel    = intval(IPS_GetName($IDEreignis));

	$rpc->SetValue($IDEventZiel, $EventValue);
}else{}


Programmende:
fclose($ErrorCheck); 

Auch wenn es wahrscheinlich nicht ganz für dich ist, wollte ich den Querverweis noch einmal auf unsere Vorstellung vom Event bringen:

paresy

1 „Gefällt mir“