Sometime ago I've come across MetaWeather, a weather data service requires no authentication or registration. I figured I'll make a little weather forecast display. (But is the weather service accurate though? Maybe just ok in my country. You can always check more accurate weather forecast on your phone, right?)
I used a WeMos D1 mini ESP8266/ESP-12 board with a much larger LCD 2004A 20x4 display module (with a LCM1602 I2C board on it). The core principle is basically the same as my ESp8266 Web Clock project.
This device would:
- Connect to WiFi on startup and make query.
- Display and cycle 6-day weather forecast data on LCD every 1.5 seconds.
- If you want an update of the weather data, press button to reset device or unplug/replug it.
EDIT: Originally I wanted this device to update automatically every 1 hour or whenever user pressed the button. It turns out the D1 would ran out of memory (get MemoryError in the JSON parsing stage) after first successful query! So now you need to reset device to manually update the data.
LCD 20x4 I2C display:
- Vcc -> 5V
- Gnd -> G
- SCL -> D1 (GPIO 5)
- SDA -> D2 (GPIO 4)
Push button:
- Leg 1 -> D3 (GPIO 0)
- Leg 2 -> G
Since D3/GPIO 0 has a built-in pull up resistor, you don't need to add one here.
And sorry that I cannot provide a Fritzing diagram; my Fritzing stopped working after I upgrade my PC with a brand new graphic card in order to play Assassin's Creed: Odyssey at 40+ fps. (Totally worth it though.)
I use MicroPython for ESP8266 v1.11 firmware. I also use Thonny editor.
The LCD display needs a driver as well: https://github.com/dhylands/python_lcd
Download the.zip, unzip it and upload lcd_api.py and esp8266_i2c_lcd.py onto your board. This driver works on LCD 16x2 too and also on ESP32 boards.
from machine import I2C, Pin
from esp8266_i2c_lcd import I2cLcd
lcd = I2cLcd(I2C(scl=Pin(5), sda=Pin(4)), 0x27, 4, 20)
lcd.move_to(0, 0)
lcd.putstr("Test line 1\nTest line 2")
Just remember to use move_to(x, y) to set the proper start position for new text. "\n" switch the position to next line and itself counted as one character. If the writing position reached end of line it would also move to the next line. Texts also remains on the screen if they haven't been replaced by other texts.
To clear the whole screen:
lcd.move_to(0, 0)
lcd.putstr(" " * 80)
Which write 80 spaces to the display.
There are also some example can be found here.
WiFi
Change the value of the variables ssid and pw in the code to your WiFi AP name and password. Do not share these information online.
If the board lose WiFi connection after initial startup, check your WiFi and simply reset the board/reconnect power.
Power SupplyIn my case, using a micro USB cable connecting the D1 and PC USB port is enough to power both the board and the LCD.
The MetaWeather APIIn https://www.metaweather.com/api/ you can see detailed information of the API, which returns JSON data.
Long story short, you need to look up your city or location's woeid (Where On Earth ID):
https://www.metaweather.com/api/location/search/?query=taipei
which returns
[
{
"title":"Taipei",
"location_type":"City",
"woeid":2306179,
"latt_long":"25.085960, 121.561478"
}
]
Then you can request weather data for the specific location:
https://www.metaweather.com/api/location/2306179/
Which you'll get
{
"consolidated_weather":[
{
"id":5731243456987136,
"weather_state_name":"Light Rain",
"weather_state_abbr":"lr",
"wind_direction_compass":"WSW",
"created":"2019-08-11T04:42:02.309324Z",
"applicable_date":"2019-08-11",
"min_temp":28.765,
"max_temp":35.205,
"the_temp":35.535,
"wind_speed":7.43196686833161,
"wind_direction":253.49900702591995,
"air_pressure":998.385,
"humidity":59,
"visibility":10.609913107452478,
"predictability":75
},
{
"id":5498167426547712,
"weather_state_name":"Heavy Rain",
"weather_state_abbr":"hr",
"wind_direction_compass":"W",
"created":"2019-08-11T04:42:05.246764Z",
"applicable_date":"2019-08-12",
"min_temp":27.424999999999997,
"max_temp":33.925,
"the_temp":35.379999999999995,
"wind_speed":3.7761608663591297,
"wind_direction":259.33212604917344,
"air_pressure":1000.4449999999999,
"humidity":64,
"visibility":13.22681788356001,
"predictability":77
},
......
],
"time":"2019-08-11T13:44:16.507115+08:00",
"sun_rise":"2019-08-11T05:25:59.195781+08:00",
"sun_set":"2019-08-11T18:32:16.764758+08:00",
"timezone_name":"LMT",
"parent":{
"title":"Taiwan",
"location_type":"Country",
"woeid":23424971,
"latt_long":"23.598440, 121.017616"
},
"sources":[
{
"title":"BBC",
"slug":"bbc",
"url":"http://www.bbc.co.uk/weather/",
"crawl_rate":360
},
{
"title":"Forecast.io",
"slug":"forecast-io",
"url":"http://forecast.io/",
"crawl_rate":480
},
......
],
"title":"Taipei",
"location_type":"City",
"woeid":2306179,
"latt_long":"25.085960, 121.561478",
"timezone":"Asia/Taipei"
}
So we can parse the JSON data and extract what we want.
>>> %Run WebWeather.py
Connecting to WiFi...
connected.
Querying data...
successful.
Weather forecast for [Taipei]
Data time: [2019-08-11T13:00:32.397399+08:00]
Date: 08-11 [75%], Temp: 35/29 *C, Humid: 59, State: Light Rain
Date: 08-12 [77%], Temp: 34/27 *C, Humid: 64, State: Heavy Rain
Date: 08-13 [75%], Temp: 35/27 *C, Humid: 63, State: Light Rain
Date: 08-14 [71%], Temp: 35/27 *C, Humid: 61, State: Heavy Cloud
Date: 08-15 [75%], Temp: 35/27 *C, Humid: 56, State: Light Rain
Date: 08-16 [77%], Temp: 35/27 *C, Humid: 55, State: Heavy Rain
Comments