mirror of
https://github.com/thejeffreystone/home-assistant-configuration.git
synced 2025-02-09 00:55:08 +00:00
e02d084c92
Lots of updates here. Updated my Readme - Added Affiliate Links, added some more information, better organized devices Updated gitignore with paths realtive to my hassio config Combined my switches and lights into single yaml files instead of the directory structure previously Added zigbee2mqtt.yaml to packages - contains automations and such for zigbee2mqtt Archived my previous version in the V4-config branch.
188 lines
5.8 KiB
Python
Executable File
188 lines
5.8 KiB
Python
Executable File
'''
|
|
---------------------------------------------------------
|
|
NWS Alerts
|
|
---------------------------------------------------------
|
|
VERSION: 0.0.2
|
|
Forum: https://community.home-assistant.io/t/severe-weather-alerts-from-the-us-national-weather-service/71853
|
|
|
|
API Documentation
|
|
---------------------------------------------------------
|
|
https://www.weather.gov/documentation/services-web-api
|
|
https://forecast-v3.weather.gov/documentation
|
|
---------------------------------------------------------
|
|
'''
|
|
|
|
import requests
|
|
import logging
|
|
import voluptuous as vol
|
|
from datetime import timedelta
|
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
|
from homeassistant.const import CONF_NAME, ATTR_ATTRIBUTION
|
|
from homeassistant.helpers import config_validation as cv
|
|
from homeassistant.helpers.entity import Entity
|
|
from homeassistant.util import Throttle
|
|
|
|
|
|
API_ENDPOINT = 'https://api.weather.gov'
|
|
USER_AGENT = 'Home Assistant'
|
|
DEFAULT_ICON = 'mdi:alert'
|
|
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
|
|
_LOGGER = logging.getLogger(__name__)
|
|
DEFAULT_NAME = 'NWS Alerts'
|
|
CONF_ZONE_ID = 'zone_id'
|
|
ZONE_ID = ''
|
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
vol.Required(CONF_ZONE_ID): cv.string,
|
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
})
|
|
|
|
|
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
|
"""Setup the sensor platform."""
|
|
name = config.get(CONF_NAME, DEFAULT_NAME)
|
|
zone_id = config.get(CONF_ZONE_ID)
|
|
add_devices([NWSAlertSensor(name, zone_id)])
|
|
|
|
|
|
class NWSAlertSensor(Entity):
|
|
"""Representation of a Sensor."""
|
|
|
|
def __init__(self, name, zone_id):
|
|
"""Initialize the sensor."""
|
|
self._name = name
|
|
self._icon = DEFAULT_ICON
|
|
self._state = 0
|
|
self._event = None
|
|
self._display_desc = None
|
|
self._spoken_desc = None
|
|
self._zone_id = zone_id.replace(' ', '')
|
|
self.update()
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the sensor."""
|
|
return self._name
|
|
|
|
@property
|
|
def icon(self):
|
|
"""Return the icon to use in the frontend, if any."""
|
|
return self._icon
|
|
|
|
@property
|
|
def state(self):
|
|
"""Return the state of the sensor."""
|
|
return self._state
|
|
|
|
@property
|
|
def device_state_attributes(self):
|
|
"""Return the state message."""
|
|
attributes = {"title": self._event,
|
|
"display_desc": self._display_desc,
|
|
"spoken_desc": self._spoken_desc
|
|
}
|
|
|
|
return attributes
|
|
|
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
|
def update(self):
|
|
"""Fetch new state data for the sensor.
|
|
This is the only method that should fetch new data for Home Assistant.
|
|
"""
|
|
values = self.get_state()
|
|
self._state = values['state']
|
|
self._event = values['event']
|
|
self._display_desc = values['display_desc']
|
|
self._spoken_desc = values['spoken_desc']
|
|
|
|
def get_state(self):
|
|
values = {'state': 0,
|
|
'event': None,
|
|
'display_desc': None,
|
|
'spoken_desc': None
|
|
}
|
|
|
|
headers = {'User-Agent': USER_AGENT,
|
|
'Accept': 'application/ld+json'
|
|
}
|
|
|
|
url = '%s/alerts/active/count' % API_ENDPOINT
|
|
r = requests.get(url, headers=headers)
|
|
_LOGGER.debug("getting state, %s", url)
|
|
if r.status_code == 200:
|
|
if 'zones' in r.json():
|
|
for zone in self._zone_id.split(','):
|
|
if zone in r.json()['zones']:
|
|
values = self.get_alerts()
|
|
break
|
|
|
|
return values
|
|
|
|
def get_alerts(self):
|
|
values = {'state': 0,
|
|
'event': None,
|
|
'display_desc': None,
|
|
'spoken_desc': None
|
|
}
|
|
|
|
headers = {'User-Agent': USER_AGENT,
|
|
'Accept': 'application/geo+json'
|
|
}
|
|
url = '%s/alerts/active?zone=%s' % (API_ENDPOINT, self._zone_id)
|
|
r = requests.get(url, headers=headers)
|
|
_LOGGER.debug("getting alert, %s", url)
|
|
if r.status_code == 200:
|
|
events = []
|
|
headlines = []
|
|
display_desc = ''
|
|
spoken_desc = ''
|
|
features = r.json()['features']
|
|
for alert in features:
|
|
event = alert['properties']['event']
|
|
if 'NWSheadline' in alert['properties']['parameters']:
|
|
headline = alert['properties']['parameters']['NWSheadline'][0]
|
|
else:
|
|
headline = event
|
|
|
|
description = alert['properties']['description']
|
|
instruction = alert['properties']['instruction']
|
|
|
|
if event in events:
|
|
continue
|
|
|
|
events.append(event)
|
|
headlines.append(headline)
|
|
|
|
if display_desc != '':
|
|
display_desc += '\n\n'
|
|
|
|
display_desc += '<b>%s</b>\n%s\n%s\n%s' % (event, headline, description, instruction)
|
|
|
|
if headlines:
|
|
num_headlines = len(headlines)
|
|
i = 0
|
|
for headline in headlines:
|
|
i += 1
|
|
if spoken_desc != '':
|
|
if i == num_headlines:
|
|
spoken_desc += ' and a '
|
|
else:
|
|
spoken_desc += ', a '
|
|
|
|
spoken_desc += headline
|
|
|
|
if len(events) > 0:
|
|
event_str = ''
|
|
for item in events:
|
|
if event_str != '':
|
|
event_str += ' - '
|
|
event_str += item
|
|
|
|
values['state'] = len(events)
|
|
values['event'] = event_str
|
|
values['display_desc'] = display_desc
|
|
values['spoken_desc'] = spoken_desc
|
|
|
|
return values
|
|
|