CSV Datei voom EMU Datenlogger einlesen

Hallo liebe Gemeinde,

ich möchte gern die Daten meines Logger EMU S0 Logger die ich per


<?
$monat = date("Y".'_'."m");// Datei definieren //

$text = file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");

  

echo $text;
?>

hole auslesen. Die Daten kommen

{ „SerialNumber“: „16735367“, „DateTime“: „1424262838“, „Meters“: [{ „InputNumber“: „1“, „Name“: „Verein“, „Type“: „Electricity“, „Value“: 0.043, „Unit“: „KWh“ }, { „InputNumber“: „1.1“, „Name“: „Verein“, „Type“: „Electricity Power“, „Value“: null, „Unit“: „W“ }, { „InputNumber“: „2“, „Name“: „Küche“, „Type“: „Electricity“, „Value“: 0.042, „Unit“: „KWh“ }, { „InputNumber“: „2.1“, „Name“: „Küche“, „Type“: „Electricity Power“, „Value“: null, „Unit“: „W“ }, { „InputNumber“: „3“, „Name“: „Flutlicht“, „Type“: „Electricity“, „Value“: 0.044, „Unit“: „KWh“ }, { „InputNumber“: „3.1“, „Name“: „Flutlicht“, „Type“: „Electricity Power“, „Value“: null, „Unit“: „W“ }, { „InputNumber“: „4“, „Name“: „Kaltwasser Verein“, „Type“: „Water“, „Value“: 0.037, „Unit“: „ccm“ }, { „InputNumber“: „4.1“, „Name“: „Kaltwasser Verein“, „Type“: „Water Power“, „Value“: null, „Unit“: „l“ }, { „InputNumber“: „5“, „Name“: „Warmwasser Gastro“, „Type“: „Water“, „Value“: 3.131, „Unit“: „ccm“ }, { „InputNumber“: „5.1“, „Name“: „Warmwasser Gastro“, „Type“: „Water Power“, „Value“: 0.000, „Unit“: „l“ }, { „InputNumber“: „6“, „Name“: „Kaltwasser Gastro“, „Type“: „Water“, „Value“: 1.597, „Unit“: „ccm“ }, { „InputNumber“: „6.1“, „Name“: „Kaltwasser Gastro“, „Type“: „Water Power“, „Value“: 0.000, „Unit“: „l“ }, { „InputNumber“: „7“, „Name“: „Warmwasser Verein“, „Type“: „Water“, „Value“: 0.030, „Unit“: „ccm“ }, { „InputNumber“: „7.1“, „Name“: „Warmwasser Verein“, „Type“: „Water Power“, „Value“: null, „Unit“: „l“ }, { „InputNumber“: „8“, „Name“: „Gas“, „Type“: „Gas“, „Value“: 0.000, „Unit“: „ccm“ }, { „InputNumber“: „8.1“, „Name“: „Gas“, „Type“: „Gas Power“, „Value“: null, „Unit“: „ccm“ }, { „InputNumber“: „11“, „Name“: „Temp. Rücklauf Zirkulation WW“, „Type“: „Temperature“, „Value“: null, „Unit“: „degree C“ } ] }

in diesem Format.

Wie komme ich nun an die Werte z.b. „Warmwasser Verein“ — „Value“: ???
Danke und
Gruß Mike

Das sieht doch stark nach Json aus.
Versuche es mal damit
PHP: json_decode - Manual
Kannst es so in ein Objekt oder Array überführen.
Michael

Alternativ könnte das hier funktionieren >> PHP: str_getcsv - Manual

Grüße,
Chris

Hallo

Danke für die schnellen Antworten… Ich habe mal versucht mich mit meinen „Nicht Englisch“ Kentnissen einzulesen. Leider raffe ich es nicht.
Könntet Ihr mir eine Starthilfe in Form eines Codeschnipsels geben?

Gruß Mike

Hier mal ein Beispiel was nicht auf dich, sondern nur auf json bezogen ist:

<?
// OpenWeatherMap.org  --  http://openweathermap.org/city/2904589
$locationID = 2925533;

$content = Sys_GetURLContent("http://api.openweathermap.org/data/2.5/weather?id=".$locationID."&units=metric&lang=de&type=day");
$json = json_decode($content);
//print_r($json);


echo "Aktuelle Wetterdaten für ".$json->name."

";

echo "Wetter: ".$json->weather[0]->description."
";

echo "Temperatur: ".$json->main->temp."°C"."
";
echo "Temperatur (min.): ".$json->main->temp_min."°C"."
";
echo "Temperatur (max.): ".$json->main->temp_max."°C"."
";

echo "Luftdruck: ".$json->main->pressure."hpa"."
";
echo "Luftfeuchtigkeit: ".$json->main->humidity."%"."
";

echo "Windgeschwindigkeit: ".$json->wind->speed." Meter/Sekunde"."
";
echo "Windrichtung: ".$json->wind->speed." Grad"."
";
?>

Und jetzt auf deinen Fall bezogen:

<?
$monat = date("Y".'_'."m");// Datei definieren //
$content = Sys_GetURLContent("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
$json = json_decode($content);
print_r($json);
?>

> und dann mal sehen was da raus kommt :slight_smile:

Grüße,
Chris

Hallo,

ich habe es so versucht


$monat = date("Y".'_'."m");// Datei definieren //
$content1 = file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
$json1 = json_decode($content1);
echo $json1->Name;

da bekomme ich fogende Fehlermeldung

Notice: Trying to get property of non-object in [auslesen datenlogger] on line 5

Vieleicht noch ne andere Idee?

Gruß Mike

Ups, Sorry habe von unterwegs nicht gesehen ob es die auch auf deutsch gibt :slight_smile:
Hier noch mal der Link zur DE Doku:
PHP: json_decode - Manual

Hast du dir die Ausgabe von print_r angesehen ?
Es müßte so lauten:

echo $json1->Meters[0]->Name;

Hier mal was ‚fast‘ fertiges:


$monat = date("Y".'_'."m");// Datei definieren //

$text = file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
$json = json_decode($text);
foreach ($json->Meters as $Meter)
{
	echo "InputNumber: ". $Meter->InputNumber.PHP_EOL;
	echo "Name: ". $Meter->Name.PHP_EOL;
	echo "Type: ". $Meter->Type.PHP_EOL;
	echo "Value: ". $Meter->Value.PHP_EOL;
	echo "Unit: ". $Meter->Unit.PHP_EOL;
	echo "-----------------------------".PHP_EOL;
}

Bei mir sieht das dann so aus:


InputNumber: 1
Name: Verein
Type: Electricity
Value: 0.043
Unit: KWh
-----------------------------
InputNumber: 1.1
Name: Verein
Type: Electricity Power
Value: 
Unit: W
-----------------------------
InputNumber: 2
Name: Küche
Type: Electricity
Value: 0.042
Unit: KWh
-----------------------------
InputNumber: 2.1
Name: Küche
Type: Electricity Power
Value: 
Unit: W
-----------------------------
InputNumber: 3
Name: Flutlicht
Type: Electricity
Value: 0.044
Unit: KWh
-----------------------------
InputNumber: 3.1
Name: Flutlicht
Type: Electricity Power
Value: 
Unit: W
-----------------------------
InputNumber: 4
Name: Kaltwasser Verein
Type: Water
Value: 0.037
Unit: ccm
-----------------------------
InputNumber: 4.1
Name: Kaltwasser Verein
Type: Water Power
Value: 
Unit: l
-----------------------------
InputNumber: 5
Name: Warmwasser Gastro
Type: Water
Value: 3.131
Unit: ccm
-----------------------------
InputNumber: 5.1
Name: Warmwasser Gastro
Type: Water Power
Value: 0
Unit: l
-----------------------------
InputNumber: 6
Name: Kaltwasser Gastro
Type: Water
Value: 1.597
Unit: ccm
-----------------------------
InputNumber: 6.1
Name: Kaltwasser Gastro
Type: Water Power
Value: 0
Unit: l
-----------------------------
InputNumber: 7
Name: Warmwasser Verein
Type: Water
Value: 0.03
Unit: ccm
-----------------------------
InputNumber: 7.1
Name: Warmwasser Verein
Type: Water Power
Value: 
Unit: l
-----------------------------
InputNumber: 8
Name: Gas
Type: Gas
Value: 0
Unit: ccm
-----------------------------
InputNumber: 8.1
Name: Gas
Type: Gas Power
Value: 
Unit: ccm
-----------------------------
InputNumber: 11
Name: Temp. Rücklauf Zirkulation WW
Type: Temperature
Value: 
Unit: degree C
-----------------------------

Reicht das ?
Ansonsten, hier wie ich jetzt weiter machen würde.

[ul]
[li]Da wir nicht wissen ob sich die Reihenfolge der Daten ändert, brauchen wir etwas womit wir die IPS-Variable zuordnen können[/li][li]InputNumber wäre eine gute Zuordnung.[/li][li]Da der ‚Ident‘ in IPS nur aus Buchstaben uns Zahlen bestehen darf, müssen wir den Punkt z.B. durch ein ‚a‘ ersetzen[/li][li]Dann holen wir die Variable mit $id =IPS_GetObjectIDByIdent[/li][li]Ist $id eine 0 dann müssen wir die Variable erst erstellen, den Ident setzen, den Parent setzen, das Profil festlegen, einen Namen vergeben etc…[/li][li]Nun könnten wir die Variable mit $Meter->Value befüllen. Eventuell reicht das schon.[/li][li] Mit etwas Pech muß $Meter->Unit oder $Meter->Type ausgewertet werden um $Meter->Value in das richtige Format zu bekommen (Float oder Integer) und illegale Werte zu ignorieren (da oben steht öfters mal ‚null‘ als Value )[/li][/ul]

Michael

Hallo …

Danke Dir Michael für deine schnelle Hilfe. Aber ich glaub ich werde beklo…
Ich hab es jetzt so


<?
$monat = date("Y".'_'."m");// Datei definieren //
$text = file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
$json = json_decode($text);
foreach ($json->Meters as $Meter){
    echo "InputNumber: ". $Meter->InputNumber.PHP_EOL;
    echo "Name: ". $Meter->Name.PHP_EOL;
    echo "Type: ". $Meter->Type.PHP_EOL;
    echo "Value: ". $Meter->Value.PHP_EOL;
    echo "Unit: ". $Meter->Unit.PHP_EOL;
    echo "-----------------------------".PHP_EOL;
}
?>

und bekomme nicht wie du eine Ausgabe sondern dies hier

Notice: Trying to get property of non-object in D:\IP-Symcon\scripts\23136.ips.php on line 5

Warning: Invalid argument supplied for foreach() in D:\IP-Symcon\scripts\23136.ips.php on line 5

Gruß Mike

Probier mal das aus… ich glaube da stimmt was nicht mit den Daten (Codierung, Umlaute etc…)
Obwohl drei verschiedene JSON Validators sagen das sie korrekt sind :frowning:
(Ich hatte deine Daten zum testen direkt in das Script kopiert…da fällt so etwas nicht unbedingt auf)


<?
if (!function_exists('json_last_error_msg')) {
    function json_last_error_msg() {
        static $errors = array(
            JSON_ERROR_NONE             => null,
            JSON_ERROR_DEPTH            => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH   => 'Underflow or the modes mismatch',
            JSON_ERROR_CTRL_CHAR        => 'Unexpected control character found',
            JSON_ERROR_SYNTAX           => 'Syntax error, malformed JSON',
            JSON_ERROR_UTF8             => 'Malformed UTF-8 characters, possibly incorrectly encoded'
        );
        $error = json_last_error();
        return array_key_exists($error, $errors) ? $errors[$error] : "Unknown error ({$error})";
    }
}

$monat = date("Y".'_'."m");// Datei definieren //
$text = file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
$json = json_decode($text);

if (is_null($json))
{
   echo "Fehler beim dekodieren: ".json_last_error_msg();
   return;
}

foreach ($json->Meters as $Meter)
{
    echo "InputNumber: ". $Meter->InputNumber.PHP_EOL;
    echo "Name: ". $Meter->Name.PHP_EOL;
    echo "Type: ". $Meter->Type.PHP_EOL;
    echo "Value: ". $Meter->Value.PHP_EOL;
    echo "Unit: ". $Meter->Unit.PHP_EOL;
    echo "-----------------------------".PHP_EOL;
}
?>

Wenn dann das hier kommt:
‚Malformed UTF-8 characters, possibly incorrectly encoded‘

Kannst du das versuchen:


//alt :
$text = file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
// ersetzt durch 
$text = utf8_encode(file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv"));

Michael

Hallo Michael

hier die Rückmeldung

Fehler beim dekodieren: Malformed UTF-8 characters, possibly incorrectly encoded

Gruß Mike

Hallo

danke danke nochmal für eure Mühe. So funktioniert es


<?
if (!function_exists('json_last_error_msg')) {
    function json_last_error_msg() {
        static $errors = array(
            JSON_ERROR_NONE             => null,
            JSON_ERROR_DEPTH            => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH   => 'Underflow or the modes mismatch',
            JSON_ERROR_CTRL_CHAR        => 'Unexpected control character found',
            JSON_ERROR_SYNTAX           => 'Syntax error, malformed JSON',
            JSON_ERROR_UTF8             => 'Malformed UTF-8 characters, possibly incorrectly encoded'
        );
        $error = json_last_error();
        return array_key_exists($error, $errors) ? $errors[$error] : "Unknown error ({$error})";
    }
}

$monat = date("Y".'_'."m");// Datei definieren //
$text = utf8_encode(file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv"));
$json = json_decode($text);
if (is_null($json))
{
echo "Fehler beim dekodieren: ".json_last_error_msg();

return;
}
foreach ($json->Meters as $Meter){
    echo "InputNumber: ". $Meter->InputNumber.PHP_EOL;
    echo "Name: ". $Meter->Name.PHP_EOL;
    echo "Type: ". $Meter->Type.PHP_EOL;
    echo "Value: ". $Meter->Value.PHP_EOL;
    echo "Unit: ". $Meter->Unit.PHP_EOL;
    echo "-----------------------------".PHP_EOL;
}
?>

und erhalte dann


InputNumber: 1
Name: Verein
Type: Electricity
Value: 0.043
Unit: KWh
-----------------------------
InputNumber: 1.1
Name: Verein
Type: Electricity Power
Value: 
Unit: W
-----------------------------
InputNumber: 2
Name: Küche
Type: Electricity
Value: 0.042
Unit: KWh
-----------------------------
InputNumber: 2.1
Name: Küche
Type: Electricity Power
Value: 
Unit: W
-----------------------------
InputNumber: 3
Name: Flutlicht
Type: Electricity
Value: 0.044
Unit: KWh
-----------------------------
InputNumber: 3.1
Name: Flutlicht
Type: Electricity Power
Value: 
Unit: W
-----------------------------
InputNumber: 4
Name: Kaltwasser Verein
Type: Water
Value: 0.037
Unit: ccm
-----------------------------
InputNumber: 4.1
Name: Kaltwasser Verein
Type: Water Power
Value: 
Unit: l
-----------------------------
InputNumber: 5
Name: Warmwasser Gastro
Type: Water
Value: 3.135
Unit: ccm
-----------------------------
InputNumber: 5.1
Name: Warmwasser Gastro
Type: Water Power
Value: 0
Unit: l
-----------------------------
InputNumber: 6
Name: Kaltwasser Gastro
Type: Water
Value: 1.607
Unit: ccm
-----------------------------
InputNumber: 6.1
Name: Kaltwasser Gastro
Type: Water Power
Value: 0
Unit: l
-----------------------------
InputNumber: 7
Name: Warmwasser Verein
Type: Water
Value: 0.03
Unit: ccm
-----------------------------
InputNumber: 7.1
Name: Warmwasser Verein
Type: Water Power
Value: 
Unit: l
-----------------------------
InputNumber: 8
Name: Gas
Type: Gas
Value: 0
Unit: ccm
-----------------------------
InputNumber: 8.1
Name: Gas
Type: Gas Power
Value: 
Unit: ccm
-----------------------------
InputNumber: 11
Name: Temp. Rücklauf Zirkulation WW
Type: Temperature
Value: 
Unit: degree C
-----------------------------

außer das er „ü“ usw nicht erkennt haut dieser teil erst mal hin.

Vielen Dank

Na dann probier mal das.
Variablen werden auf gleicher Höhe wie das Script automatisch erstellt.
Am besten das Script vorher in ein Dummy-Modul werfen.
Fehler beim laden oder dekodieren werden in das Log geschrieben.
Ebenso wenn eine Einheit ($Meter->Unit) nicht im Script berücksichtigt wird.
Felder ohne Daten (Also wenn dort gar kein Wert vorhanden ist.) werden ignoriert.

Da in deinem Beispiel keine Werte für Watt und Liter waren, habe ich den Bereich auskommentiert.
Und für Kubikzentimeter mußt du dir noch ein Variablenprofil anlegen und den Variablen dann zuweisen.

Der Rest sollte aber (hoffentlich) passen.


<?
if( $_IPS['SENDER'] == "Execute")
{
	IPS_SetHidden($_IPS['SELF'],true);
}

$monat = date("Y".'_'."m");// Datei definieren //

$text = @file_get_contents("http://xxx.xxx.xxx.xxx:xxxxx/'.$monat.'.csv");
if ($text === false)
{
	IPS_LogMessage((string)$_IPS['SELF'],'Fehler beim laden der Daten');
	return;
}

$text = utf8_decode($text);

$json = json_decode($text);

if (is_Null($json))
{
	IPS_LogMessage((string)$_IPS['SELF'],'Keine gültigen Daten gelesen');
	return;
}

$parent = IPS_GetParent($_IPS['SELF']);
foreach ($json->Meters as $Meter)
{
	if (!is_numeric($Meter->Value)) continue; //  Kein Wert -> weiter mit dem nächsten.
	
	$ident = str_replace('.','a',$Meter->InputNumber);
	$vid = @IPS_GetObjectIDByIdent($ident,$parent); // Variablen ID holen
	if ($vid == 0) // Variable vorhanden ?
	{
	   switch ($Meter->Unit)
	   {
		   case 'KWh':
				$varProfil ='~Electricity'; // Sollte passen
				break;
// Watt habe ich mal auskommentiert, da scheinen ja keine Daten zu kommen
/*		   case 'W':
				$varProfil =''; // ~Power ist kW es werden aber nur W (naja nicht) geliefert
				break;
*/
		   case 'ccm':
				$varProfil =''; // ~Liter wäre zu groß von der Einheit, da 1000 ccm 1 Liter sind -> eigens Profil später per Hand anlegen
				break;
// Liter habe ich mal auskommentiert, da scheinen ja keine Daten zu kommen
/*
		   case 'l':
				$varProfil ='~Liter';
				break;
*/
// degree C habe ich mal auskommentiert, da scheinen ja keine Daten zu kommen
/*
		   case 'degree C':
				$varProfil ='~Temperature';
				break;
*/
			default:
				$varProfil ='';
				IPS_LogMessage((string)$_IPS['SELF'],'Unbekannte Einheit: '.$Meter->Unit);
			break;
		}
	   $vid = IPS_CreateVariable(2);
		IPS_SetName($vid,utf8_decode($Meter->Name));
		IPS_SetParent($vid,$parent);
		IPS_SetIdent($vid,$ident);
		IPS_SetVariableCustomProfile($vid,$varProfil);
	}
	SetValueFloat($vid,$Meter->Value);
}
?>

Michael