In this project, we will be using an online weather service to display local weather and time on a Graphic LCD Phidget (LCD1100). Code is available for this project in C# and Python.
SuppliesThe following hardware is used:
- VINT Hub Phidget (HUB0000_0)
- Graphic LCD Phidget (LCD1100_0)
Connect your Graphic LCD Phidget to your VINT Hub on any port.
Step 2: OverviewAs shown above, there are two main parts of this project:
- Accessing weather data
- Displaying weather data
Let's start by taking a look at accessing the data.
Step 3: Accessing Weather DataWe will be using OpenWeather to access our local weather forecast. They provide free access to weather forecasts in over 200, 000 cities. The following formats are supported:
- JSON
- XML
- HTML
For this project, we will be using XML format.
In order to access weather data, you must create a free account and get an API key.
Step 4: Create Your AccountFollow this link to create a free account and get an API key. After getting your API key, you will can access data through this URL:
api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}Replace {city name} with your city, and {API key} with your API key. For example, this is what ours looks like:
http://api.openweathermap.org/data/2.5/weather?q=Calgary&APPID=fakeid111111111111111111111111111&units=metric&mode=xmlTry entering your URL into any web browser. You will see XML formatted weather data as shown above. The next step is creating a program that can parse the data so it can be displayed.
Step 5: Read/Parse Weather Data - C#For C#, you can use the XMLTextReader class to quickly parse the XML data:
static string readXML(string arg1, string arg2)
{
String URLString = "http://api.openweathermap.org/data/2.5/weather?q=Calgary&APPID=fakeid111111111111111111111111111&units=metric&mode=xml";
XmlTextReader reader = new XmlTextReader(URLString);
reader.ReadToFollowing(arg1);
reader.MoveToAttribute(arg2);
return reader.Value;
}You can use the function above like this:
static void updateWeather(LCD lcd) {
string city = readXML("city", "name");
string temperature = readXML("temperature", "value");
string humidity = readXML("humidity", "value");
string windspeed = readXML("speed", "value");
string descript = readXML("weather", "value");
string iconID = readXML("weather", "icon");
}There are other values available (sunrise time, sunset time, pressure, etc.) but for this project, we will only be displaying a subset of the values.
Step 6: Read/Parse Weather Data - PythonFor Python, you can use the ElementTree XML API to quickly parse the data:
import xml.etree.ElementTree as ET
from urllib.request import urlopen
url = urlopen('http://api.openweathermap.org/data/2.5/weather?q=Calgary&APPID=fakeid111111111111111111111111111&units=metric&mode=xml')
tree = ET.parse(url)
root = tree.getroot()
def readXML(arg1, arg2):
for item in root.iter(arg1):
return item.get(arg2)
print(readXML('city','name'))
print(readXML('temperature','value'))
print(readXML('humidity','value'))
print(readXML('speed','value'))
print(readXML('weather','value'))
print(readXML('weather','icon'))There are other values available (sunrise time, sunset time, pressure, etc.) but for this project, we will only be displaying a subset of the values.
Step 7: OpenWeather IconsYou may have noticed that we stored the iconID above. This value represents an image describing the current weather. You can view the icons here. The Graphic LCD Phidget is capable of displaying bitmaps, we can easily implement these icons in our program. If you haven't explored bitmaps on the Graphic LCD Phidget, check out this project.
There are many pixel art programs available online, we used Piskel. It was easy to recreate the OpenWeatherMap icons because of the simple Export to C File option. The results of the bitmaps are provided in the github repo below.
Step 8: Displaying Data - C#Now that we have collected the weather data, the last step is to display it on the Graphic LCD Phidget:
static void updateWeather(LCD lcd)
{
string city = readXML("city", "name");
string temperature = readXML("temperature", "value");
string humidity = readXML("humidity", "value");
string windspeed = readXML("speed", "value");
string descript = readXML("weather", "value");
string iconID = readXML("weather", "icon");
if (temperature.Length > 5)
{
temperature = temperature.Remove(5);
}
//Temperature box
int x = (44 - ((temperature.Length * 6) + 12)) / 2;
lcd.WriteText(LCDFont.Dimensions_6x12, x, 15, temperature);
lcd.WriteText(LCDFont.User1, x + temperature.Length * 6, 15, "0");
lcd.WriteText(LCDFont.Dimensions_6x12, x + temperature.Length * 6 + 6, 15, "C");
//Weather image + descript box
byte[] temp;
if (iconID == "01d")
temp = _01d;
else if (iconID == "02d")
temp = _02d;
else if (iconID == "03d")
temp = _03d;
else if (iconID == "04d")
temp = _04d;
else if (iconID == "09d")
temp = _09d;
else if (iconID == "10d")
temp = _10d;
else if (iconID == "11d")
temp = _11d;
else if (iconID == "13d")
temp = _13d;
else if (iconID == "50d")
temp = _50d;
else if (iconID == "01n")
temp = _01n;
else if (iconID == "02n")
temp = _02n;
else if (iconID == "10n")
temp = _10n;
else
temp = unknown;
lcd.WriteBitmap(2, 31, 32, 32, temp);
lcd.WriteText(LCDFont.Dimensions_5x8, 40, 42, descript);
//Extra info box
lcd.WriteText(LCDFont.Dimensions_5x8, 50, 11, "Humidity: " + humidity + "%");
lcd.WriteText(LCDFont.Dimensions_5x8, 50, 20, "Wind: " + windspeed + "km/h");
}
static void redraw(LCD lcd)
{
lcd.Clear();
//draw borders around outside
lcd.DrawLine(0, 0, 127, 0);
lcd.DrawLine(0, 0, 0, 63);
lcd.DrawLine(127, 0, 127, 63);
lcd.DrawLine(0, 63, 127, 63);
//draw borders inside
lcd.DrawLine(0, 10, 128, 10);
lcd.DrawLine(43, 10, 43, 30);
lcd.DrawLine(1, 30, 127, 30);
lcd.WriteText(LCDFont.Dimensions_5x8, 1, 1, DateTime.Now.ToString(" ddd, MMM d hh:mm:ss tt"));
updateWeather(lcd);
lcd.Flush();
}<br>Here is a quick review of the code above:
redraw
This function draws the main borders on the Graphic LCD. It also prints the current time and calls the updateWeather program.
updateWeather
This function arranges the data from the OpenWeather service onto the Graphic LCD.
Step 9: Displaying Data - PythonNow that we have collected the weather data, the last step is to display it on the Graphic LCD Phidget:
def updateWeather():
city = readXML('city', 'name')
temperature = readXML('temperature', 'value')
humidity = readXML('humidity', 'value')
windspeed = readXML('speed', 'value')
descript = readXML('weather', 'value')
iconID = readXML('weather', 'icon')
if(len(temperature) > 5):
temperature = temperature[:-1:] #remove last char so it fits
#temperature box
x = (44 - ((len(temperature) * 6) + 12)) / 2
x = int(x) #force to int
lcd.writeText(LCDFont.FONT_6x12, x, 15, temperature)
lcd.writeText(LCDFont.FONT_User1, x + len(temperature) * 6, 15, "0")
lcd.writeText(LCDFont.FONT_6x12, x + len(temperature) * 6 + 6, 15, "C")
#Weather icon + descript box
temp = []
if(iconID == "01d"):
temp = _01d
elif(iconID == "02d"):
temp = _02d
elif (iconID == "03d"):
temp = _03d
elif (iconID == "04d"):
temp = _04d
elif (iconID == "09d"):
temp = _09d
elif (iconID == "10d"):
temp = _10d
elif (iconID == "11d"):
temp = _11d
elif (iconID == "13d"):
temp = _13d
elif (iconID == "50d"):
temp = _50d
elif (iconID == "01n"):
temp = _01n
elif (iconID == "02n"):
temp = _02n
elif (iconID == "10n"):
temp = _10n
else:
temp = unknown
lcd.writeBitmap(2, 31, 32, 32, temp)
lcd.writeText(LCDFont.FONT_5x8, 40, 42, descript)
#Extra info box
lcd.writeText(LCDFont.FONT_5x8, 50, 11, "Humidity: " + humidity + "%")
lcd.writeText(LCDFont.FONT_5x8, 50, 20, "Wind: " + windspeed + "km/h")
def redraw():
lcd.clear()
#Draw borders around outside
lcd.drawLine(0, 0, 127, 0)
lcd.drawLine(0, 0, 0, 63)
lcd.drawLine(127, 0, 127, 63)
lcd.drawLine(0, 63, 127, 63)
#draw borders inside
lcd.drawLine(0, 10, 128, 10)
lcd.drawLine(43, 10, 43, 30)
lcd.drawLine(1, 30, 127, 30)
timeStr = datetime.now().strftime("%a, %b %d %I:%M:%S %p")
lcd.writeText(LCDFont.FONT_5x8, 1, 1, timeStr)
updateWeather()
lcd.flush()<br>Here is a quick review of the code above:redraw
This function draws the main borders on the Graphic LCD. It also prints the current time and calls the updateWeather program.
updateWeather
This function arranges the data from the OpenWeather service onto the Graphic LCD.
Step 10: Main LoopThe last thing to do is to create a main loop that updates the LCD on a set schedule. Here is what we recommend:
- Every second: update the time on the LCD
- Every 15 minutes: update the weather status on the LCD
Create an infinite loop that loops every second. Create a counter to track the loops, when the counter hits 900 (900 seconds is 15 minutes) update the weather.
Step 11: Going ForwardThe full code for this project is available here: https://github.com/phidgeteer/LCDWeather.git
If you have any questions, drop a comment below!







Comments