Gadget, Weather Station

Weather Station Mk-I Part II

This post was originally published on October 26, 2017 at https://sparklechicken.net/channel/jakessbc

Server Prep

First and foremost, you need a standard LAMP stack.  nginx can be substituted fro Apache if you are more comfortable with that, and I suppose that you could do this on a Windows server as well, but it would just be wrong to do so and you’re on your own.  To make it look pretty I used WordPress as a base, so that is the first thing that you should get going.  There are plenty of guides on how to install and configure it, so I won’t reproduce those steps here.

Take a random JPG and make eight copies of it naming them:

daily.jpg
dailyp.jpg
week.jpg
weekp.jpg
month.jpg
monthp.jpg
year.jpg
yearp.jpg

Upload these to your WordPress site.  These are the files that will be overwritten by your scripts to generate the graphs dynamically.

Make a copy of the JPG that you are using for the front page of the theme that you are using.  If you don’t start with a fresh copy every time that makefrontpage.py runs, then you’ll end up with black stripes instead of data on the front page.

The Python libraries that you’ll need are Pandas, PIL (Python Image Library) and matplotlib.  You can either install them with pip or your package manager, but keep in mind that when installing with pip your computer needs to compile stuff.  If you’re using something rinky-dink like a Raspberry Pi, it will take ages for the compilation to take place.  Pandas is used for the SQL stuff, PIL generates the JPG on the front page, and matplotlib is used to generate the graphs.

To set up the database run the following SQL script:


CREATE data;
USE data;
CREATE TABLE weather_data (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  created TIMESTAMP DEFAULT NOW(),
  temperature DECIMAL(6,2),
  humidity DECIMAL(6,2),
  pressure DECIMAL(6,2),
  heatindex DECIMAL(6,2)
);

Make a directory within /var/www/html called weather.  Create the following files within it, making sure to populate the SQL authentication with your own, and setting the file paths properly.

process.php:


<?php

$temperature=$_POST['temperature'];
$humidity=$_POST['humidity'];
$pressure=$_POST['pressure'];
$heatindex=$_POST['heatindex'];
$con=mysqli_connect('localhost','username','password');
$sql=("INSERT INTO weather_data(temperature,humidity,pressure,heatindex)
        VALUES('$temperature','$humidity','$pressure','$heatindex')");

if (!mysqli_query($con,$sql))

  {

  die('Error: ' . mysqli_error());

  }

echo "1 record added";
mysqli_close($con);
echo 'Done!';
?>

makefrontpage.py:


from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import MySQLdb
import pandas
deg = u'\N{DEGREE SIGN}'
conn = MySQLdb.connect(host="localhost",user="username",passwd="password",db="data")
cur = conn.cursor()
query = """
SELECT created,temperature,humidity,pressure,heatindex
FROM weather_data
ORDER BY created DESC
LIMIT 1
"""
cur.execute(query)
data = cur.fetchone()
temp = str(data[1])
humi = str(data[2])
pres = str(data[3])
heat = str(data[4])
tempf = str(((data[1]*9)/5)+32)
heatf = str(((data[4]*9)/5)+32)
dewp = str(data[1] - ((100-data[2])/5))
dewpf = str((data[1] - (((100-data[2])/5)*9)/5)+32)
img = Image.open("/var/www/html/wp-content/themes/path-to-header2.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeSans.ttf", 80)
draw.text((100,50),"Temperature:  " + temp + deg +"C/" + tempf + deg + "F",(0,0,0),font=font)
draw.text((100,150),"Humidity:  " + humi + "%",(0,0,0),font=font)
draw.text((100,250),"Pressure:  " + pres + "mBar",(0,0,0),font=font)
draw.text((100,350),"Heat Index:  " + heat + deg +"C/" + heatf + deg + "F",(0,0,0),font=font)
draw.text((100,450),"Dew Point:  " + dewp + deg + "C/" + dewpf + deg + "F",(0,0,0),font=font)
img.save('/var/www/html/wp-content/themes/path-to-header.jpg')

plot_daily.py:


import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pandas
import MySQLdb
conn = MySQLdb.connect(host="localhost", user="username", passwd="password", db="data")
query = """
SELECT created, temperature, humidity, heatindex
FROM weather_data
WHERE created >= CURDATE() - INTERVAL 1 DAY
"""
df = pandas.read_sql(query, conn, index_col=['created'])
fig, ax = plt.subplots()
df.plot(ax=ax)
fig.savefig('/var/www/html/wp-content/uploads/path-to-daily.jpg', dpi=100)
conn.close()
conn = MySQLdb.connect(host="localhost", user="username", passwd="password", db="data")
query = """
SELECT created, pressure
FROM weather_data
WHERE created >= CURDATE() - INTERVAL 1 DAY
"""
df = pandas.read_sql(query, conn, index_col=['created'])
fig, ax = plt.subplots()
df.plot(ax=ax)
fig.savefig('/var/www/html/wp-content/uploads/path-to-dailyp.jpg', dpi=100)
conn.close()

Copy plot_daily.py to:

plot_week.py
plot_month.py
plot_year.py

Edit each of those scripts replacing “INTERVAL 1 DAY” with WEEK, MONTH, and YEAR respectively.  Also remember to change the file name to week.jpg, weekp.jpg, etc.

Run “crontab -e” and add the following to it to automatically run the python scripts:


*/10 * * * * python /var/www/html/weather/makefrontpage.py
*/20 * * * * python /var/www/html/weather/plot_daily.py
0 * * * * python /var/www/html/weather/plot_week.py
10 0 * * * python /var/www/html/weather/plot_month.py
30 0 * * * python /var/www/html/weather/plot_year.py

That should do it!