If like many you have been starting gardens and planting rather than traveling and visiting in recent months, there is one important thing to consider lately – severe weather reports including frost on your crops. I noted there was a little red (!) alert icon on an Android weather widget, but there seems to be no such alert for desktop computer or Linux computer or phone. It is a fairly simple to make this alert though with a simple script:
Prep: Install lxml and requests libraries, these are a bit better and easier than the built in xml and libraries:
pip3 install lxml
pip3 install requests
You will need to find the ATOM feed url the national weather service gives for your region. The regions are listed mid-page here: https://alerts.weather.gov/ – for Iowa for example that would be the ATOM link, https://alerts.weather.gov/cap/ia.php?x=0.
Read a url to a string with:
req = requests.get('https://alerts.weather.gov/cap/wwaatmget.php?x=ORC029&y=0')
print(dir(req))
This shows the output, various attributes of which the “content” is mostly what we want:
import requests
import lxml
def main(args):
req = requests.get('https://alerts.weather.gov/cap/wwaatmget.php?x=ORC029&y=0')
print(dir(req))
print(req.content)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Gives the content of an ATOM xml. Now to change that inner script to parse it with lxml:
req = requests.get('https://alerts.weather.gov/cap/wwaatmget.php?x=ORC029&y=0')
xml = req.content
from lxml import etree
atom = etree.fromstring(xml)
print(atom)
This creates an element tree object:
$ python3 ./nws.py
<Element {http://www.w3.org/2005/Atom}feed ...
Note the namespace, a namespace is a space where a certain name has meaning (for example the word “can” as a verb or “can” as a container, you could say are in different namespaces, namespace of verbs and namespace of containers. All the elements in this document are atom xml elements… not svg graphics, not some other xml… and you can find an example of getting an element or elements here. Xpath is a good way to get all elements (by “//tagname” or a certain path such as “/outer/inner/tag/in/tag…” with outer tag and inner tag directly inside it.
The notifications area (at the top center of the screen or the side on older Ubuntu systems) can be notified by adding a notification using something like the examples here. I used libnotify, and pulling this all together:
import requests
import lxml
from gi.repository import Notify
Notify.init("weatheralert")
def main(args):
req = requests.get('https://alerts.weather.gov/cap/or.php?x=0')
xml = req.content
from lxml import etree
ns = {'atom': 'http://www.w3.org/2005/Atom'}
atom = etree.fromstring(xml)
for element in atom.xpath('//atom:entry', namespaces=ns):
title = ''
text = ''
for node in element.iterchildren():
if node.tag.find("event") >-1:
title = node.text
elif node.tag.find("summary") >-1:
text = node.text
notification = Notify.Notification.new(title, text)
notification.show()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
After some adjustments to not show non-alerts, the current revision is available here:
https://github.com/programmin1/WeatherAlert
Check it out add it to your crontab to get it set… run:
sudo nano /etc/crontab
The script can be run once every couple hours by adding a line:
1 */2 * * * username python3 /home/user/path/to/file.py