Pages: [1] 2   Go Down
Author Topic: PHP Frage zum Arduino Webserver / PHP / Text parsen  (Read 1806 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Forum,

bevor ich jetzt gleich Amok laufe, stelle ich mal mein (hoffentlich) letztes Problem hier ein. Ich habe einen Webserver auf dem Ardunio laufen mit dem enc28j60 Chipsatz. Alles funktioniert bestens. Jetzt möchte ich aber die Temperatur (nur Temperatur) per PHP Script auf meinem Infoframe anzeigen lassen. Dazu habe ich ein kleines zwischenscript geschrieben welches den Quellcode des Arduino Webservers parsed und mir in eine Text Datei auf meinem Server schreibt. Dies macht er alles wunderbar und es funktioniert auch alles Wunderbar. Hier mal der Inhalt der Textdatei:

Code:
<H1>THT - NET Webserver</H1><br/><table><br/><br/>Wohnzimmer: 25.0&deg;C / 44%<br/>Aussen: 15.9 &deg;C / 0%</table>

alles in eine Zeile. So jetzt mein PHP Script:

Code:
// read Temperature File
$TEMPhandle = fopen ("arduino/Arduino_Temp_2.txt", "r");
    $TEMPbuffer = fgets($TEMPhandle, 100);
    $TEMPbuffer1 = fgets($TEMPhandle, 100);
fclose ($TEMPhandle);


// print temperature
//Sensor0
$pos = strpos($TEMPbuffer, 'Wohnzimmer:') + 12;
$posa = strpos($TEMPbuffer, ' ', $pos);

$TempAkt = substr($TEMPbuffer, $pos, $posa - $pos);

//Sensor1
$pos1 = strpos($TEMPbuffer1, 'Aussen:') + 8;
$pos1a = strpos($TEMPbuffer1, ' ', $pos1);

$TempAkt1 = substr($TEMPbuffer1, $pos1, $pos1a - $pos1);

Und jetzt mein Problem. Die Temperatur vom Wohnzimmer wird mir angezeigt. Jedoch nicht die von Aussen. Egal was ich mache. Es will einfach nicht und ich habe keinen schimmer warum...... Kennt sich hier jemand mit PHP aus?
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 260
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

hast du mal mit echo gecheckt, was die einzelnen variablen beinhalten?

Meine Vermutung:
$TEMPbuffer1 = fgets($TEMPhandle, 100);
gibt false zurück.

PHP-Referenz: "fgets — Liest eine Zeile von der Position des Dateizeigers"

Sprich: Du hast nur eine Zeile in der Datei, willst mit dem zweiten fgets aber eine zweite Zeile auslesen, weshalb du ein false von fgets zurückgegeben bekommst.

Noch eine kleine Kritik:
Warum nicht preg_match und regular expressions verwenden?
Damit kannst du auch gleich prüfen, ob deine Datei überhaupt einen "gültigen" Ihnalt hat.

Code:
// read Temperature File
$TEMPhandle = fopen ("arduino/Arduino_Temp_2.txt", "r");
    $TEMPbuffer = fgets($TEMPhandle, 100);
fclose ($TEMPhandle);
if(preg_match('/Wohnzimmer: ([\-0-9.]+)(.*?)Aussen: ([\-0-9.]+)/i', $TEMPhandle, $result)
{
 // suchmuster gefunden, daten in der datei gültig
 $temp1 = intval($result[1]);  // temperaturwerte sind als string im $result-array gespeichert
 $temp2 = intval($result[3]); // intval macht einen integer-wert (bzw float) aus ihnen

}
else
{
 echo 'Suchmuster konnte nicht gefunden werden!';
}


Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Kudin,

danke für deine Antwort. Das problem ist, ich verstehe nicht wie ich es eleganter lösen könnte. Das mit preg_match und regular expressions hatte ich zwar mal angesehen aber auch hier fällt es mir schwer zu verstehen wie ich da vorgehen muss. Da tue ich micht mit der Arduino Sprache leichter ^^

Spass beiseite. Ich habe auch versucht mir mit echo es anzeigen zu lassen, leider bekomme ich nur eine weiße Seite.
Code:
<?php
//***************************************************************************************************
//   Initialization
//***************************************************************************************************

// set error handling to only report errors (no warnings, infos...)
// error_reporting( E_ALL );

function datumDeutsch($datumsstring){
$englisch = array("Morgen""Monday""Tuesday""Wednesday""Thursday""Friday""Saturday""Sunday""Mon""Tue""Wed""Thu""Fri""Sat""Sun""January""February""March""April""May""June""July""August""September""October""November""December""Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec""Motag");
$deutsch = array("Morgen""Montag""Dienstag""Mittwoch""Donnerstag""Freitag""Samstag""Sonntag""Mo""Di""Mi""Do""Fr""Sa""So""Januar""Februar""März""April""Mai""Juni""Juli""August""September""Oktober""November""Dezember""Jan""Feb""M&auml;r""Apr""Mai""Jun""Jul""Aug""Sep""Okt""Nov""Dez""Montag");
return str_replace($englisch$deutsch$datumsstring);
}



// read Temperature File
$TEMPhandle fopen ("arduino/Arduino_Temp_2.txt""r");
    
$TEMPbuffer fgets($TEMPhandle100);
    
$TEMPbuffer1 fgets($TEMPhandle100);
fclose ($TEMPhandle);


// print temperature
//Sensor0
$pos strpos($TEMPbuffer'Wohnzimmer:') + 12;
$posa strpos($TEMPbuffer'&'$pos);

$TempAkt substr($TEMPbuffer$pos$posa $pos);

//Sensor1
$pos1 strpos($TEMPbuffer1'Aussen:') + 8;
$pos1a strpos($TEMPbuffer1'&'$pos1);

$TempAkt1 substr($TEMPbuffer1$pos1$pos1a $pos1);





// load configuration
$config parse_ini_file("config.ini"true);
$sysconfig $config['System'];
// include path for zend framework
if ($sysconfig['zendfw_path'] != "") {
set_include_path(get_include_path() . PATH_SEPARATOR $sysconfig['zendfw_path']);
}
// set locale for date/time formatting
$loc setlocale(LC_ALL'de_DE.UTF8''de_DE''de''ge');

// includes
require_once 'library/tools.php';
require_once 
'library/dbconn.php';
require_once 
'library/iplugin.php';
 
// set the width and height of the new image in pixels
$image_width $sysconfig['image_width'];
$image_height $sysconfig['image_height'];

// create simple black image
$im ImageCreateTrueColor($image_width$image_height);
$backgroundcol ImageColorAllocate($im000);
ImageFillToBorder($im00$backgroundcol$backgroundcol);

// copy (resized) background image on background
$bgimagefile 'resources/background.jpg';
$bg = @ImageCreateFromJpeg ($bgimagefile); /* Versuch, Datei zu öffnen */
if ($bg) {
imagecopyresampled($im$bg0000$image_width$image_heightimagesx($bg), imagesy($bg));
}

// open database connection
$dbconn DbConnection::connect($sysconfig['db_host'], $sysconfig['db_name'], $sysconfig['db_user'], $sysconfig['db_password']);
if (!
$dbconn)
die('keine Datenbankverbindung möglich: ' mysql_error());

// create cache directory if it doesn't exist already
if (!file_exists('cache/'))
mkdir('cache');

// load and init plugins (calls, weather, calendar, mails...)
// every ini [group] except "System" is used as class name for a plugin and instantiated
$plugins = array();
foreach (
$config as $key=>$elem) {
if ($key != "System") {
// include class file
require_once 'plugins/' $key '.php';
// create instance
$plugins[$key] = new $key($dbconn$config[$key]);
}
}

// process call action if exist
if(($_GET['action'] == 'call') && $plugins['CallsPlugin'])
{
$plugins['CallsPlugin']->processCallEvent($_GET['event'], $_GET['src_name'], $_GET['src_address'], $_GET['src_numb'], $_GET['dst_name'], $_GET['dst_address'], $_GET['dst_numb'], $_GET['duration']);
}

//***************************************************************************************************
//   Check if plugin data is outdated and should be updated
//***************************************************************************************************

// do update of plugins data if last update is older than config:updatetime minutes
$updateInterval $sysconfig['updatetime'];
if ((
$updateInterval == null) || ($updateInterval == ""))
$updateInterval 5;
$updatePlugins false;
$query  "SELECT value FROM if_system where name = 'last_update'";
$result mysql_query($query$dbconn);
if (
mysql_num_rows($result) > 0) {
$row mysql_fetch_assoc($result);
$diff_seconds = (time() - $row['value']);
if ($diff_seconds >= (5*60))
{
$updatePlugins true;
// update last_update date
$query "UPDATE if_system SET value = '".time()."' WHERE name = 'last_update'";
mysql_query($query$dbconn) or die('Error, insert query failed: '.mysql_error());
}

} else {
$updatePlugins true;
// insert last_update date
$query "INSERT INTO if_system (name, value) VALUES ('last_update', '".time()."')";
mysql_query($query$dbconn) or die('Error, insert query failed: '.mysql_error());
}
mysql_free_result($result);

// debug: never do updates
//$updatePlugins = false;


//***************************************************************************************************
//   Output
//***************************************************************************************************

// styles
$style = array(); 
$style['textcolor'] = ImageColorAllocate ($im255255255);
$style['font'] = 'resources/calibri.ttf';
$style['fontb'] = 'resources/calibrib.ttf';

// current vertical offset for main info area. Must be increased by each plugin writing to this area,
// so that following plugins knows correct y position to start output from
$currentYOffset 160

// Do output of all plugins (calls, weather, calendar, mails...) with one exception:
// If the phone is currently ringing, skip displaying other plugins to show the name/number
// of the caller as fast and huge as possible and don't waste time/space for weather, mails etc...
if (($plugins['CallsPlugin']) && ($plugins['CallsPlugin']->isPhoneRinging())) {
// only print calls
$plugins['CallsPlugin']->doOutput($im$style$updatePlugins$currentYOffset);
} else {
// print all plugins in the order as they are in config
foreach ($plugins as $plugin) {
$plugin->doOutput($im$style$updatePlugins$currentYOffset);
}

$opt1 = array(
'width' => 150,
'align' => ALIGN_RIGHT
);
imagettftextboxopt($im200$image_width-162113$style['textcolor'], $style['font'], ' '.str_pad(number_format($TempAkt,1),3,'0',STR_PAD_LEFT).'°C'$opt1);
$Baum ImageCreateFromPNG 'resources/icons/tree.png' );
ImageCopy($im$Baum$image_width-10811100imagesx($Baum), imagesy($Baum));
ImageDestroy($Baum);
imagettftextboxopt($im200$image_width-285113$style['textcolor'], $style['font'], ' '.str_pad(number_format($TempAkt1,1),3,'0',STR_PAD_LEFT).'°C'$opt1);
$Haus ImageCreateFromPNG 'resources/icons/house.png' );
ImageCopy($im$Haus$image_width-23511200imagesx($Haus), imagesy($Haus));
ImageDestroy($Haus);


// check again for active incomming call (maybe we just get one in the meantime while updating/printing all other plugins)
// if so don't output any image to prevent overwriting the (incoming call) image already sent to another request
if (($plugins['CallsPlugin']) && ($plugins['CallsPlugin']->isPhoneRinging()))
die();
}

// print date & time
$opt = array(
    
'width' => 450,
    
'align' => ALIGN_LEFT
);
imagettftextboxopt($im7202025$style['textcolor'], $style['font'], strftime("%H:%M"), $opt);
imagettftextboxopt($im20020100$style['textcolor'], $style['font'], datumDeutsch(strftime("%A, %d. %B %Y (KW%V)")), $opt);   
imagesetthickness($im2);
imageline($im15140$image_width-20140$style['textcolor']);


// resize image
//$resized_image = imagecreatetruecolor(480, 324);
//imagecopyresampled($resized_image, $im, 0, 0, 0, 0, imagesx($resized_image), imagesy($resized_image), imagesx($im), imagesy($im));
//$im = $resized_image;   


// set the HTTP header type to jpeg
header("Content-type: image/jpeg"); 

// send the new PNG image to the browser
ImageJpeg($im);
 
// destroy the reference pointer to the image in memory to free up resources
ImageDestroy($im); 
 
// close database connection
DbConnection::disconnect();
 
?>
« Last Edit: July 18, 2012, 03:01:50 pm by ht81 » Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wäre es mit deinem Code einfacher es zu realisieren? Auch das er auf minus Temperaturen richtig reagiert? Also weil da ja noch ein - vor der Zahl steht? Oben ist der gesamte Code der Index.php hoffe Du / Ihr versteht ihn.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Meine Vermutung:
$TEMPbuffer1 = fgets($TEMPhandle, 100);
gibt false zurück.

PHP-Referenz: "fgets — Liest eine Zeile von der Position des Dateizeigers"

Sprich: Du hast nur eine Zeile in der Datei, willst mit dem zweiten fgets aber eine zweite Zeile auslesen, weshalb du ein false von fgets zurückgegeben bekommst.

Ja ich dachte das er durch das erneute fget den inhalt der txt Datei nochmals ausließt. Also das in beiden $TEMPbuffern der selbe Inhalt drin steht. Dem ist wohl nicht so.....Mir qualmt der Kopf.... smiley-confuse
Logged

Hamburg
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Warum gibst Du die Temperaturen nicht einfach in einem String aus?

z.B. Temperatur Wohnzimmer, Schlafzimmer, Kinderzimmer, Garten

Ausgabe Arduino:
21|14|20|-15

php:
$temp = explode("|", $stringVonArduino);

echo 'Temperatur Wohnzimmer '.$temp[0].'grad';
echo 'Temperatur Schlafzimmer '.$temp[1].'grad';
echo 'Temperatur Kinderzimmer '.$temp[2].'grad';
...
..
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich würde Dir empfehlen die Werte in einer anderen Form in der Textdatei zu speichern. Ich würde die Textdatei gar nicht überschreiben sondern immer mit der aktuellen Uhrzeit den neuen Wert in eine neue Zeile schreiben. Dann kannst Du den Verlauf auswerten, ist eine nette Spielerei.

Wenn Du
$TEMPbuffer1 = fgets($TEMPhandle);
gegen
$TEMPbuffer1  = $TEMPbuffer;
tauscht geht es.

$TEMPbuffer1 ist leer wenn nur 1 Zeile in der Txt Datei steht.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke für eure Antworten. Komme erst heute Abend dazu eure Vorschläge umzusetzten und auszuprobieren.

@Voralpenkreuz: Welche Form meinst Du? Ich benutze das ENC28J60 Ethernet Modul mit diesem Treiber hier http://trollmaker.com/article11/arduino-1-0-with-enc28j60-ethernet-shield-v1-1/

Dieser Treiber scheint doch recht abgespeckt zu sein im Gegensatz zum Offiziele Shield. Aus diesem Grunde habe ich mich für das Parsen des Webservers entschieden. Jedoch hast Du mich auf folgende Idee gebracht: Wäre es möglich die Daten auf meinem Server zu Speichern (So wie Du es vorgeschlagen hast) und dann mit dem Ardunio die Datei einzulesen und dann den Grafischen Temperaturverlauf über den Ardunio Webserver anzeigen zu lassen? Grund hierfür ist der fehlenede SD Slot ^^
Logged

Heidelberg
Offline Offline
Full Member
***
Karma: 1
Posts: 207
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Was tut ihr da  smiley-cool

http://php.net/manual/de/function.preg-match.php

da ist alles mit drinnen, schieb den betreffenden Wert zwischen 2 sichere Zeichen, schneide es raus. Vorzeichen, alles dabei. Einzeiler smiley-wink
Logged

 

Hamburg
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Wo ist da der Vorteil gegenüber dem Explode?
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 721
42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dass explode() total übers Ziel hinausschießt. preg_match() ist exakt die Funktion, die exakt das tut, was er will. Alles andere ist mit der Hand durch den Rücken in den Hals. Totaler Pfusch. Was haben die Leute nur gegen Regular Expressions? Sicherlich sehen sie kompliziert aus - aber wenn man das Prinzip verstanden hat, sind sie extrem leistungsfähig.
Logged


Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi zusammen,

also ich habe mal grad den Code von Kudin eingebaut:

Code:
// read Temperature File
$TEMPhandle = fopen ("arduino/Arduino_Temp_2.txt", "r");
    $TEMPbuffer = fgets($TEMPhandle, 100);
fclose ($TEMPhandle);
if(preg_match('/Wohnzimmer: ([\-0-9.]+)(.*?)Aussen: ([\-0-9.]+)/i', $TEMPhandle, $result)
{
 // suchmuster gefunden, daten in der datei gültig
 $temp1 = intval($result[1]);  // temperaturwerte sind als string im $result-array gespeichert
 $temp2 = intval($result[3]); // intval macht einen integer-wert (bzw float) aus ihnen

}
else
{
 echo 'Suchmuster konnte nicht gefunden werden!';
}

leider geht dann gar nichts. Habe mit auskommentieren herausgefunden das es  an dem Befehl preg_match liegt oder zumindest was damit zu tun hat. Wahrscheinlich ist das Suchmuster falsch? Ich kann mir auch kein Error anzeigen lassen, dachte das funktioniert mit Error_all aber irgendwie nicht bei mir...

Andere Frage: muss in der if Zuweisung nicht TEMPbuffer statt TEMPhandle stehen?
Logged

Heidelberg
Offline Offline
Full Member
***
Karma: 1
Posts: 207
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Du solltest die gesamte Arduino Webseite in eine Variable lesen und die dann in ihre Bestandteile zerlegen, 2 oder 3 bis 4 Zeilen. Dateien schreiben wird schnell nicht handlebar, wenn du da mehrere Betsandteile hast. Überdies ist das nicht zielführend, bremst nur.
Logged

 

Offline Offline
Sr. Member
****
Karma: 1
Posts: 260
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
muss in der if Zuweisung nicht TEMPbuffer statt TEMPhandle stehen?
doch, mein fehler...

Lass dir doch erstmal alle variablen ausgeben, dann können wir den fehler weiter einkreisen.

Code:
// read Temperature File
$TEMPhandle = fopen ("arduino/Arduino_Temp_2.txt", "r");
    $TEMPbuffer = fgets($TEMPhandle, 100);
 echo 'TEMPbuffer: '.$TEMPbuffer.'<br />';
 echo 'TEMPhandle: '.$TEMPhandle.'<br />';
fclose ($TEMPhandle);
if(preg_match('/Wohnzimmer: ([\-0-9.]+)(.*?)Aussen: ([\-0-9.]+)/i', $TEMPhandle, $result)
{
 // suchmuster gefunden, daten in der datei gültig
 $temp1 = intval($result[1]);  // temperaturwerte sind als string im $result-array gespeichert
 $temp2 = intval($result[3]); // intval macht einen integer-wert (bzw float) aus ihnen

 echo 'temp1: '.$temp1.'<br />';
 echo 'temp2: '.$temp2.'<br />';

}
else
{
 echo 'Suchmuster konnte nicht gefunden werden!';
}
Poste mal was dabei rauskommt.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Guten morgen,

habe gestern noch den Code versucht. Leider kommt nur "Interner Server Fehler 500" als ausgabe. Sonst nix mehr. Sowohl wenn ich den Code in die gepostete Index.php einbinde, sowie in eine "Nackte" Index.php welches nur den von Dir geposteten Code enthält. Beides mal erscheint der "Interner Server Fehler 500".

Bin grad etwas ratlos.....Kann man das den nicht irgendwie auf Error Reporting stellen? Irgendwie bin ich ja Blind und kann euch und mir ja auch keine weiteren Fehlerbeschreibung liefern.

@Voralpenkreuz: Nur zur Info, Du hast recht. Wenn ich den Code so umstelle wie Du es gepostet hast, funktioniert es. smiley
Logged

Pages: [1] 2   Go Up
Jump to: