Table of Contents
Pulling the Current UK Threat Level from MI5
The MI5 provide 'the current' UK threat level in an RSS (Atom) feed, which can be parsed to use within Home Assistant. Unfortunately, feedreader is poorly documented and doesn't really do what we need so for this you have two options; AppDeemon, PyScript, both of which are Add-ons from HACS.
I'm going to document the PyScript Method here, and this tutorial assumed you already have PyScript installed and working.
PyScript
Firstly, create an input_text helper called threatlevel. This is where we'll store the threat level.
Next, we create our PyScript code (which you place in config/pyscript by default) in a file named mi5.py:
import feedparser import requests import json import pprint import datetime @pyscript_compile def getmi5(url): try: headers = {'User-Agent': 'curl/7.68.0'} response = requests.get(url, headers=headers) data = response.content # bytes cus its UTF-8 return data, None except Exception as exc: return None, exc @service def mi5(action=None, id=None): """MI5 API (RSS) fetcher and parser""" log.info(f"MI5 got action {action} id {id}") contents, exception = task.executor(getmi5, "https://www.mi5.gov.uk/UKThreatLevel/UKThreatLevel.xml") if exception: raise exception feed = feedparser.parse(contents) if feed.entries: levelstr = feed.entries[0]['title'] levelarr = levelstr.split(': ') level = levelarr[1] else: level = "Unknown" threat = input_text.threatlevel log.info(f"Current Value: {threat} new value {level}") if threat != level: input_text.threatlevel = level
What we are doing here is fetching the XML from the MI5 website, then parsing this with feedparser, checking we've got entries, and then extracting the threat level from the feed entry. We then check to see if its the same, and if not, we update input_text.threatlevel.
The reason we need to use task.executor, is because MI5 can't afford a proper web host and it takes too long to retrieve the feed otherwise.
To actually make this code run, you need to setup an automation to call it. Something like:
alias: "Schedule: MI5 Threat Level" description: "" trigger: - platform: time_pattern minutes: "0" condition: - condition: time after: "07:00:00" before: "22:00:00" action: - service: pyscript.mi5 data: {} mode: single
Notice we're getting the update every hour between 0700 and 2200. Its important not to be silly with this and don't spam MI5's server or it will likely block you (I would), so once an hour seems a fair rate.
Finally, you can create an automation that's triggered on a state change of input_text.threatlevel to, for example, send you a message, play a message, broadcast an announcement and anything else you want.
AppDaemon
For anyone wanting to use AppDaemon instead this would be the code:
import hassapi as hass import feedparser import requests import json import pprint import datetime class MI5(hass.Hass): def initialize(self): self.run_hourly(self.run_schedule, datetime.time(hour=0)) def run_schedule(self, cb_args): url = "https://www.mi5.gov.uk/UKThreatLevel/UKThreatLevel.xml" headers = {'User-Agent': 'curl/7.68.0'} response = requests.get(url, headers=headers) data = response.content # bytes cus its UTF-8 feed = feedparser.parse(data) if feed.entries: levelstr = feed.entries[0]['title'] levelarr = levelstr.split(': ') level = levelarr[1] else: level = "Unknown" clevel = self.get_entity("input_text.threatlevel") if clevel.state != level: log = "Setting threat level to "+level self.log(log) self.set_textvalue("input_text.threatlevel",level) self.set_state("input_text.threatlevel",level) else: self.log("No Change Required")
Don't forget to add the app in apps.yaml.