Im ersten Beitrag zu diesem Thema sind ja schon ganz nette Sachen beschrieben worden. Jedoch gibt es Probleme, wenn der php-Teil zu umfangreich ist und damit zu lange braucht. Studio behandelt ein php-skript wie eine Zeile Studio-code. Da Makros in Studio grundsätzlich nacheinander abgearbeitet werden sieht es wohl danach aus, daß auch ein php-skript Teil des Studio-Codes wird und nicht in einen eigenen Thread bearbeitet wird (bitte verbessern sollte ich hier falsch liegen). Damit ist Studio quasi blockiert, wenn php nicht schnell genug fertig wird.
Um dieses Problem zu umgehen bin ich auf folgenden Weg gestossen:
php auf der Kommandozeile. Ja richtig, php-skripts können ganz ohne Server-installation in einen DOS-Fenster aufgerufen werden. Das alles ist im php-Paket enthalten.
Der Ablauf sieht nun so aus:
Studio startet mit startwin ein php-skript auf der Kommandozeile. Dieses wird ausgeführt und erzeugt z.B. eine Grafik. Mittels der Serverlösung für Studio, die >hier< beschrieben ist, wird dann direkt aus dem skript heraus Studio quasi fernbedient, also Objekte geschaltet oder Variablen zugewiesen. Das tolle an der Sache ist, daß es nun völlig egal ist, wie lange das skript läuft, erst am Ende wird der Schaltbefehl an Studio geschickt. Studio braucht zum Aufruf nur den Startwin-Befehl, ist also absolut nicht zeitkritisch.
Der php Interpreter liegt gleich in 2 Versionen vor: eine öffnet die DOS-Box, die andere läuft ohne, also völlig unsichtbar! Um nun ein skript zu testen baue ich nur noch den Aufruf in Studio ein, der Test erfolgt erst mal aus der Dos-Box heraus.
Damit das ganze schonend und schnell arbeitet nutze ich eine RAM-Disk. Beim Rechnerstart wird ein Verzeichnis, in dem sämtliche benötigte Dateien liegen, in die Ram-Disk kopiert. Für die verschiedenen Bilder, die in Studio verwendet werden, habe ich sozusagen "Startbilder" in diesem Verzeichnis stehen. Beim Start von Studio findet meine Anwendung nun gleich Bilder statt nur einen roten Hintergrund zu zeigen. Wenn nun erstmals ein neues Bild gerechnet wird wird dieses dargestellt. Somit sehe ich gleich, welches Makro schon gelaufen ist (z.B. beim Empfang der Temperatursensoren).
Rückmeldungen des php-Skripts an Studio wären zwar auch mit execstudioco möglich, hier müßte man aber von php aus wiederung ein Kommandozeilenprogramm aufrufen und es würde wieder die Dos-Box kurz aufblitzen. Eleganter ist die Serverlösung. Dazu bitte dem link oben folgen, die nötigen Dateien runterladen und mal sämtliche begleitenden Texte durchlesen. Die Dateien entsprechend anpassen (Port, Host, Name, Passwort in der ini festlegen, wird dann im php-skript gebraucht). Zusammen mit Studio muß dann der Server gestartet werden. Dieser residiert dann im Systray, man kann ein Monitor-Fenster öffnen, um dem Treiben zuzusehen. Im Server ist leider ein Bug: 1. er läßt sich nur per Rechtsklick auf das Trayicon beenden (nicht wirklich ein Bug) 2. er verhindert (jedenfalls auf meinen 2 Rechnern mit XP), solange er läuft, ein runterfahren des Rechners. Mittes kill oder einem AutoHotKey-Progrämmchen kann man das Problem aber lösen.
Für das folgende Beispiel muß in einem Verzeichnis R:\studio\php folgendes drinstehen:
R:\studio\php
libmysql.dll
php5ts.dll
php.ini
php.exe
php-win.exe
studio.php
bmp.php
sowie die
test.php
R:\studio\php\ext
php_gd2.dll
** sowie weitere benötigte Erweiterungen
php_mysql.dll
Die o.g. Dateien sind aus dem php-Installations-zip (außer studio.php, dieses ist aus der Servererweiterung sowie bmp.php zum erzeugen von bmp-Bildern, dazu siehe den ersten Thread oder suche im forum nach bmp.php).
Die php.ini sieht so aus:
php.ini
Code: Alles auswählen
[PHP]
; Directory in which the loadable extensions (modules) reside.
extension_dir = ".\ext\"
extension=php_gd2.dll
extension=php_mysql.dll
Im Makro des Sensors steht (unter anderem) folgendes:
Code: Alles auswählen
** Bild/Anzeige auf 1 setzen (damit "geschaltet" wird), im Beispiel phpGrafik
phpGrafik:=1
** Parameter basteln
Param:="r:\studio\php\php.exe -f test.php Wert="+TempAnzeige.TempValuePHP
** php-File aufrufen
startwin(Param)
Der Wert selbst steht in TempAnzeige.TempValuePHP (müßt ihr anpassen an eure Umgebung).
Die Übergabe mit "irgendwas=Wert" ist nötig, da mit Wert allein als Parameter eine negative Zahl als Argument für php.exe gewertet würde! irgendwas kann irgendwas sein, es wird nur alles nach dem = ausgewertet.
die test.php sieht so aus:
Code: Alles auswählen
<?
// übergebenes Argument rechts vom = Zeichen auswerten, mehrere Argumente stehen in ..[argv][2] [argv][3] etc
$wert = substr (strrchr ( $_SERVER[argv][1] , "=") ,1);
// gegebenenfalls Komma gegen Punkt tauschen
$wert = strtr ( $wert , "," , "." )+0;
// Skala definieren
// minimum = -20
// maximum = 40
// Skalenbereich = 60, Offset = 20
$skalenbereich = 60;
$wert += 20;
$skala = ($wert * 270 /$skalenbereich)+135;
if ( $skala > 360) $skala = $skala - 360;
// bmp ermöglichen
include("bmp.php");
// mit print_r($_SERVER) kann man schön prüfen, ob und wie die Parameter übergeben werden. ggf // entfernen
//print_r($_SERVER);
// Grafik erstellen:
$im = @ImageCreatetruecolor (41, 41);
// Hintergrund blau für durchsichtig in Studio
$background = ImageColorAllocate ($im, 0, 0, 255);
imagefill( $im, 0 , 0 , $background );
// hellgrauer Hintergrund rund
$kreis = ImageColorAllocate ($im, 236, 233, 216);
imagefilledellipse ( $im, 20, 20, 40, 40, $kreis );
// kreisbogen 270° als Skala
$skalafarbe = ImageColorAllocate ($im, 64, 64, 64);
imagearc ( $im, 20, 20, 36, 36, 135, 45, $skalafarbe );
$skalafarbe = ImageColorAllocate ($im, 64, 64, 64);
imagearc ( $im, 20, 20, 34, 34, 135, 45, $skalafarbe );
// Skalenstriche, als Winkel-Lines, anschliessend eine gefüllter Kreis zum drüberschreiben
// Zeiger
$zeigerfarbe = imagecolorallocate($im, 0x90, 0x00, 0x00);
imagefilledarc ( $im, 20, 20, 40, 40, $skala, $skala+1 , $zeigerfarbe, IMG_ARC_PIE);
// hellgrauer Hintergrund in der Mitte
$kreis = ImageColorAllocate ($im, 236, 233, 216);
imagefilledellipse ( $im, 20, 20, 15, 15, $kreis );
// Wert als Text in die Mitte schreiben
$fontpath='c:/WINDOWS/fonts/';
$schrift =$fontpath. 'tahoma.ttf';
$box = imagettfbbox ( 8, 0, $schrift, $wert );
imagettftext ( $im, 8, 0, (20-(0.5*($box[4]-$box[6]))), 25, $zeigerfarbe, $schrift, $wert);
// Einheit °C Anzeige
$box2 = imagettfbbox ( 6, 0, $schrift, "°C" );
imagettftext ( $im, 7, 0, (20-(0.5*($box2[4]-$box2[6]))), 34, $skalafarbe, $schrift, "°C");
// Ausgabe des Bildes
$file = "test.bmp";
imagebmp ($im, $file);
// über Server das Bild umschalten (ausschalten)
include ("Studio.php");
SetStudio ("phpGrafik" , "aus");
?>
... übrigens funktioniern auf diese Weise die True-Type Fonts ohne Probleme!! (der Workaround ist nicht nötig).
Anwendbar ist das Ganze für alles mögliche: Abrufen von Bildern einer Webcam, Internetinhalte lesen und auswerten, Grafiken direkt erzeugen (wie im Beispiel), Grafiken oder Diagramme von woanders erzeugen lassen (z.B. jpgraph zur Erstellung von Diagrammen). Auf dem oben beschriebenen Weg ist es auch nicht mehr Zeitkritisch, egal wie umfangreich die Aufgabe ist.
Nachdem ich meine Diagramme, die z.T. mehrere 1000 Datensätze auswerten (das Zisternendiagramm, an anderer Stelle vorgestellt wertet bei 30 Tagen immerhin 42700 Datensätze aus), auf diese Technik umgestellt habe läuft Studio absolut stabil. Vorher hatte ich schon ab und zu Hänger, oder Studio ist abgestürzt.
So, genug für heute. Wer's probieren will sollte etwas Zeit übrig haben, wenn das Gerüst aber mal steht ist es super!
Viele Grüße
Sanys