My goal was to make a Pi kitchen appliance that shows me the key things that I want to see and music I want to listen to while I’m getting my morning coffee. For this project I used a Rasp Pi with 2.8″ TFT touchscreen. These screens start at a round $15.
People’s morning interests will vary so in this blog I just wanted to highlight some of the issues that I needed to worked through. For me the main stumbling blocks were:
- Hiding the top Rasp Pi menu bar
- Creating a GUI that uses the full screen
- Getting weather data
- scraping web pages to extract what I need
Getting Started
There are some great Raspberry Pi TFT screens that come with buttons and cases. You will need to look at the documentation that comes with your screen, but a good reference is: https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi
For my project I simply used some of my kids Lego blocks.
Remove the Pi Menu Bar
The Pi TFT screen isn’t super large, so I wanted to remove the Pi menu bar and run my application at full size.
To remove the menu bar tweek two files. First:
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
Comment out the line (with #) :
@lxpanel --profile LXDE
Then do the same for:
nano /home/pi/.config/lxsession/LXDE-pi/autostart
After this reboot the system.
Create a Full Size App
There are a multitude of choices for a screen layout. I was looking for lines of text, with maybe the bottom line used for buttons. I found that 7 lines was a reasonable fit. To remove the Python Tkinter title I positioned the top of the screen above the physical screen position (-30 instead of 0).
# My Kitchen Appliance App # import urllib.request as urllib2 import tkinter as Tkinter from tkinter.ttk import * from tkinter.font import Font from tkinter import messagebox top = Tkinter.Tk() top.title("My Kitchen Appliance") top.geometry("320x240+-5+-30") # set screen size, left (-5) and top (-30) top.resizable(False, False) top.details_expanded = False #Define the buttons myfont = Font(family="Times New Roman Bold",size= 12) # Should try a few more sizes tft_rows = 7 # try 7 rows of buttons tftbutton = ['' for i in range(tft_rows)] for i in range(tft_rows): tftbutton[i] = Tkinter.Button(top, text = "Line " + str(i+1), fg = "blue", bg = "white", anchor="w", width= 35, height= 1,font=myfont).grid(row=(i+1),column=1) # a buttpn arra top.mainloop()
The Python GUI will look like this:
Get Weather Data
There are a number of good weather API’s. I used OpenWeather because I can use it in variety of apps like Node-Red. OpenWeather has a free user API but you should login and get an appid.
A Python example to get some current weather data for a city:
# get Open Weather (REST API) data import requests # api-endpoint URL = "https://openweathermap.org/data/2.5/weather?q=" mycity = "burlington,CA" myappid = "&appid=b6907d289e10d714a6e88b30761fae22" # sending get request and saving the response as response object fullURL = URL + mycity + myappid r = requests.get(fullURL) # extracting data in json format data = r.json() print (data) # Check out the structure #for index, value in enumerate(data): # print(index, value) # Show some weather data print (data['weather'][0]['description']) print (data['weather'][0]['main']) print (str(int(data['main']['temp'])) + " C") # convert wind speed from meters/sec to kph print (str((data['wind']['speed'] * 3.6)) + " kph")
This code will give output such as:
$Python3 burlweather.py {'coord': {'lon': -79.8, 'lat': 43.32}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'base': 'stations', 'main': {'temp': 5.81, 'pressure': 1014, 'humidity': 93, 'temp_min': 3.33, 'temp_max': 7.78}, 'visibility': 24140, 'wind': {'speed': 2.1, 'deg': 50}, 'clouds': {'all': 75}, 'dt': 1574816701, 'sys': {'type': 1, 'id': 818, 'country': 'CA', 'sunrise': 1574771158, 'sunset': 1574804839}, 'timezone': -18000, 'id': 5911592, 'name': 'Burlington', 'cod': 200} broken clouds Clouds 5 C 7 kph
Scraping Web Pages
I wasn’t able to find an API for all the things I was after, so I need to scrape web pages. The Python Beautiful Soup library is a great for finding and grabbing stuff on web pages. To install it:
$ apt-get install python-bs4
(for Python 2)
$ apt-get install python3-bs4
(for Python 3)
I had an example where I wanted to find the ski lifts and runs open. I had the Web page but I needed to search the ugly HTML code.
In the HTML code I found that the lift and run information is contained in a <p class=“open value” tag. Beautiful Soup allows you to make searches based on attributes. The results can be HTML code or the .text property will return the results as simple text (no HTML code).
The following Python code would search my URL and extract the number of lifts open:
$ python Python 3.7.4 Type "help", "copyright", "credits" or "license" for more information. >>> import urllib.request as urllib2 >>> from bs4 import BeautifulSoup >>> theurl = 'https://www.onthesnow.ca/ontario/blue-mountain/skireport.html' >>> page = urllib2.urlopen(theurl) >>> soup = BeautifulSoup(page, 'html.parser') >>> liftopen = soup.find("p", attrs={"class":"open value"}) >>> liftopen.text '2 of 11'
Final Comments
There are a ton of different “Pi Appliance” applications that could be done. I hope that some of these hints that I’ve documented are helpful.