Let us start with grabbing some external weather data from openweathermap.org The openweathermap.org service has free and paid plans for their weather APIs to obtain weather data in realtime for any city on earth. They
Let us start with grabbing some external weather data from openweathermap.org
The openweathermap.org service has free and paid plans for their weather APIs to obtain weather data in realtime for any city on earth. They also have weather forecast data for the upcoming 5 days in a 3 hour interval. These values are already available in their free plan and this is what I use here to soup up my own weather site with my own temperature displays.
Start by creating an account at https://home.openweathermap.org/
After you are registered, you will already have free access to the 2.5 version of the openweathermap API which already makes the above described weather data available. Head over to their menu “API keys” and grab your own API key here, which we will use later in our code for the weather.php site:
https://home.openweathermap.org/api_keys
Once you have copied your own personal API key, we can create a script that gathers all the information and stores it into our sensor_data database that we created for the climate control system – module one.
Head over to your web server document directory and open a file weather.sh
nano weather.sh
#!/bin/bash
# OpenWeatherMap API-Key
api_key=”yourkeyhere”
# Stadt und Land (z.B., “Munich,DE”)
city=”Munich,DE”
# Datenbankverbindung
db_host=”192.168.x.y”
db_user=”yourdbuserhere”
db_password=”yourdbpasshere”
db_name=”sensor_data”
# SQL-Abfrage zur Erstellung der Tabelle (falls noch nicht vorhanden)
create_table_sql=”CREATE TABLE IF NOT EXISTS openweathermap (
id INT AUTO_INCREMENT PRIMARY KEY,
city VARCHAR(255),
temperature FLOAT,
min_temperature FLOAT,
max_temperature FLOAT,
feels_like FLOAT,
main_weather VARCHAR(255),
description VARCHAR(255),
visibility INT,
clouds INT,
sunrise TIME,
sunset TIME,
wind_speed FLOAT,
wind_deg INT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);”
# Führe die SQL-Abfrage zur Erstellung der Tabelle aus
mysql -h “$db_host” -u “$db_user” -p”$db_password” -e “$create_table_sql” “$db_name”
# API-Anfrage an OpenWeatherMap
api_url=”http://api.openweathermap.org/data/2.5/weather?q=$city&appid=$api_key”
api_response=$(curl -s “$api_url”)
# Daten aus der API-Antwort extrahieren (angepasst an JSON-Format)
temperature=$(echo “$api_response” | jq -r ‘.main.temp – 273.15’)
min_temperature=$(echo “$api_response” | jq -r ‘.main.temp_min – 273.15’)
max_temperature=$(echo “$api_response” | jq -r ‘.main.temp_max – 273.15’)
feels_like=$(echo “$api_response” | jq -r ‘.main.feels_like – 273.15’)
main_weather=$(echo “$api_response” | jq -r ‘.weather[0].main’)
description=$(echo “$api_response” | jq -r ‘.weather[0].description’)
visibility=$(echo “$api_response” | jq -r ‘.visibility’)
clouds=$(echo “$api_response” | jq -r ‘.clouds.all’)
sunrise=$(echo “$api_response” | jq -r ‘.sys.sunrise | strftime(“%H:%M:%S”)’)
sunset=$(echo “$api_response” | jq -r ‘.sys.sunset | strftime(“%H:%M:%S”)’)
wind_speed=$(echo “$api_response” | jq -r ‘.wind.speed’)
wind_deg=$(echo “$api_response” | jq -r ‘.wind.deg’)
# SQL-Abfrage zur Einfügung der Daten in die Datenbanktabelle
insert_sql=”INSERT INTO openweathermap (city, temperature, min_temperature, max_temperature, feels_like, main_weather, description, visibility, clouds, sunrise, sunset, wind_speed, wind_deg) VALUES (‘$city’, $temperature, $min_temperat>
# Führe die SQL-Abfrage zur Einfügung der Daten aus
mysql -h “$db_host” -u “$db_user” -p”$db_password” -e “$insert_sql” “$db_name”
Confirgure your own City and state, MySQL database settings and your own API key here. Save and exit the file.
Create another one for the forecast data:
nano forecast.sh
#!/bin/bash
# OpenWeatherMap API-Key
api_key=”yourapikeyhere”
# Stadt und Land (z.B., “Munich,DE”)
city=”Munich,DE”
# Datenbankverbindung
db_host=”192.168.x.y”
db_user=”yourdbuser”
db_password=”yourdbpass”
db_name=”sensor_data”
# SQL-Abfrage zur Erstellung der Tabelle (falls noch nicht vorhanden)
create_table_sql=”CREATE TABLE IF NOT EXISTS forecast (
id INT AUTO_INCREMENT PRIMARY KEY,
city VARCHAR(255),
forecast_data JSON,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);”
# Führe die SQL-Abfrage zur Erstellung der Tabelle aus
mysql -h “$db_host” -u “$db_user” -p”$db_password” -e “$create_table_sql” “$db_name”
# API-Anfrage an OpenWeatherMap Forecast-API
api_url=”http://api.openweathermap.org/data/2.5/forecast?q=$city&appid=$api_key”
api_response=$(curl -s “$api_url”)
# SQL-Abfrage zur Einfügung der API-Daten in die Datenbanktabelle
insert_sql=”INSERT INTO forecast (city, forecast_data) VALUES (‘$city’, ‘$api_response’);”
# Führe die SQL-Abfrage zur Einfügung der Daten aus
mysql -h “$db_host” -u “$db_user” -p”$db_password” -e “$insert_sql” “$db_name”
Confirgure your own City and state, MySQL database settings and your own API key here. Save and exit the file.
And a third script for the “whole day” accumulation.
nano wholeday.sh
#!/bin/bash # API-Schlüssel und Anfrageparameter api_key=”yourapikey” stadt=”Munich” land=”DE” # Datenbank-Parameter db_host=”192.168.x.y” db_name=”sensor_data” db_user=”yourdbuser” db_password=”yourdbpass” # Aktuelles Datum und Zeitstempel timestamp=$(date +’%Y-%m-%d %H:%M:%S’) # API-Anfrage für die tägliche Vorhersage und JSON-Antwort in der Datei “forecast.json” speichern curl -s “https://api.openweathermap.org/data/2.5/forecast?q=${stadt},${land}&appid=${api_key}” > forecast.json # Überprüfen, ob die Anfrage erfolgreich war if [ $? -eq 0 ]; then # Temperatur von Kelvin in Celsius umrechnen kelvin_temp=$(jq -r ‘.list[0].main.temp’ forecast.json) celsius_temp=$(echo “$kelvin_temp – 273.15” | bc) # Wetterbeschreibung extrahieren wetter=$(jq -r ‘.list[0].weather[0].description’ forecast.json) # Zusammenfassung in die Datenbank einfügen und Datum/Zeitstempel hinzufügen mysql -h “$db_host” -u “$db_user” -p”$db_password” “$db_name” <Now we use a cronjob for all three scripts and gather the data from openweathermap.org every 15 minutes.
crontab -e
And add the following three lines to it:
*/15 * * * * /home/axel/scripts/weather.sh > /dev/null
*/15 * * * * /home/axel/scripts/forecast.sh > /dev/null
*/15 * * * * /home/axel/scripts/wholeday.sh > /dev/null
Now we need a php page to display
Start by opening a file weather.php
nano weather.php
and copy/paste the following code into it:
Local Weather Sensors and Model Forecast
connect_error) { die(“Verbindung zur Datenbank fehlgeschlagen: ” . $conn->connect_error); } // SQL-Abfrage, um lokale Daten aus der sensor_data-Tabelle abzurufen $local_data_sql = “SELECT Innentemperatur, Aussentemperatur, AirQuality, AirQualityScale, Luftdruck, Feuchtigkeit, valvestate, date, time FROM sensor_data ORDER BY date DESC, time DESC LIMIT 1”; $local_data_result = $conn->query($local_data_sql); if ($local_data_result->num_rows > 0) { $row = $local_data_result->fetch_assoc(); $temperatur = $row[“Innentemperatur”]; $outtemperatur = $row[“Aussentemperatur”]; $luftdruck = $row[“Luftdruck”]; $luftfeuchte = $row[“Feuchtigkeit”]; $rdate = $row[“date”]; $rtime = $row[“time”]; $airqualityscale = $row[“AirQualityScale”]; $valve1 = $row[“valvestate”]; } else { echo “Keine lokalen Daten in der Datenbank gefunden.”; } // SQL-Abfrage, um lokale Daten aus der sensor_data2-Tabelle abzurufen $local_data2_sql = “SELECT Innentemperatur2, Aussentemperatur2, AirQuality2, AirQualityScale2, Luftdruck2, Feuchtigkeit2, valvestate2, date2, time2 FROM sensor_data2 ORDER BY date2 DESC, time2 DESC LIMIT 1”; $local_data2_result = $conn->query($local_data2_sql); if ($local_data2_result->num_rows > 0) { $row = $local_data2_result->fetch_assoc(); $temperatur2 = $row[“Innentemperatur2”]; $outtemperatur2 = $row[“Aussentemperatur2”]; $luftdruck2 = $row[“Luftdruck2”]; $luftfeuchte2 = $row[“Feuchtigkeit2”]; $rdate2 = $row[“date2”]; $rtime2 = $row[“time2”]; $airqualityscale2 = $row[“AirQualityScale2”]; $valve2 = $row[“valvestate2”]; } else { echo “Keine lokalen Daten in der Datenbank gefunden.”; } // SQL-Abfrage, um lokale Daten aus der sensor_data2-Tabelle abzurufen $local_data3_sql = “SELECT Innentemperatur3, Aussentemperatur3, AirQuality3, AirQualityScale3, Luftdruck3, Feuchtigkeit3, valvestate3, date3, time3 FROM sensor_data3 ORDER BY date3 DESC, time3 DESC LIMIT 1”; $local_data3_result = $conn->query($local_data3_sql); if ($local_data3_result->num_rows > 0) { $row = $local_data3_result->fetch_assoc(); $temperatur3 = $row[“Innentemperatur3”]; $outtemperatur3 = $row[“Aussentemperatur3”]; $luftdruck3 = $row[“Luftdruck3”]; $luftfeuchte3 = $row[“Feuchtigkeit3”]; $rdate3 = $row[“date3”]; $rtime3 = $row[“time3”]; $airqualityscale3 = $row[“AirQualityScale3”]; $valve3 = $row[“valvestate3”]; } else { echo “Keine lokalen Daten in der Datenbank gefunden.”; } // SQL-Abfrage, um lokale Daten aus der sensor_data2-Tabelle abzurufen $local_data4_sql = “SELECT Innentemperatur4, Aussentemperatur4, AirQuality4, AirQualityScale4, Luftdruck4, Feuchtigkeit4, valvestate4, date4, time4 FROM sensor_data4 ORDER BY date4 DESC, time4 DESC LIMIT 1”; $local_data4_result = $conn->query($local_data4_sql); if ($local_data4_result->num_rows > 0) { $row = $local_data4_result->fetch_assoc(); $temperatur4 = $row[“Innentemperatur4”]; $outtemperatur4 = $row[“Aussentemperatur4”]; $luftdruck4 = $row[“Luftdruck4”]; $luftfeuchte4 = $row[“Feuchtigkeit4”]; $rdate4 = $row[“date4”]; $rtime4 = $row[“time4”]; $airqualityscale4 = $row[“AirQualityScale4”]; $valve4 = $row[“valvestate4”]; } else { echo “Keine lokalen Daten in der Datenbank gefunden.”; } // SQL-Abfrage, um Daten aus der openweathermap-Tabelle abzurufen $openweathermap_sql = “SELECT temperature, feels_like, main_weather, description, visibility, clouds, sunrise, sunset, wind_speed, wind_deg FROM openweathermap ORDER BY timestamp DESC LIMIT 1”; $openweathermap_result = $conn->query($openweathermap_sql); if ($openweathermap_result->num_rows > 0) { $row = $openweathermap_result->fetch_assoc(); $temperature_celsius = $row[“temperature”]; $feels_like = $row[“feels_like”]; $main_weather = $row[“main_weather”]; $description = $row[“description”]; $visibility = $row[“visibility”]; $clouds = $row[“clouds”]; $sunrise = $row[“sunrise”]; $sunset = $row[“sunset”]; $wind_speed = $row[“wind_speed”]; $wind_deg = $row[“wind_deg”]; } else { echo “Keine OpenWeatherMap-Daten in der Datenbank gefunden.”; } // SQL-Abfrage, um Daten aus der forecast-Tabelle abzurufen $forecast_sql = “SELECT forecast_data FROM forecast ORDER BY timestamp DESC LIMIT 1”; $forecast_result = $conn->query($forecast_sql); if ($forecast_result->num_rows > 0) { $row = $forecast_result->fetch_assoc(); $forecast_data = json_decode($row[“forecast_data”]); } else { echo “Keine Wettervorhersage-Daten in der Datenbank gefunden.”; } // Verbindung zur Datenbank schließen $conn->close(); ?>Current Weather in Munich, DE
= $colorRange2[0] && $temperature_celsius < $colorRange2[1]) { return $colorRange2[2]; } } return '#000'; // Standardfarbe (Schwarz) für Werte außerhalb des Schemas } // Definiere ein Assoziatives Array, das die Wetter-Icons den Wetterbedingungen zuordnet $weathernow_icons = [ "clear sky" => “day_clear.png”, “few clouds” => “day_partial_cloud.png”, “scattered clouds” => “day_partial_cloud.png”, “broken clouds” => “broken_cloud.png”, “overcast clouds” => “angry_clouds.png”, “light rain” => “day_rain.png”, “moderate rain” => “rain.png”, “heavy intensity rain” => “moderate_rain.png”, “very heavy rain” => “heavy_rain.png”, “extreme rain” => “very_heavy_rain.png”, “freezing rain” => “sleet.png”, “light snow” => “snow.png”, “snow” => “snow.png”, “heavy snow” => “snow.png”, “sleet” => “sleet.png”, “shower sleet” => “sleet.png”, “light rain and snow” => “day_snow.png”, “rain and snow” => “day_snow.png”, “light shower snow” => “snow.png”, “shower snow” => “snow.png”, “heavy shower snow” => “snow.png”, “thunderstorm” => “thunder.png”, “mist” => “mist.png”, “fog” => “fog.png”, “light fog” => “fog.png”, “smoke” => “fog.png”, “haze” => “fog.png”, “sand/dust whirls” => “fog.png”, “volcanic ash” => “fog.png”, “squalls” => “fog.png”, “tornado” => “tornado.png”, “light rain and snow” => “day_snow.png”, “light shower sleet” => “sleet.png”, “light drizzle” => “day_rain.png”, “light intensity drizzle” => “day_rain.png”, “light intensity drizzle rain” => “day_rain.png”, “light shower rain” => “rain.png”, “light intensity shower rain” => “rain.png”, “heavy intensity shower rain” => “rain.png”, “ragged shower rain” => “rain.png”, “light intensity shower rain” => “rain.png”, “shower rain” => “rain.png”, “thunderstorm with light rain” => “day_rain_thunder.png”, “thunderstorm with rain” => “rain_thunder.png”, “thunderstorm with heavy rain” => “rain_thunder.png”, “thunderstorm with light drizzle” => “rain_thunder.png”, “thunderstorm with drizzle” => “rain_thunder.png”, “thunderstorm with heavy drizzle” => “rain_thunder.png”, “default” => “default.png” // Standard-Icon, wenn keine Übereinstimmung gefunden wird ]; $icon_filename = isset($weathernow_icons[$description]) ? $weathernow_icons[$description] : ‘default.png’; echo “Temperature: $temperature_celsius °C
“; ?>Feels like: °C
Weather: ()
Visibility: m
Clouds: %
Sunrise:
Sunset:
Wind speed: m/s
Direction: °
Upcoming weather next 3 hours
connect_error) { die(“Verbindung zur Datenbank fehlgeschlagen: ” . $conn->connect_error); } // Ersetzen Sie das Abfragedatum “CURDATE()” durch das gewünschte Datum, wenn die Daten nicht korrekt abgerufen werden. $desired_date = date(“Y-m-d”); // Heutiges Datum // $today_forecast_sql = “SELECT temperature, weather, date FROM wholeday WHERE date = ‘$desired_date'”; // $today_forecast_sql = “SELECT temperature, weather, date FROM wholeday ORDER BY date DESC LIMIT 1”; $today_forecast_sql = “SELECT temperature, weather, date FROM wholeday ORDER BY date DESC LIMIT 1”; $today_forecast_result = $conn->query($today_forecast_sql); if ($today_forecast_result->num_rows > 0) { $row = $today_forecast_result->fetch_assoc(); $temperature_today = $row[“temperature”]; $weather_today = $row[“weather”]; $date_today = date_format(date_create($row[“date”]), “Y-m-d”); // Definieren Sie die Icons entsprechend den Wetterbedingungen $weather_icons = [ “clear sky” => “day_clear.png”, “few clouds” => “day_partial_cloud.png”, “scattered clouds” => “day_partial_cloud.png”, “broken clouds” => “broken_cloud.png”, “overcast clouds” => “angry_clouds.png”, “light rain” => “day_rain.png”, “moderate rain” => “rain.png”, “heavy intensity rain” => “moderate_rain.png”, “very heavy rain” => “heavy_rain.png”, “extreme rain” => “very_heavy_rain.png”, “freezing rain” => “sleet.png”, “light snow” => “snow.png”, “snow” => “snow.png”, “heavy snow” => “snow.png”, “sleet” => “sleet.png”, “shower sleet” => “sleet.png”, “light rain and snow” => “day_snow.png”, “rain and snow” => “day_snow.png”, “light shower snow” => “snow.png”, “shower snow” => “snow.png”, “heavy shower snow” => “snow.png”, “thunderstorm” => “thunder.png”, “mist” => “mist.png”, “fog” => “fog.png”, “light fog” => “fog.png”, “smoke” => “fog.png”, “haze” => “fog.png”, “sand/dust whirls” => “fog.png”, “volcanic ash” => “fog.png”, “squalls” => “fog.png”, “tornado” => “tornado.png”, “light rain and snow” => “day_snow.png”, “light shower sleet” => “sleet.png”, “light drizzle” => “day_rain.png”, “light intensity drizzle” => “day_rain.png”, “light intensity drizzle rain” => “day_rain.png”, “light shower rain” => “rain.png”, “light intensity shower rain” => “rain.png”, “heavy intensity shower rain” => “rain.png”, “ragged shower rain” => “rain.png”, “light intensity shower rain” => “rain.png”, “shower rain” => “rain.png”, “thunderstorm with light rain” => “day_rain_thunder.png”, “thunderstorm with rain” => “rain_thunder.png”, “thunderstorm with heavy rain” => “rain_thunder.png”, “thunderstorm with light drizzle” => “rain_thunder.png”, “thunderstorm with drizzle” => “rain_thunder.png”, “thunderstorm with heavy drizzle” => “rain_thunder.png”, “default” => “default.png” ]; $icon_filename_today = isset($weather_icons[$weather_today]) ? $weather_icons[$weather_today] : ‘default.png’; // Geben Sie das Icon, die Temperatur und das Datum aus echo “Temperature: $temperature_today °C
“; echo “Date: $date_today
“; } else { echo “Keine Wettervorhersage-Daten für heute gefunden.”; } // Schließen Sie die Verbindung zur Datenbank $conn->close(); ?>Live Webcam Stream Austrian Alps
Weather forecast for Munich, DE
“day_clear.png”, “few clouds” => “day_partial_cloud.png”, “scattered clouds” => “day_partial_cloud.png”, “broken clouds” => “broken_cloud.png”, “overcast clouds” => “angry_clouds.png”, “light rain” => “day_rain.png”, “moderate rain” => “rain.png”, “heavy intensity rain” => “moderate_rain.png”, “very heavy rain” => “heavy_rain.png”, “extreme rain” => “very_heavy_rain.png”, “freezing rain” => “sleet.png”, “light snow” => “snow.png”, “snow” => “snow.png”, “heavy snow” => “snow.png”, “sleet” => “sleet.png”, “shower sleet” => “sleet.png”, “light rain and snow” => “day_snow.png”, “rain and snow” => “day_snow.png”, “light shower snow” => “snow.png”, “shower snow” => “snow.png”, “heavy shower snow” => “snow.png”, “thunderstorm” => “thunder.png”, “mist” => “mist.png”, “fog” => “fog.png”, “light fog” => “fog.png”, “smoke” => “fog.png”, “haze” => “fog.png”, “sand/dust whirls” => “fog.png”, “volcanic ash” => “fog.png”, “squalls” => “fog.png”, “tornado” => “tornado.png”, “light rain and snow” => “day_snow.png”, “light shower sleet” => “sleet.png”, “light drizzle” => “day_rain.png”, “light intensity drizzle” => “day_rain.png”, “light intensity drizzle rain” => “day_rain.png”, “light shower rain” => “rain.png”, “light intensity shower rain” => “rain.png”, “heavy intensity shower rain” => “rain.png”, “ragged shower rain” => “rain.png”, “light intensity shower rain” => “rain.png”, “shower rain” => “rain.png”, “thunderstorm with light rain” => “day_rain_thunder.png”, “thunderstorm with rain” => “rain_thunder.png”, “thunderstorm with heavy rain” => “rain_thunder.png”, “thunderstorm with light drizzle” => “rain_thunder.png”, “thunderstorm with drizzle” => “rain_thunder.png”, “thunderstorm with heavy drizzle” => “rain_thunder.png”, “default” => “default.png” // Standard-Icon, wenn keine Übereinstimmung gefunden wird ]; // Farbschema für die Temperatur definieren $colorScheme3 = array( array(-100, -15, ‘#00008b’), // Dunkelblau array(-15, -5, ‘#0000ff’), // Blau array(-5, 0, ‘#5da8d6’), // Hellblau array(0, 10, ‘#70b0d6’), // Helles Pastellblau array(10, 15, ‘#efc700’), // Hellgelb array(15, 20, ‘#80de90’), // Hellgrün array(20, 25, ‘#ef9500’), // Hellorange array(25, 30, ‘#ef7f50’), // Orange array(30, 35, ‘#ef5340’), // Hellrot array(35, 40, ‘#ef0000’), // Rot array(40, 100, ‘#8b0000’) // Dunkelrot ); // Funktion zum Finden der passenden Farbe function findTemperatureColor3($forecast_temp_celsius, $colorScheme3) { foreach ($colorScheme3 as $colorRange3) { if ($forecast_temp_celsius >= $colorRange3[0] && $forecast_temp_celsius < $colorRange3[1]) { return $colorRange3[2]; } } return '#000'; // Standardfarbe (Schwarz) für Werte außerhalb des Schemas } foreach ($forecast_data->list as $forecast) { $forecast_date = date(“Y-m-d”, $forecast->dt); if ($forecast_date !== $current_date) { if ($current_date !== null) { echo “$forecast_day_of_week, $forecast_date
“; $current_date = $forecast_date; } $forecast_time = date(“H:i:s”, $forecast->dt); $forecast_weather_description = $forecast->weather[0]->description; // Ermittle das passende Wetter-Icon basierend auf der Beschreibung $icon_filename = isset($weather_icons[$forecast_weather_description]) ? $weather_icons[$forecast_weather_description] : ‘default.png’; $forecast_feels_like = round(($forecast->main->feels_like – 273.15), 2); // Runde auf 2 Dezimalstellen $forecast_temp_celsius = round(($forecast->main->temp_max – 273.15), 2); // Runde auf 2 Dezimalstellen $forecast_temp_min_celsius = round(($forecast->main->temp_min – 273.15), 2); // Runde auf 2 Dezimalstellen $forecast_description = $forecast->weather[0]->description; $forecast_rain = $forecast->rain->{“3h”} ?? 0; // Niederschlag in den letzten 3 Stunden (standardmäßig auf 0 setzen) $forecast_wind_speed = $forecast->wind->speed; $forecast_wind_deg = $forecast->wind->deg; $temperature_color = findTemperatureColor3($forecast_temp_celsius, $colorScheme3); // Finden Sie die Farbe basierend auf der Temperatur echo “$forecast_time:
Max: $fo> } echo “
Again, use your own data and database credentials here in this file.
We are still not done. We also need some graphs here to display our own sensors data in a pretty way. Open another file to generate the graphs from our data from our inside temperature
nano temperature_graph.php
And copy the following lines into it
connect_error) { die(“Verbindung zur Datenbank fehlgeschlagen: ” . $conn->connect_error); } // Datum für den aktuellen Tag $currentDate = date(“Y-m-d”); // SQL-Abfrage, um alle relevanten Daten für den aktuellen Tag abzurufen $sql = “SELECT time, Innentemperatur FROM sensor_data WHERE date = ‘$currentDate’ ORDER BY time”; $result = $conn->query($sql); if ($result->num_rows > 0) { // Daten sammeln while ($row = $result->fetch_assoc()) { $data[] = array( ‘time’ => date(“H:i”, strtotime($row[‘time’])), ‘temperature’ => floatval($row[‘Innentemperatur’]) ); } // GD-Bild erstellen $width = 900; // Breite des Graphen $height = 240; // Höhe des Graphen $img = imagecreatetruecolor($width, $height); // Hintergrundfarbe festlegen $background = imagecolorallocate($img, 255, 255, 255); imagefilledrectangle($img, 0, 0, $width, $height, $background); // Linienfarben $lineColor = imagecolorallocate($img, 255, 0, 0); $axisColor = imagecolorallocate($img, 0, 0, 0); // Schwarze Achsen // Achsen zeichnen imageline($img, 50, 50, 50, $height – 50, $axisColor); // Vertikale Achse imageline($img, 50, $height – 50, $width – 50, $height – 50, $axisColor); // Horizontale Achse // Basisfrequenz für die Beschriftung (zum Beispiel alle 3 Stunden) $baseLabelFrequency = 28; // Initialisiere die LabelFrequency mit der Basisfrequenz $xLabelFrequency = $baseLabelFrequency; // Beschriftung der x-Achse (Zeit) $dayStart = strtotime($currentDate . ‘ 00:00:00’); $dayEnd = strtotime($currentDate . ‘ 23:59:59’); $xLabelFrequency = 2; for ($timestamp = $dayStart; $timestamp <= $dayEnd; $timestamp += $xLabelFrequency * 3600) { $x = 50 + ($timestamp - $dayStart) / (24 * 60 * 60) * ($width - 100); // Anpassung auf 24 Stunden imagestring($img, 3, $x, $height - 30, date("H:i", $timestamp), $axisColor); } /* $numDataPoints = count($data); for ($i = 0; $i < $numDataPoints; $i += $xLabelFrequency) { $timestamp = strtotime($currentDate . ' ' . $data[$i]['time']); // Berechne die Stunde aus dem Zeitstempel $hour = date('G', $timestamp); // Überprüfe die Uhrzeit und passe die LabelFrequency an if ($hour % $baseLabelFrequency === 0) { $xLabelFrequency = $baseLabelFrequency; } else { $xLabelFrequency = $baseLabelFrequency - ($hour % $baseLabelFrequency); } $x = 50 + ($timestamp - strtotime($currentDate)) / (24 * 60 * 60) * ($width - 100); // Anpassung auf 24 Stunden imagestring($img, 3, $x, $height - 30, date("H:i", $timestamp), $axisColor); } */ // Beschriftung der y-Achse (Temperatur) für den aktuellen Tag $maxTemperature = max(array_column($data, 'temperature')); $minTemperature = min(array_column($data, 'temperature')); $temperatureRange = $maxTemperature - $minTemperature; $yLabelFrequency = $temperatureRange / 10; // 10 Temperaturwerte auf der y-Achse for ($i = 0; $i <= 10; $i++) { $y = $height - 50 - ($i * ($height - 100) / 10); $label = number_format($minTemperature + $i * $yLabelFrequency, 1); imagestring($img, 3, 20, $y + 5, $label, $axisColor); } // Temperaturwerte zeichnen für den aktuellen Tag $values = array(); foreach ($data as $entry) { if (isset($entry['time'])) { $timestamp = strtotime($currentDate . ' ' . $entry['time']); // Umrechnung der Zeit in die x-Position im 24-Stunden-Graphen $x = 50 + ($timestamp - strtotime($currentDate)) / (24 * 60 * 60) * ($width - 100); // Korrektur, um sicherzustellen, dass x im erwarteten Bereich liegt $x = max(50, min($width - 50, $x)); $y = $height - 50 - (($entry['temperature'] - $minTemperature) / $temperatureRange) * ($height - 100); $values[] = $x; $values[] = $y; // Debug-Ausgabe # echo "time: {$entry['time']}, x: $x, y: $y“; } } // Zeichnen der Linie (offen) für den aktuellen Tag imagesetthickness($img, 2); if (count($values) >= 4 && count($values) % 2 === 0) { imageopenpolygon($img, $values, count($values) / 2, $lineColor); } // Vortag-Daten abrufen $yesterday = date(“Y-m-d”, strtotime($currentDate . ” -1 day”)); $sqlYesterday = “SELECT time, Innentemperatur FROM sensor_data WHERE date = ‘$yesterday’ ORDER BY time”; $resultYesterday = $conn->query($sqlYesterday); if ($resultYesterday->num_rows > 0) { // Daten für den Vortag sammeln $dataYesterday = array(); while ($rowYesterday = $resultYesterday->fetch_assoc()) { $dataYesterday[] = array( ‘time’ => strtotime($yesterday . ‘ ‘ . $rowYesterday[‘time’]), ‘temperature’ => floatval($rowYesterday[‘Innentemperatur’]) ); } // Beschriftung der y-Achse (Temperatur) für den Vortag $maxTemperatureYesterday = max(array_column($dataYesterday, ‘temperature’)); $minTemperatureYesterday = min(array_column($dataYesterday, ‘temperature’)); $temperatureRangeYesterday = $maxTemperatureYesterday – $minTemperatureYesterday; $yLabelFrequencyYesterday = $temperatureRangeYesterday / 10; // 10 Temperaturwerte auf der y-Achse for ($i = 0; $i <= 10; $i++) { $y = $height - 50 - ($i * ($height - 100) / 10); $label = number_format($minTemperatureYesterday + $i * $yLabelFrequencyYesterday, 1); imagestring($img, 3, $width - 40, $y + 5, $label, $axisColor); } // Temperaturwerte zeichnen für den Vortag (gestern) $valuesYesterday = array(); for ($i = 0; $i < count($dataYesterday) - 1; $i++) { $x1 = 50 + (($dataYesterday[$i]['time'] - $dataYesterday[0]['time']) / (24 * 60 * 60)) * ($width - 100); $y1 = $height - 50 - (($dataYesterday[$i]['temperature'] - $minTemperatureYesterday) / $temperatureRangeYesterday) * ($height - 100); $x2 = 50 + (($dataYesterday[$i + 1]['time'] - $dataYesterday[0]['time']) / (24 * 60 * 60)) * ($width - 100); $y2 = $height - 50 - (($dataYesterday[$i + 1]['temperature'] - $minTemperatureYesterday) / $temperatureRangeYesterday) * ($height - 100); if ($x2 <= $width - 50) { // Zeichne nur, wenn x2 im Graphenbereich liegt $valuesYesterday[] = $x1; $valuesYesterday[] = $y1; $valuesYesterday[] = $x2; $valuesYesterday[] = $y2; } } // Zeichnen der Linie für den Vortag (gestern) $yesterdayColor = imagecolorallocate($img, 173, 216, 230); // Hellblaue Farbe imagesetthickness($img, 1); imageopenpolygon($img, $valuesYesterday, count($valuesYesterday) / 2, $yesterdayColor); } // Bild ausgeben header("Content-Type: image/png"); imagepng($img); // Bildspeicher freigeben imagedestroy($img); } else { echo "Keine Daten für den aktuellen Tag gefunden."; } // Verbindung zur Datenbank schließen $conn->close(); ?>
Use your own configuration data here and open another file for the outside temperature graph
nano outtemperature_graph.php
connect_error) {
die(“Verbindung zur Datenbank fehlgeschlagen: ” . $conn->connect_error);
}
// Datum für den aktuellen Tag
$currentDate = date(“Y-m-d”);
// SQL-Abfrage, um alle relevanten Daten für den aktuellen Tag abzurufen
$sql = “SELECT time, Aussentemperatur FROM sensor_data WHERE date = ‘$currentDate’ ORDER BY time”;
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// Daten sammeln
while ($row = $result->fetch_assoc()) {
$data[] = array(
‘time’ => date(“H:i”, strtotime($row[‘time’])),
‘temperature’ => floatval($row[‘Aussentemperatur’])
);
}
// GD-Bild erstellen
$width = 900; // Breite des Graphen
$height = 240; // Höhe des Graphen
$img = imagecreatetruecolor($width, $height);
// Hintergrundfarbe festlegen
$background = imagecolorallocate($img, 235, 255, 255);
imagefilledrectangle($img, 0, 0, $width, $height, $background);
// Linienfarben
$lineColor = imagecolorallocate($img, 255, 0, 0);
$axisColor = imagecolorallocate($img, 0, 0, 0); // Schwarze Achsen
// Achsen zeichnen
imageline($img, 50, 50, 50, $height – 50, $axisColor); // Vertikale Achse
imageline($img, 50, $height – 50, $width – 50, $height – 50, $axisColor); // Horizontale Achse
// Basisfrequenz für die Beschriftung (zum Beispiel alle 3 Stunden)
$baseLabelFrequency = 28;
// Initialisiere die LabelFrequency mit der Basisfrequenz
$xLabelFrequency = $baseLabelFrequency;
// Beschriftung der x-Achse (Zeit)
$dayStart = strtotime($currentDate . ‘ 00:00:00’);
$dayEnd = strtotime($currentDate . ‘ 23:59:59’);
$xLabelFrequency = 2;
for ($timestamp = $dayStart; $timestamp <= $dayEnd; $timestamp += $xLabelFrequency * 3600) {
$x = 50 + ($timestamp - $dayStart) / (24 * 60 * 60) * ($width - 100); // Anpassung auf 24 Stunden
imagestring($img, 3, $x, $height - 30, date("H:i", $timestamp), $axisColor);
}
/*
$numDataPoints = count($data);
for ($i = 0; $i < $numDataPoints; $i += $xLabelFrequency) {
$timestamp = strtotime($currentDate . ' ' . $data[$i]['time']);
// Berechne die Stunde aus dem Zeitstempel
$hour = date('G', $timestamp);
// Überprüfe die Uhrzeit und passe die LabelFrequency an
if ($hour % $baseLabelFrequency === 0) {
$xLabelFrequency = $baseLabelFrequency;
} else {
$xLabelFrequency = $baseLabelFrequency - ($hour % $baseLabelFrequency);
}
$x = 50 + ($timestamp - strtotime($currentDate)) / (24 * 60 * 60) * ($width - 100); // Anpassung auf 24 Stunden
imagestring($img, 3, $x, $height - 30, date("H:i", $timestamp), $axisColor);
}
*/
// Beschriftung der y-Achse (Temperatur) für den aktuellen Tag
$maxTemperature = max(array_column($data, 'temperature'));
$minTemperature = min(array_column($data, 'temperature'));
$temperatureRange = $maxTemperature - $minTemperature;
$yLabelFrequency = $temperatureRange / 10; // 10 Temperaturwerte auf der y-Achse
for ($i = 0; $i <= 10; $i++) {
$y = $height - 50 - ($i * ($height - 100) / 10);
$label = number_format($minTemperature + $i * $yLabelFrequency, 1);
imagestring($img, 3, 20, $y + 5, $label, $axisColor);
}
// Temperaturwerte zeichnen für den aktuellen Tag
$values = array();
foreach ($data as $entry) {
if (isset($entry['time'])) {
$timestamp = strtotime($currentDate . ' ' . $entry['time']);
// Umrechnung der Zeit in die x-Position im 24-Stunden-Graphen
$x = 50 + ($timestamp - strtotime($currentDate)) / (24 * 60 * 60) * ($width - 100);
// Korrektur, um sicherzustellen, dass x im erwarteten Bereich liegt
$x = max(50, min($width - 50, $x));
$y = $height - 50 - (($entry['temperature'] - $minTemperature) / $temperatureRange) * ($height - 100);
$values[] = $x;
$values[] = $y;
// Debug-Ausgabe
# echo "time: {$entry['time']}, x: $x, y: $y“; } } // Zeichnen der Linie (offen) für den aktuellen Tag imagesetthickness($img, 2); if (count($values) >= 4 && count($values) % 2 === 0) { imageopenpolygon($img, $values, count($values) / 2, $lineColor); } // Vortag-Daten abrufen $yesterday = date(“Y-m-d”, strtotime($currentDate . ” -1 day”)); $sqlYesterday = “SELECT time, Aussentemperatur FROM sensor_data WHERE date = ‘$yesterday’ ORDER BY time”; $resultYesterday = $conn->query($sqlYesterday); if ($resultYesterday->num_rows > 0) { // Daten für den Vortag sammeln $dataYesterday = array(); while ($rowYesterday = $resultYesterday->fetch_assoc()) { $dataYesterday[] = array( ‘time’ => strtotime($yesterday . ‘ ‘ . $rowYesterday[‘time’]), ‘temperature’ => floatval($rowYesterday[‘Aussentemperatur’]) ); } // Beschriftung der y-Achse (Temperatur) für den Vortag $maxTemperatureYesterday = max(array_column($dataYesterday, ‘temperature’)); $minTemperatureYesterday = min(array_column($dataYesterday, ‘temperature’)); $temperatureRangeYesterday = $maxTemperatureYesterday – $minTemperatureYesterday; $yLabelFrequencyYesterday = $temperatureRangeYesterday / 10; // 10 Temperaturwerte auf der y-Achse for ($i = 0; $i <= 10; $i++) { $y = $height - 50 - ($i * ($height - 100) / 10); $label = number_format($minTemperatureYesterday + $i * $yLabelFrequencyYesterday, 1); imagestring($img, 3, $width - 40, $y + 5, $label, $axisColor); } // Temperaturwerte zeichnen für den Vortag (gestern) $valuesYesterday = array(); for ($i = 0; $i < count($dataYesterday) - 1; $i++) { $x1 = 50 + (($dataYesterday[$i]['time'] - $dataYesterday[0]['time']) / (24 * 60 * 60)) * ($width - 100); $y1 = $height - 50 - (($dataYesterday[$i]['temperature'] - $minTemperatureYesterday) / $temperatureRangeYesterday) * ($height - 100); $x2 = 50 + (($dataYesterday[$i + 1]['time'] - $dataYesterday[0]['time']) / (24 * 60 * 60)) * ($width - 100); $y2 = $height - 50 - (($dataYesterday[$i + 1]['temperature'] - $minTemperatureYesterday) / $temperatureRangeYesterday) * ($height - 100); if ($x2 <= $width - 50) { // Zeichne nur, wenn x2 im Graphenbereich liegt $valuesYesterday[] = $x1; $valuesYesterday[] = $y1; $valuesYesterday[] = $x2; $valuesYesterday[] = $y2; } } // Zeichnen der Linie für den Vortag (gestern) $yesterdayColor = imagecolorallocate($img, 173, 216, 230); // Hellblaue Farbe imagesetthickness($img, 1); imageopenpolygon($img, $valuesYesterday, count($valuesYesterday) / 2, $yesterdayColor); } // Bild ausgeben header("Content-Type: image/png"); imagepng($img); // Bildspeicher freigeben imagedestroy($img); } else { echo "Keine Daten für den aktuellen Tag gefunden."; } // Verbindung zur Datenbank schließen $conn->close(); ?>
Again, as always, use your own data here and open another graph painting php file for the humidity
nano humidity_graph.php
And copy the follwing code into it
connect_error) { die(“Verbindung zur Datenbank fehlgeschlagen: ” . $conn->connect_error); } // Datum für den aktuellen Tag $currentDate = date(“Y-m-d”); // SQL-Abfrage, um alle relevanten Daten für den aktuellen Tag abzurufen $sql = “SELECT time, Feuchtigkeit FROM sensor_data WHERE date = ‘$currentDate’ ORDER BY time”; $result = $conn->query($sql); if ($result->num_rows > 0) { // Daten sammeln while ($row = $result->fetch_assoc()) { $data[] = array( ‘time’ => date(“H:i”, strtotime($row[‘time’])), ‘temperature’ => floatval($row[‘Feuchtigkeit’]) ); } // GD-Bild erstellen $width = 900; // Breite des Graphen $height = 240; // Höhe des Graphen $img = imagecreatetruecolor($width, $height); // Hintergrundfarbe festlegen $background = imagecolorallocate($img, 235, 235, 255); imagefilledrectangle($img, 0, 0, $width, $height, $background); // Linienfarben $lineColor = imagecolorallocate($img, 255, 0, 0); $axisColor = imagecolorallocate($img, 0, 0, 0); // Schwarze Achsen // Achsen zeichnen imageline($img, 50, 50, 50, $height – 50, $axisColor); // Vertikale Achse imageline($img, 50, $height – 50, $width – 50, $height – 50, $axisColor); // Horizontale Achse // Basisfrequenz für die Beschriftung (zum Beispiel alle 3 Stunden) $baseLabelFrequency = 28; // Initialisiere die LabelFrequency mit der Basisfrequenz $xLabelFrequency = $baseLabelFrequency; // Beschriftung der x-Achse (Zeit) $dayStart = strtotime($currentDate . ‘ 00:00:00’); $dayEnd = strtotime($currentDate . ‘ 23:59:59’); $xLabelFrequency = 2; for ($timestamp = $dayStart; $timestamp <= $dayEnd; $timestamp += $xLabelFrequency * 3600) { $x = 50 + ($timestamp - $dayStart) / (24 * 60 * 60) * ($width - 100); // Anpassung auf 24 Stunden imagestring($img, 3, $x, $height - 30, date("H:i", $timestamp), $axisColor); } /* $numDataPoints = count($data); for ($i = 0; $i < $numDataPoints; $i += $xLabelFrequency) { $timestamp = strtotime($currentDate . ' ' . $data[$i]['time']); // Berechne die Stunde aus dem Zeitstempel $hour = date('G', $timestamp); // Überprüfe die Uhrzeit und passe die LabelFrequency an if ($hour % $baseLabelFrequency === 0) { $xLabelFrequency = $baseLabelFrequency; } else { $xLabelFrequency = $baseLabelFrequency - ($hour % $baseLabelFrequency); } $x = 50 + ($timestamp - strtotime($currentDate)) / (24 * 60 * 60) * ($width - 100); // Anpassung auf 24 Stunden imagestring($img, 3, $x, $height - 30, date("H:i", $timestamp), $axisColor); } */ // Beschriftung der y-Achse (Temperatur) für den aktuellen Tag $maxTemperature = max(array_column($data, 'temperature')); $minTemperature = min(array_column($data, 'temperature')); $temperatureRange = $maxTemperature - $minTemperature; $yLabelFrequency = $temperatureRange / 10; // 10 Temperaturwerte auf der y-Achse for ($i = 0; $i <= 10; $i++) { $y = $height - 50 - ($i * ($height - 100) / 10); $label = number_format($minTemperature + $i * $yLabelFrequency, 1); imagestring($img, 3, 20, $y + 5, $label, $axisColor); } // Temperaturwerte zeichnen für den aktuellen Tag $values = array(); foreach ($data as $entry) { if (isset($entry['time'])) { $timestamp = strtotime($currentDate . ' ' . $entry['time']); // Umrechnung der Zeit in die x-Position im 24-Stunden-Graphen $x = 50 + ($timestamp - strtotime($currentDate)) / (24 * 60 * 60) * ($width - 100); // Korrektur, um sicherzustellen, dass x im erwarteten Bereich liegt $x = max(50, min($width - 50, $x)); $y = $height - 50 - (($entry['temperature'] - $minTemperature) / $temperatureRange) * ($height - 100); $values[] = $x; $values[] = $y; // Debug-Ausgabe # echo "time: {$entry['time']}, x: $x, y: $y“; } } // Zeichnen der Linie (offen) für den aktuellen Tag imagesetthickness($img, 2); if (count($values) >= 4 && count($values) % 2 === 0) { imageopenpolygon($img, $values, count($values) / 2, $lineColor); } // Vortag-Daten abrufen $yesterday = date(“Y-m-d”, strtotime($currentDate . ” -1 day”)); $sqlYesterday = “SELECT time, Feuchtigkeit FROM sensor_data WHERE date = ‘$yesterday’ ORDER BY time”; $resultYesterday = $conn->query($sqlYesterday); if ($resultYesterday->num_rows > 0) { // Daten für den Vortag sammeln $dataYesterday = array(); while ($rowYesterday = $resultYesterday->fetch_assoc()) { $dataYesterday[] = array( ‘time’ => strtotime($yesterday . ‘ ‘ . $rowYesterday[‘time’]), ‘temperature’ => floatval($rowYesterday[‘Feuchtigkeit’]) ); } // Beschriftung der y-Achse (Temperatur) für den Vortag $maxTemperatureYesterday = max(array_column($dataYesterday, ‘temperature’)); $minTemperatureYesterday = min(array_column($dataYesterday, ‘temperature’)); $temperatureRangeYesterday = $maxTemperatureYesterday – $minTemperatureYesterday; $yLabelFrequencyYesterday = $temperatureRangeYesterday / 10; // 10 Temperaturwerte auf der y-Achse for ($i = 0; $i <= 10; $i++) { $y = $height - 50 - ($i * ($height - 100) / 10); $label = number_format($minTemperatureYesterday + $i * $yLabelFrequencyYesterday, 1); imagestring($img, 3, $width - 40, $y + 5, $label, $axisColor); } } // Temperaturwerte zeichnen für den Vortag (gestern) $valuesYesterday = array(); for ($i = 0; $i < count($dataYesterday) - 1; $i++) { $x1 = 50 + (($dataYesterday[$i]['time'] - $dataYesterday[0]['time']) / (24 * 60 * 60)) * ($width - 100); $y1 = $height - 50 - (($dataYesterday[$i]['temperature'] - $minTemperatureYesterday) / $temperatureRangeYesterday) * ($height - 100); $x2 = 50 + (($dataYesterday[$i + 1]['time'] - $dataYesterday[0]['time']) / (24 * 60 * 60)) * ($width - 100); $y2 = $height - 50 - (($dataYesterday[$i + 1]['temperature'] - $minTemperatureYesterday) / $temperatureRangeYesterday) * ($height - 100); if ($x2 <= $width - 50) { // Zeichne nur, wenn x2 im Graphenbereich liegt $valuesYesterday[] = $x1; $valuesYesterday[] = $y1; $valuesYesterday[] = $x2; $valuesYesterday[] = $y2; } } // Zeichnen der Linie für den Vortag (gestern) $yesterdayColor = imagecolorallocate($img, 173, 216, 230); // Hellblaue Farbe imagesetthickness($img, 1); imageopenpolygon($img, $valuesYesterday, count($valuesYesterday) / 2, $yesterdayColor); } // Bild ausgeben header("Content-Type: image/png"); imagepng($img); // Bildspeicher freigeben imagedestroy($img); } else { echo "Keine Daten für den aktuellen Tag gefunden."; } // Verbindung zur Datenbank schließen $conn->close(); ?>
The needed images are self_explanatory. There are many free weather images to download from free picture sites that you can use for your weather website, or you can paint them on your own to give your site a unique design and style.
The graphs are very informative and show all kinds of data from today and yesterday. When you need more information or help in this project, feel free to reach out.