Eigenes WebInterface für Studio unter PHP

Programmierung der FHZ-Zentralen mit contronics homeputer Standard / homeputer Studio & WEB-Server

Moderator: Co-Administratoren

shen
Ehrenmitglied
Beiträge: 753
Registriert: 14.07.2006, 19:24
Wohnort: Wegberg
Kontaktdaten:

Eigenes WebInterface für Studio unter PHP

Beitrag von shen » 21.11.2006, 00:51

Im folgenden möchte ich eine Alternative aufzeigen, Studio über eine WebAnwendung zu steuern. Diese richtet sich an Anwender mit entsprechenden HTML- und PHP-Kenntnissen und erlaubt die Steuerung von Studio über einen bereits vorhandenen oder noch zu installierenden WebServer (idealerweise im Intranet) mit installiertem PHP. Dabei spielt es keine Rolle, ob der WebServer auf dem selben PC läuft, auf dem homeputer Studio gestartet ist. Es kann also durchaus eine andere Maschine sein. Auch kann diese unter Linux oder BSD oder sonstwas laufen - solange PHP unterstützt wird und eine TCP/IP-Verbindung zum Studio-PC besteht, kann damit gearbeitet werden.

Hinweis: Der contronics WebServer wird hier nicht benötigt. Meine Lösung stellt einen komplett anderen Weg dar und erfordert entsprechende HMTL- und PHP-Kenntnisse. Das einfache Zusammenklicken einer WebOberfläche für homeputer Studio wie dies im contronics WebServer angedacht ist, ist mit meiner hier vorgestellten Lösung nicht möglich, contronics WebServer wird dadurch also weder ersetzt noch erweitert!

Voraussetzungen zum Betrieb
  • Ein PC mit laufender Anwendung contronics homeputer Studio, installiertem TCP/IP, ExecStudio(Co) von contronics (1) sowie ServerExecStudio (2) von Forenmtglied Bruno.
    1) http://www.contronics.de/html/download.html
    2) http://homematic-forum.de/downloads/ServerExecStudio/

    Ein funktionierender WebServer (etwa Apache, IIS) mit installiertem PHP. Betriebssystem und Standort dieses PCs sind unabhängig vom Studio-PC, solange eine TCP/IP-Verbindung zu diesem hergestellt werden kann. Alternativ kann auch auf dem Studio-PC ein WebServer samt PHP installiert werden.
    Wer einen gut funktionierenden WebServer unter Windows mit möglichst wenig Aufwand installieren möchte, dem sei das Paket XAMPP* empfohlen, denn dort ist alles notwendige (incl. PHP) bereits enthalten. Die einfachste Variante ist die Installer-Version. Ich habe meine Skripte gerade nochmal in einer VM unter einer frischen XAMPP-Installation getestet, das läuft so ohne Änderungen.
    *) http://www.apachefriends.org/de/xampp-windows.html

    Kenntnisse in PHP und HTML sowie entsprechendes KnowHow zum Betrieb der entsprechenden zuvor beschriebenen Umgebung.
Kommunikation mit Studio in PHP

Damit man sich in PHP mit homeputer Studio unterhalten kann, muss das von contronics zum freien Download angebotene Kommandozeilen-Utility "ExecStudioCo" auf dem Studio-PC installiert sein. Dies erlaubt zwar bereits ein Steuern und Abfragen von Studio aus der Windows Kommandozeile heraus, ist aber in dieser Form noch nicht für die Ansteuerung über einen (entfernten) WebServer geeignet. Hier kommt dann das Tool "ServerExecStudio" von Forenmtglied Bruno ins Spiel, welches über TCP/IP-Kommunikation den Aufruf von "ExecStudioCo" aus der Ferne erlaubt. Genau an dieser Stelle greift meine hier vorgestellte Bibliothek mit enstprechenden selbstprogrammierten PHP-Funktionen, die in eigenen Skripten entsprechend eingesetzt werden können.

Zur Kommunikation mit homeputer Studio bieten also die folgenden vier Funktionen die entsprechenden Möglichkeiten:
  • - GetStudio() fragt den Zustand eines Objektes ab
    - GetStudioArray() fragt den Zustand mehrerer Objekte mit nur einem Aufruf von ExecStudio ab
    - SetStudio() setzt den Zustand eines Objektes
    - RunStudio() führt ein Makro aus
Die Kommentare im Skript sollten als Erläuterung zur Anwendung der Funktionen reichen, entsprechende PHP-Kenntnisse setze ich voraus.

studio.inc.php4:

Code: Alles auswählen

<?

  //
  // studio.inc.php4 / Stefan Hendricks, fhz-forum.de, 11/2006 
  // 
  // Funktionen zur Kommunikation mit contronics homeputer Studio 
  // über TCP/IP via ExecStudio(Co)/ServerExecStudio 
  // 
  // Voraussetzungen auf dem Studio-PC: 
  // - Installation von ExecStudio (contronics) 
  // - Installation von ServerExecStudio (Forenmtglied Bruno) 
  //



  
  // Konstanten für die Kommunikation mit ServerExecStudio:
  
  $studio_server    = "192.168.0.10"; // IP oder Hostname des Servers
  $studio_port      = 54711;          // Port des Servers
  $studio_timeout   = 10;             // Timeout in Sekunden
  $studio_password  = "geheim";       // Passwort für ServerExecStudio
  
  
  //
  // Funktion GetStudio($object)
  //
  // Liefert den Wert von $object als String zurück,
  // im Fehlerfalle ist der Rückgabewert "false"
  //
  // Beispiel: $steckdose1 = GetStudio("Steckdose1");
  //
  
  function GetStudio($object) {
    global $studio_server, $studio_port, $studio_timeout, $studio_password;
    if ($socket = fsockopen($studio_server, $studio_port, $errno, $errstr, $studio_timeout)) {
      fputs($socket, trim("$studio_password g$object") ."\r\n");
      $data = trim(fgets($socket));
      fclose($socket);
      if ((substr($data,  0, 5) != "Error") and (substr($data,  0, 13)  != "access denied"))  {
        return substr($data, strpos($data, "=")+1);
      } else {
        return(false);
      }
    } else {
      return(false);
    }
  }
  
  
  //
  // Funktion GetStudioArray($objects)
  //
  // Liefert die Werte von $objects (durch Komma getrennt) als Array zurück,
  // im Fehlerfalle ist der Rückgabewert "false"
  //
  // Beispiel:  $zustaende = GetStudioArray("Schalter1, Schalter2, Lampe1");
  // ergibt ... $zustaende["Schalter1"] = "an"
  //            $zustaende["Schalter2"] = "aus"
  //            $zustaende["Lampe1"]    = "an"
  //
  
  function GetStudioArray($objects) {
    global $studio_server, $studio_port, $studio_timeout, $studio_password;
    if ($socket = fsockopen($studio_server, $studio_port, $errno, $errstr, $studio_timeout)) {
      $objects_array = explode(",", $objects);
      for ($i=0; $i<count($objects_array); $i++) {
          $objects_array[$i] = trim($objects_array[$i]);
        }
      $command = "g" . implode(" g", $objects_array);
      fputs($socket, trim("$studio_password $command") ."\r\n");
      for ($i=0; $i<count($objects_array); $i++) {
        $data = trim(fgets($socket));
        if (substr(strtolower($data), 0, strpos($data, "=")) == strtolower($objects_array[$i])) {
          $result[$objects_array[$i]] = substr($data, strpos($data, "=")+1);
        } else {
          fclose($socket);
          return(false);
        }
      }
      fclose($socket);
      return($result);
    } else {
      return(false);
    }
  }
  

  //
  // Funktion SetStudio($object, $data)
  // 
  // Setzt $object auf $data, im Fehlerfalle ist der Rückgabewert "false"
  //
  // Beispiel: SetStudio("Ausgabe", "Hello World");
  //
  
  function SetStudio($object, $data) {
    global $studio_server, $studio_port, $studio_timeout, $studio_password;
    if ($socket = fsockopen($studio_server, $studio_port, $errno, $errstr,  $studio_timeout)) {
      fputs($socket, trim("$studio_password s$object=\"$data\"") ."\r\n");
      $data = trim(fgets($socket));
      fclose($socket);
      if ((substr($data,  0, 5) != "Error") and (substr($data,  0, 13)  != "access denied"))  {
        return(true);
      } else {
        return(false);
      }
    } else {
      return(false);
    }
  } 
  
  
  //
  // Funktion RunStudio($macro)
  //
  // Startet das Makro $macro, im Fehlerfalle ist der Rückgabewert "false"
  //
  // Beispiel: RunStudio("Makro1");
  //
  
  function RunStudio($macro) {
    global $studio_server, $studio_port, $studio_timeout, $studio_password;
    if ($socket = fsockopen($studio_server, $studio_port, $errno, $errstr,  $studio_timeout)) {
      fputs($socket, trim("$studio_password r$macro") ."\r\n");
      $data = trim(fgets($socket));
      fclose($socket);
      if ((substr($data,  0, 5) != "Error") and (substr($data,  0, 13)  != "access denied"))  {
        return(true);
      } else {
        return(false);
      }
    } else {
      return(false);
    }
  } 
  
?>
Demoanwendung KS300 Wettersensor

Das folgende simple Skript zeigt, wie man unter Verwendung von GetStudioArray() in einem Rutsch alle Daten eines Objektes abholt und als HTML-Tabelle darstellt.
Skript und HTML-Ausgabe sind bewusst simpel gehalten, da sie nur als einfaches Programmierbeispiel dienen sollen. Wenn das Objekt des Wettersensors nicht den Standardnamen "KS300" bekommen hat, dann ist das Skript natürlich entsprechend zu modifizieren.

So sieht's im Browser aus:
Screenshot_KS300.gif
Screenshot_KS300.gif (2.8 KiB) 55044 mal betrachtet
ks300.php4:

Code: Alles auswählen

<?
  include("studio.inc.php4");
  
  $data = GetStudioArray("KS300_Temp,
                          KS300_Feuchte,
                          KS300_Wind,
                          KS300_Regen,
                          KS300_RegenAStunde,
                          KS300_RegenLStunde,
                          KS300_RegenATag,
                          KS300_RegenLTag") or die("<br><b>Fehler beim Einlesen");
                            
   echo "<table border='1'>";
   foreach($data as $objekt => $wert) {
     echo "<tr><td>$objekt</td><td>$wert</td></tr>"; 
   }
   echo "</table><br>";
  
?>

Demoanwendung Raumregler FHT08B

Das folgende Skript ist schon etwas komplexer. Es dient dazu, auf alle Raumregler zuzugreifen, deren Daten anzuzeigen sowie die Solltemperatur und/oder den Modus (Automatik/Manuell) umzuschalten.

Ganz oben im Skript sind die Namen der eigenen Raumregler-Objekte entsprechend anzupassen.

Wie im vorherigen Skript werden alle Daten jeweils eines FHTs in einem Rutsch ausgelesen und in einer Tabelle dargestellt.
Im darauf folgenden Formular können die Werte neu gesetzt werden, hier wird also zusätzlich die Funktion SetStudio() demonstriert.
Zu guter Letzt kann zwischen allen im Skript konfigurierten Raumreglern umgeschaltet werden.


So sieht's im Browser aus:
Screenshot_FHT.gif
Screenshot_FHT.gif (7.19 KiB) 55043 mal betrachtet

studio.inc.php4:

Code: Alles auswählen

<?
  include("studio.inc.php4");
  
  $raumregler[] = "Heizung_Werkkeller";
  $raumregler[] = "Heizung_Buero";
  $raumregler[] = "Heizung_Wohnzimmer";
  $raumregler[] = "Heizung_Wintergarten";
  $raumregler[] = "Heizung_Kueche";
  $raumregler[] = "Heizung_Flur_EG";
  $raumregler[] = "Heizung_Bad_EG";
  $raumregler[] = "Heizung_Bibliothek";
  $raumregler[] = "Heizung_Schlafzimmer";
  $raumregler[] = "Heizung_Kinderzimmer_links";
  $raumregler[] = "Heizung_Kinderzimmer_rechts";
  $raumregler[] = "Heizung_Bad_OG";
  
  $fht             = $_REQUEST[fht];
  $neue_temperatur = $_REQUEST[neue_temperatur];
  $neuer_modus     = $_REQUEST[neuer_modus];    

  if ($fht) {
  
    echo "<b>$fht:</b><hr>";  
    
    if ($neuer_modus) {
      SetStudio("$fht.Modus", $neuer_modus);
    }
    
    if ($neue_temperatur) {
      echo "<i>Setze neue Solltemperatur auf $neue_temperatur °C ...</i><br><br>";
      SetStudio($fht, $neue_temperatur);
    }
    
    $data = GetStudioArray("$fht,
                            $fht.Modus,
                            $fht.Temperatur,
                            $fht.Ventilpos,
                            $fht.KomfortTemperatur,
                            $fht.AbsenkTemperatur,
                            $fht.Alarm,
                            $fht.Fenster") or die("<br><b>Fehler beim Einlesen von $fht");
                            
    if ($data[$fht] == "5,5")  $data[$fht] = "Off";
    if ($data[$fht] == "30,5") $data[$fht] = "On";
    
    echo "<table border='1'>";
    foreach($data as $objekt => $wert) {
      echo "<tr><td>$objekt</td><td>$wert</td></tr>"; 
    }
    echo "</table><br>";
    
    echo "<form name='soll_temperatur' action='$PHP_SELF' method='post' target='_self'>";
    echo "Neue Temperatur: ";
    echo "<select name='neue_temperatur'>";
    for ($i=5.5; $i<=30.5; $i=$i+0.5) {
      $x = number_format($i, 1, ",", "");
      echo "<option value='$x'";
      
      switch($x) {
        case "5,5":
          if ($data[$fht] == "Off") echo " selected";
          echo ">Off";
          break;
        case "30,5":
          if ($data[$fht] == "On") echo " selected";
          echo ">On";
          break;
        default: 
          if ($data[$fht] == $x) echo " selected";
          echo ">$x °C";
      }
          
      echo "</option>\n";
    }
    echo "</select>";
    echo "<select name='neuer_modus'>";
    
    echo "<option value='Automatik'";
    if ($data["$fht.Modus"] == "Automatik") echo " selected";
    echo ">Automatik</option>";
    
    echo "<option value='Manuell'";
    if ($data["$fht.Modus"] == "Manuell") echo " selected";
    echo ">Manuell</option>";
    
    echo "</select>";
    echo "<input type='hidden' name='fht' value='$fht'>";
    echo "<input type='submit' value='OK'>";
    echo "</form>";
    echo "<hr>";
    
  }

  for ($i=0; $i<count($raumregler); $i++) {
    echo "<a href='$PHP_SELF?fht=$raumregler[$i]'>".str_replace("Heizung ", "", $raumregler[$i])."</a><br>";
  }
  
?>

Hinweise zum Umgang mit Objekten und Variablen aus Studio in PHP:
  • Wenn ein Objektname in Studio ein Leerzeichen enthält, so ist dieses bei Nutzung der oben vorgestellten Funktionen durch einen Unterstrich ("_") zu ersetzen. So muss z.B. "KS300 Wind" als "KS300_Wind" angesprochen werden.

    Studio verwaltet Dezimalzahlen unglücklicherweise mit einem Komma als Dezimaltrenner, also etwa "23,5" statt wie in Programmiersprachen üblich mit einem Punkt ("23.5"). D.h. wenn man sich Dezimalwerte aus Studio abholt, so sind diese - etwa mit str_replace(",", ".", $wert) - vor einer Weiterbearbeitung in PHP entsprechend umzuwandeln. Umgekehrt gilt natürlich dasselbe, aus Kommas müssen Punkte werden, also etwa str_replace(".", ",", $wert)

    Wann immer auf einer HTML-Seite mehrere Objektzustände und/oder Variablen aus Studio angezeigt werden sollen, dann ist aus Performancegründen immer die Funktion GetStudioArray() der Funktion GetStudio() vorzuziehen, da diese mehrere Werte mit nur einem Aufruf von ExecStudioCo auf dem Studio-PC abholt. Andererseits wäre für jedes Objekt / jede Variable ein einzelner Aufruf von ExecStudioCo notwendig, was entsprechend langsamer geht.
Sonstige Hinweise:
  • Sollte etwas einmal nicht wie gewünscht funktionieren, dann empfiehlt sich immer ein Blick auf das Monitorfenster von ServerExecStudio auf dem Studio-PC (Rechtsklick auf das Taskleistensymbol der Anwendung und dann "Monitor"). Dort sieht man, welche Befehle dort ausgeführt werden und bei Get-Abfragen auch, welche Werte zurückgegeben werden, was die Fehlersuche deutlich erleichtern kann.


    Da bei allen Funktionen bei Nichterfolg (z.B. Abfragen eines nichtdefinierten Objektes) "false" zurückgegeben wird, lauert eine kleine Falle bei GetStudio():
    Ist die Variable bzw. der Wert des Objektes = 0 (gilt jedoch nicht für "0,0", wie es etwa bei Temperaturen oder Regenmengen vorkommen kann, da PHP das Komma ja nicht also Dezimaltrenner ansieht und so der String "0,0" zurückgegeben werden würde) oder leer (""), dann würde

    Code: Alles auswählen

    $wert = GetStudio("leeres_objekt") or die("Error");
    echo "Wert = $wert";
    die Ausgabe "Error" zur Folge haben, was aber eigentlich in diesem Falle kein Fehler ist. Hier ist also Vorsicht angebracht. Dies gilt aber auch für alle internen Funktionen innerhalb PHP, die "0" oder einen Leerstring als Ergebnis zurückliefern würden.

    Wer dennoch nach dieser Methode arbeiten möchte, der sollte den Wert wie folgt abfragen:

    Code: Alles auswählen

    $wert = GetStudioArray("leeres_objekt") or die("Error");
    echo "Wert = $wert[leeres_objekt]";
    das hätte dann zumindest die Ausgabe "Wert =" zur Folge.
Ich hoffe, dass ich mit den hier vorgestellten Lösungen den ein oder anderen auf den Weg bringen kann, sich seine eigene Anwendung zur Steuerung von Studio über einen WebBrowser zusammenzuschustern und wünsche viel Spass beim Ausprobieren.
Ich helfe gerne weiter, wenn wieder Erwarten etwas nicht mit den hier vorgestellten Skripten funktioniert (dies schliesst aber nicht automatisch Nachhilfe in PHP oder HTML ein - wie bereits geschrieben setze ich enstprechende Kenntnisse voraus!). Dennoch soll dies alles eher "Hilfe zur Selbsthilfe" angesehen werden, oder als "Machbarkeitsstudie". Es soll also nur der grundsätzliche Weg anhand von einfachen Programmierbeispielen aufgezeigt werden. Was man daraus macht, bleibt jedem selbst überlassen.
Für etwaige Fehlfunktionen, Folgeschäden etc. übernehme ich keinerlei Haftung.

An dieser Stelle auch besten Dank an Bruno, der ServerExecStudio insofern "interaktiv" mit mir entwickelt hat, als dass er während der Programmierung auf meine Ansprüche für die hier vorgestellten Funktionen Rücksicht genommen hat, was eben jene in dieser Form erst ermöglicht hat. Während der erfreulich kurzen Entwicklungsphase beider Teile standen wir in ständigem Kontakt und konnten so das hier vorgestellte in Rekordzeit auf die Beine stellen :-)
Gruß
Stefan Hendricks (ehemaliger HomeMatic-Forum Betreiber)

leknilk0815
Beiträge: 6693
Registriert: 19.03.2007, 08:21
Danksagung erhalten: 2 Mal

Beitrag von leknilk0815 » 06.05.2007, 12:40

Hallo Stefan,
sorry für die folgende Anfängerfrage, aber vielleicht hilfst Du mir ja auf die Sprünge...
Ich kann mit der ersten Zeile des Beispieles für den KS300:

"include("studio.inc.php4");"

leider nix anfangen, lt. Beschreibung soll wohl eine Datei einbezogen werden, für einen kurzen Erläuterungszweizeiler wäre ich dankbar (ich erwarte keinen Anfängerkurs!)

Danke!
Gruß - Toni

KS300 + Sonnendauer + Windrichtung, KS888, HM-CC-TC/HM-CC-VD, FHT80b, und etwas FS20-xx, Keymatic, EM1000, CCU2 und FHZ2000 sowie HP Studio, HPCL + Upgrade für FHZ

shen
Ehrenmitglied
Beiträge: 753
Registriert: 14.07.2006, 19:24
Wohnort: Wegberg
Kontaktdaten:

Beitrag von shen » 06.05.2007, 12:49

In der Tat wird dort die entsprechen referenzierte Datei inkludiert. Diese kannst meinem Ursprungsposting entnehmen, das ist der erste "Codeblock", den Du enstprechend in eine Datei speicherst.
Gruß
Stefan Hendricks (ehemaliger HomeMatic-Forum Betreiber)

leknilk0815
Beiträge: 6693
Registriert: 19.03.2007, 08:21
Danksagung erhalten: 2 Mal

Beitrag von leknilk0815 » 06.05.2007, 12:58

Danke, ich denke, ich hab's kapiert...
Gruß - Toni

KS300 + Sonnendauer + Windrichtung, KS888, HM-CC-TC/HM-CC-VD, FHT80b, und etwas FS20-xx, Keymatic, EM1000, CCU2 und FHZ2000 sowie HP Studio, HPCL + Upgrade für FHZ

loewi1979
Beiträge: 2
Registriert: 25.09.2007, 11:00

Beitrag von loewi1979 » 26.09.2007, 10:53

Hallo!

Hätte da noch eine Frage. Genügt für die Ausführung die kostenlose Homeputer Standard Version oder benötigt man unbedingt die Homeputer Studio-Software?

Danke für eure Hilfe

BR Löwi

shen
Ehrenmitglied
Beiträge: 753
Registriert: 14.07.2006, 19:24
Wohnort: Wegberg
Kontaktdaten:

Beitrag von shen » 26.09.2007, 21:46

PHP wird nur in Homeputer Studio unterstützt, dies ist also Voraussetzung.
Gruß
Stefan Hendricks (ehemaliger HomeMatic-Forum Betreiber)

caveman_1966
Beiträge: 10
Registriert: 09.05.2008, 15:31

Re: Eigenes WebInterface für Studio unter PHP

Beitrag von caveman_1966 » 16.08.2008, 17:51

hallo liebe gemeinde,

mag sein das ich jetzt offene türen einrenne oder als begriffstutzig.
bei mir ist die fhz mit der maschine verbunden die auch den webserver darstellt.
meine frage, was brauche ich nun um via php mit meiner fhz arbeiten zu können.

entschuldigt meine vielleicht etwas dumme frage, aber ich steige einfach nicht so wirklich dahinter, vermutlich ist es eine einfache lösung.

danke

leknilk0815
Beiträge: 6693
Registriert: 19.03.2007, 08:21
Danksagung erhalten: 2 Mal

Re: Eigenes WebInterface für Studio unter PHP

Beitrag von leknilk0815 » 16.08.2008, 20:34

Servus,
um irgendwas mit PHP und FHZ zu machen, brauchst Du die Studio.
Gruß - Toni

KS300 + Sonnendauer + Windrichtung, KS888, HM-CC-TC/HM-CC-VD, FHT80b, und etwas FS20-xx, Keymatic, EM1000, CCU2 und FHZ2000 sowie HP Studio, HPCL + Upgrade für FHZ

caveman_1966
Beiträge: 10
Registriert: 09.05.2008, 15:31

Re: Eigenes WebInterface für Studio unter PHP

Beitrag von caveman_1966 » 17.08.2008, 10:02

hallo toni,

hab die studio-software, fhz1000 pc, apache als webserver, dyndns.
funktioniert alles wunderbar, nur begreif ich einfach nicht wie ich das ganze zusammen bringe.
alles was notwendig ist, ist vorhanden.

brauche einfach nur nen guten tip und das ganze für mich zu begreifen.

danke

leknilk0815
Beiträge: 6693
Registriert: 19.03.2007, 08:21
Danksagung erhalten: 2 Mal

Re: Eigenes WebInterface für Studio unter PHP

Beitrag von leknilk0815 » 17.08.2008, 10:41

Servus,
hier bin ich leider auch der falsche Ansprechpartner, ich habe von PHP auch nur rudimentäre Ahnung...
Ich habe das am Anfang stehende Script für meine Zwecke etwas angepasst (mittels try and error), ich will damit auch nur verschiedenen Werte in einer Tabelle anzeigen und ins Web stellen. Notwendig war es bei mir, da die FHZ zwar den KS300 anzeigen kann, nicht aber die zusätzlichen Temp- Sensoren. Diese Werte lese ich mit dem Script aus der PG- Datenbank und stelle sie mit den Werten der FHZ zusammen ins Netz.
Ich denke aber, daß Dir hier andere mit mehr Ahnung weiterhelfen werden.
Gruß - Toni

KS300 + Sonnendauer + Windrichtung, KS888, HM-CC-TC/HM-CC-VD, FHT80b, und etwas FS20-xx, Keymatic, EM1000, CCU2 und FHZ2000 sowie HP Studio, HPCL + Upgrade für FHZ

Antworten

Zurück zu „homeputer Studio / Standard: Programmierbeispiele“