Kindle Netatmo Code

  • <php


    // Zugangsdaten Netatmo


    $username = "your@user.name";

    $password = "yourpassword";

    $app_id = "netatmo-app-id";

    $app_secret = "netatmo-app-secret";



    // Token anfordern


    $postdata = array(

    'grant_type' => "password",

    'client_id' => $app_id,

    'client_secret' => $app_secret,

    'username' => $username,

    'password' => $password,

    'scope' => 'read_station'

    );


    $url = "https://api.netatmo.net/oauth2/token";


    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);

    curl_setopt($ch, CURLOPT_POST, 1);

    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    curl_setopt($ch, CURLOPT_HEADER, 0);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    $response = curl_exec($ch);

    curl_close($ch);



    // Anfrage mit Token


    $params = null;

    $params = json_decode($response, true);

    $api_url = "https://api.netatmo.net/api/devicelist?access_token=" . $params['access_token'];



    // Daten abrufen


    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $api_url);

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    curl_setopt($ch, CURLOPT_HEADER, 0);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    $array = curl_exec($ch);

    curl_close($ch);



    $netatmo = json_decode($array,true);

    // hier müssen die ids angepasst werden. meine Module haben komischerweise höhere Nummern weil

    // in meinem Account zuerst die Module von einer befreundeten freigegebenen Station gefunden werden...

    // der Vorteil der Zuordnung hier ist, dass im Folgenden nichts mehr angepasst werden muss.

    $device0 = "0"; //Basisstation

    $module0 = "5"; //Außenmodul

    $module1 = "6"; //1. Innenmodul

    $module2 = "7"; //Regenmesser

    $module3 = "8"; //2. Innenmodul


    // Messwerte bereitstellen


    $name_station = $netatmo["body"]["devices"][$device0]["station_name"];

    $date_station = $netatmo["body"]["devices"][$device0]["last_status_store"];

    $name_base = $netatmo["body"]["devices"][$device0]["module_name"];

    $temp_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["Temperature"];

    $humi_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["Humidity"];

    $CO2_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["CO2"];

    $min_temp_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["min_temp"];

    $max_temp_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["max_temp"];

    $min_date_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["date_min_temp"];

    $max_date_base = $netatmo["body"]["devices"][$device0]["dashboard_data"]["date_max_temp"];

    $pressure = $netatmo["body"]["devices"][$device0]["dashboard_data"]["Pressure"];

    $name_mod0 = $netatmo["body"]["modules"][$module0]["module_name"];

    $temp_mod0 = $netatmo["body"]["modules"][$module0]["dashboard_data"]["Temperature"];

    $humi_mod0 = $netatmo["body"]["modules"][$module0]["dashboard_data"]["Humidity"];

    $min_temp_mod0 = $netatmo["body"]["modules"][$module0]["dashboard_data"]["min_temp"];

    $max_temp_mod0 = $netatmo["body"]["modules"][$module0]["dashboard_data"]["max_temp"];

    $min_date_mod0 = $netatmo["body"]["modules"][$module0]["dashboard_data"]["date_min_temp"];

    $max_date_mod0 = $netatmo["body"]["modules"][$module0]["dashboard_data"]["date_max_temp"];

    $name_rain = $netatmo["body"]["modules"][$module2]["module_name"];

    $rain_1 = $netatmo["body"]["modules"][$module2]["dashboard_data"]["sum_rain_1"];

    $rain_24 = $netatmo["body"]["modules"][$module2]["dashboard_data"]["sum_rain_24"];

    $name_mod1 = $netatmo["body"]["modules"][$module1]["module_name"];

    $temp_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["Temperature"];

    $humi_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["Humidity"];

    $CO2_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["CO2"];

    $min_temp_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["min_temp"];

    $max_temp_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["max_temp"];

    $min_date_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["date_min_temp"];

    $max_date_mod1 = $netatmo["body"]["modules"][$module1]["dashboard_data"]["date_max_temp"];

    $name_mod3 = $netatmo["body"]["modules"][$module3]["module_name"];

    $temp_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["Temperature"];

    $humi_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["Humidity"];

    $CO2_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["CO2"];

    $min_temp_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["min_temp"];

    $max_temp_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["max_temp"];

    $min_date_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["date_min_temp"];

    $max_date_mod3 = $netatmo["body"]["modules"][$module3]["dashboard_data"]["date_max_temp"];


    // Berechnung Sonnenauf- und -untergang


    $latitude = $netatmo["body"]["devices"][$device0]["place"]["location"][1];

    $longitude = $netatmo["body"]["devices"][$device0]["place"]["location"][0];

    $time = time();

    $dst = date("I", $time);

    if ($dst) {

    $offset = 2;

    } else {

    $offset = 1;

    }

    $zenith = 50/60;

    $zenith = $zenith + 90;

    $sunrise = date_sunrise($time, SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude, $zenith, $offset);

    $sunrise = date("H:i", $sunrise);

    $sunset = date_sunset($time, SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude, $zenith, $offset);

    $sunset = date("H:i", $sunset);


    // Taupunkt-Berechnung


    if ($temp_mod0 > 0) {

    $k2 = 17.62;

    $k3 = 243.12;

    } else {

    $k2 = 22.46;

    $k3 = 272.62;

    }

    $dewpoint = $k3 *(($k2 * $temp_mod0) / ($k3 + $temp_mod0) + log($humi_mod0 / 100));

    $dewpoint = $dewpoint / (($k2 * $k3) / ($k3 + $temp_mod0) - log($humi_mod0 / 100));

    $dewpoint = round($dewpoint, 1);


    // Messwerte formatieren


    $min_date_mod0 = date("H:i",$min_date_mod0);

    $max_date_mod0 = date("H:i",$max_date_mod0);

    $min_date_base = date("H:i", $min_date_base);

    $max_date_base = date("H:i", $max_date_base);

    $min_date_mod1 = date("H:i", $min_date_mod1);

    $max_date_mod1 = date("H:i", $max_date_mod1);

    $min_date_mod3 = date("H:i", $min_date_mod3);

    $max_date_mod3 = date("H:i", $max_date_mod3);

    $date_station = DatumText($date_station);

    $temp_mod0 = number_format($temp_mod0,1,",","");

    $temp_base = number_format($temp_base,1,",","");

    $temp_mod1 = number_format($temp_mod1,1,",","");

    $temp_mod3 = number_format($temp_mod3,1,",","");

    $pressure = number_format($pressure,1,",","");

    $dewpoint = number_format($dewpoint,1,",","");

    $rain_1 = number_format($rain_1,1,",","");

    $rain_24 = number_format($rain_24,1,",","");

    $max_temp_mod0 = number_format($max_temp_mod0,1,",","");

    $min_temp_mod0 = number_format($min_temp_mod0,1,",","");

    $max_temp_base = number_format($max_temp_base,1,",","");

    $min_temp_base = number_format($min_temp_base,1,",","");

    $max_temp_mod1 = number_format($max_temp_mod1,1,",","");

    $min_temp_mod1 = number_format($min_temp_mod1,1,",","");

    $max_temp_mod3 = number_format($max_temp_mod3,1,",","");

    $min_temp_mod3 = number_format($min_temp_mod3,1,",","");


    // Variablen


    $filename = "weather-script-output.png";


    // Schriftart aus den Beispielen der c't

    $DEFAULT_FONT = array("regular"=>realpath("./fonts/LiberationSans-Regular.ttf"),"bold"=>realpath("./fonts/LiberationSans-Bold.ttf"),"italic"=>realpath("./fonts/LiberationSans-Italic.ttf"));


    // Leere PNG-Datei mit weißem Hintergrund erstellen


    $im = @ImageCreateTrueColor(640,384);

    $background = ImageColorAllocate($im, 255, 255, 255);

    ImageFilledRectangle($im, 0, 0, 640, 384, $background);


    // über die Schriftgröße wird nachher ALLES skaliert

    $fontSize = 15;

    $cursorY = $fontSize*2.7;

    $X0 = $fontsize;

    $X1 = $fontSize*6.66;

    $X2 = $fontSize*12;

    $X3 = $fontSize*17.33;

    $X4 = $fontSize*23;

    $X5 = $fontSize*28;

    $X6 = $fontSize*38;

    // Farbe für Schrift und Hilfslinien festlegen


    $black = ImageColorAllocate($im, 0, 0, 0);

    $red = ImageColorAllocate($im, 255,0,0);

    $color = $black;

    $fontb = $DEFAULT_FONT['bold'];

    $fontr = $DEFAULT_FONT['regular'];

    // Text einfügen


    ImageTTFText($im, $fontSize*2.1, 0, $X0, $cursorY, $color, $fontb, $name_station);

    ImageTTFText($im, $fontSize/1.5, 0, $X5, $cursorY-$fontSize*1.1, $color, $fontr, "Sonnenaufgang ".$sunrise);

    ImageTTFText($im, $fontSize/1.5, 0, $X5, $cursorY, $color, $fontr, "Sonnenuntergang ".$sunset);

    $cursorY = $cursorY+$fontSize*1.5;

    ImageTTFText($im, $fontSize*0.7, 0, $X0+20, $cursorY, $color, $fontr, "Letzte Aktualisierung: ".$date_station);


    $cursorY = $cursorY+$fontSize*2;

    ImageTTFText($im, $fontSize*1.3, 0, $X0, $cursorY, $color, $fontr, $name_mod0);

    ImageTTFText($im, $fontSize*0.55, 0, $X3, $cursorY, $color, $fontr, "Luftfeuchtigkeit");

    ImageTTFText($im, $fontSize*0.55, 0, $X5, $cursorY, $color, $fontr, "Luftdruck");

    $cursorY = $cursorY+$fontSize*2.1;

    If(intval($temp_mod0) <= 4 || intval($temp_mod0) >= 30){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X0, $cursorY, $color, $fontr, $temp_mod0);

    $color = $black;

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize*1.2, $color, $fontr, $max_temp_mod0." / ".$max_date_mod0);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize/3, $color, $fontr, $min_temp_mod0." / ".$min_date_mod0);

    ImageTTFText($im, $fontSize*1.5, 0, $X2, $cursorY-$fontSize/4, $color, $fontr, "°C");

    ImageTTFText($im, $fontSize*2, 0, $X3, $cursorY, $color, $fontr, $humi_mod0);

    ImageTTFText($im, $fontSize*1.5, 0, $X4, $cursorY-$fontSize/4, $color, $fontr, "%");

    ImageTTFText($im, $fontSize*2, 0, $X5, $cursorY, $color, $fontr, $pressure);

    ImageTTFText($im, $fontSize*1.5, 0, $X6, $cursorY-$fontSize/4, $color, $fontr, "hPa");


    $cursorY = $cursorY+$fontSize*1.5;

    ImageTTFText($im, $fontSize*0.55, 0, $X0, $cursorY, $color, $fontr, "Niederschlag letzte Stunde");

    ImageTTFText($im, $fontSize*0.55, 0, $X3, $cursorY, $color, $fontr, "Niederschlag letzter Tag");

    ImageTTFText($im, $fontSize*0.55, 0, $X5, $cursorY, $color, $fontr, "Taupunkt");

    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*2, 0, $X0, $cursorY, $color, $fontr, $rain_1);

    ImageTTFText($im, $fontSize*0.8, 0, $X1, $cursorY-$fontSize/3, $color, $fontr, "mm");

    ImageTTFText($im, $fontSize*2, 0, $X3, $cursorY, $color, $fontr, $rain_24);

    ImageTTFText($im, $fontSize*0.8, 0, $X4, $cursorY-$fontSize/3, $color, $fontr, "mm");

    ImageTTFText($im, $fontSize*2, 0, $X5, $cursorY, $color, $fontr, $dewpoint);

    ImageTTFText($im, $fontSize*1.5, 0, $X6, $cursorY-$fontSize/4, $color, $fontr, "°C");


    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*1.3, 0, $X0, $cursorY, $color, $fontr, $name_base);

    ImageTTFText($im, $fontSize*0.55, 0, $X3, $cursorY, $color, $fontr, "Luftfeuchtigkeit");

    ImageTTFText($im, $fontSize*0.55, 0, $X5, $cursorY, $color, $fontr, "CO2-Gehalt");

    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*2, 0, $X0, $cursorY, $color, $fontr, $temp_base);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize*1.2, $color, $fontr, $max_temp_base." / ".$max_date_base);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize/3, $color, $fontr, $min_temp_base." / ".$min_date_base);

    ImageTTFText($im, $fontSize*1.5, 0, $X2, $cursorY-$fontSize/4, $color, $fontr, "°C");

    If(intval($humi_base) > 60 || intval($humi_base) < 40){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X3, $cursorY, $color, $fontr, $humi_base);

    $color =$black;

    ImageTTFText($im, $fontSize*1.5, 0, $X4, $cursorY-$fontSize/4, $color, $fontr, "%");

    If(intval($CO2_base) >1500){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X5, $cursorY, $color, $fontr, $CO2_base);

    $color = $black;

    ImageTTFText($im, $fontSize*1.5, 0, $X6, $cursorY-$fontSize/4, $color, $fontr, "ppm");


    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*1.3, 0, $X0, $cursorY, $color, $fontr, $name_mod1);

    ImageTTFText($im, $fontSize*0.55, 0, $X3, $cursorY, $color, $fontr, "Luftfeuchtigkeit");

    ImageTTFText($im, $fontSize*0.55, 0, $X5, $cursorY, $color, $fontr, "CO2-Gehalt");

    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*2, 0, $X0, $cursorY, $color, $fontr, $temp_mod1);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize*1.2, $color, $fontr, $max_temp_mod1." / ".$max_date_mod1);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize/3, $color, $fontr, $min_temp_mod1." / ".$min_date_mod1);

    ImageTTFText($im, $fontSize*1.5, 0, $X2, $cursorY-$fontSize/4, $color, $fontr, "°C");

    If(intval($humi_mod1) > 60 || intval($humi_mod1) < 40){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X3, $cursorY, $color, $fontr, $humi_mod1);

    $color = $black;

    ImageTTFText($im, $fontSize*1.5, 0, $X4, $cursorY-$fontSize/4, $color, $fontr, "%");

    If(intval($CO2_mod1) > 1500){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X5, $cursorY, $color, $fontr, $CO2_mod1);

    $color = $black;

    ImageTTFText($im, $fontSize*1.5, 0, $X6, $cursorY-$fontSize/4, $color, $fontr, "ppm");


    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*1.3, 0, $X0, $cursorY, $color, $fontr, $name_mod3);

    ImageTTFText($im, $fontSize*0.55, 0, $X3, $cursorY, $color, $fontr, "Luftfeuchtigkeit");

    ImageTTFText($im, $fontSize*0.55, 0, $X5, $cursorY, $color, $fontr, "CO2-Gehalt");

    $cursorY = $cursorY+$fontSize*2.1;

    ImageTTFText($im, $fontSize*2, 0, $X0, $cursorY, $color, $fontr, $temp_mod3);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize*1.2, $color, $fontr, $max_temp_mod3." / ".$max_date_mod3);

    ImageTTFText($im, $fontSize*0.55, 0, $X1, $cursorY-$fontSize/3, $color, $fontr, $min_temp_mod3." / ".$min_date_mod3);

    ImageTTFText($im, $fontSize*1.5, 0, $X2, $cursorY-$fontSize/4, $color, $fontr, "°C");

    If(intval($humi_mod3) > 60 || intval($humi_mod3) < 40){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X3, $cursorY, $color, $fontr, $humi_mod3);

    $color = $black;

    ImageTTFText($im, $fontSize*1.5, 0, $X4, $cursorY-$fontSize/4, $color, $fontr, "%");

    If(intval($CO2_mod3) >1500){$color = $red;} else {$color = $black;}

    ImageTTFText($im, $fontSize*2, 0, $X5, $cursorY, $color, $fontr, $CO2_mod3);

    $color = $black;

    ImageTTFText($im, $fontSize*1.5, 0, $X6, $cursorY-$fontSize/4, $color, $fontr, "ppm");


    // PNG-erstellen, könnte man für's c't-Projekt auch weglassen

    ImagePNG($im, $filename);


    // wenn Aufruf mit 'weather-script.php?debug=true', dann Ausgabe als png, sonst als Bytestream für's ePaper

    if($_GET['debug'] == 'true'){

    header("Content-type: image/png");

    imagepng($im);

    }

    else{

    header("X-productionMode: true"); // siehe Anleitung c't, auf false setzen um ESP32 Weboberfläche zu aktivieren

    echo rawImage($im);

    // echo ASCIIImage($im); // stellt die Grafik im browser aus nullen und einsen dar, nur zum testen

    }

    imagedestroy($im);


    function rawImage($im) {

    $bits = "";

    $bytes = "";

    $pixelcount = 0;


    for ($y = 0; $y < imagesy($im); $y++) {

    for ($x = 0; $x < imagesx($im); $x++) {


    $rgb = imagecolorat($im, $x, $y);

    $r = ($rgb >> 16) & 0xFF;

    $g = ($rgb >> 8 ) & 0xFF;

    $b = $rgb & 0xFF;

    $gray = ($r + $g + $b) / 3;


    if ($gray < 0xFF) {

    $bits .= "1";

    }else {

    $bits .= "0";

    }


    $pixelcount++;

    if ($pixelcount % 8 == 0) {

    $bytes .= pack('H*', str_pad(base_convert($bits, 2, 16),2, "0", STR_PAD_LEFT));

    $bits = "";

    }

    }

    }

    return $bytes;

    }

    // diese Funktion ist nur zum testen ob die Konvertierung grundsätzlich klappt

    function ASCIIImage($im) {

    $bits = "";

    $bytes = "";

    $pixelcount = 0;


    for ($y = 0; $y < imagesy($im); $y++) {

    for ($x = 0; $x < imagesx($im); $x++) {


    $rgb = imagecolorat($im, $x, $y);

    $r = ($rgb >> 16) & 0xFF;

    $g = ($rgb >> 8 ) & 0xFF;

    $b = $rgb & 0xFF;

    $gray = ($r + $g + $b) / 3;


    if ($gray < 0xFF) {

    $bits .= "1";

    }else {

    $bits .= "0";

    }


    $pixelcount++;

    if ($pixelcount % 8 == 0) {

    $bytes .= $bits;

    $bits = "";

    }

    }

    $bytes .= "\n";

    }

    return $bytes;

    }

    function DatumText($ti) {

    $time = $ti;

    $weekday = date("D", $time);

    $day = date("j", $time);

    $month = date("n", $time);

    $year = date("Y", $time);

    $zeit = date("H:i", $time);


    switch ($weekday) {

    case "Mon":

    $weekday = "Montag";

    break;

    case "Tue":

    $weekday = "Dienstag";

    break;

    case "Wed":

    $weekday = "Mittwoch";

    break;

    case "Thu":

    $weekday = "Donnerstag";

    break;

    case "Fri":

    $weekday = "Freitag";

    break;

    case "Sat":

    $weekday = "Samstag";

    break;

    case "Sun":

    $weekday = "Sonntag";

    break;

    }


    switch ($month) {

    case 1:

    $month = "Januar";

    break;

    case 2:

    $month = "Februar";

    break;

    case 3:

    $month = "März";

    break;

    case 4:

    $month = "April";

    break;

    case 5:

    $month = "Mai";

    break;

    case 6:

    $month = "Juni";

    break;

    case 7:

    $month = "Juli";

    break;

    case 8:

    $month = "August";

    break;

    case 9:

    $month = "September";

    break;

    case 10:

    $month = "Oktober";

    break;

    case 11:

    $month = "November";

    break;

    case 12:

    $month = "Dezember";

    break;

    }


    return "$weekday, $day. $month $year $zeit";

    }

    ?>