1 """Generic GeoRSS events service.
3 Retrieves current events (typically incidents or alerts) in GeoRSS format, and
4 shows information on events filtered by distance to the HA instance's location
5 and grouped by category.
8 from __future__
import annotations
10 from datetime
import timedelta
13 from georss_client
import UPDATE_OK, UPDATE_OK_NO_DATA
14 from georss_generic_client
import GenericFeed
15 import voluptuous
as vol
18 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
26 CONF_UNIT_OF_MEASUREMENT,
35 _LOGGER = logging.getLogger(__name__)
37 ATTR_CATEGORY =
"category"
38 ATTR_DISTANCE =
"distance"
41 CONF_CATEGORIES =
"categories"
43 DEFAULT_ICON =
"mdi:alert"
44 DEFAULT_NAME =
"Event Service"
45 DEFAULT_RADIUS_IN_KM = 20.0
46 DEFAULT_UNIT_OF_MEASUREMENT =
"Events"
48 DOMAIN =
"geo_rss_events"
52 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
54 vol.Required(CONF_URL): cv.string,
55 vol.Optional(CONF_LATITUDE): cv.latitude,
56 vol.Optional(CONF_LONGITUDE): cv.longitude,
57 vol.Optional(CONF_RADIUS, default=DEFAULT_RADIUS_IN_KM): vol.Coerce(float),
58 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
59 vol.Optional(CONF_CATEGORIES, default=[]): vol.All(cv.ensure_list, [cv.string]),
61 CONF_UNIT_OF_MEASUREMENT, default=DEFAULT_UNIT_OF_MEASUREMENT
70 add_entities: AddEntitiesCallback,
71 discovery_info: DiscoveryInfoType |
None =
None,
73 """Set up the GeoRSS component."""
74 latitude = config.get(CONF_LATITUDE, hass.config.latitude)
75 longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
76 url = config.get(CONF_URL)
77 radius_in_km = config.get(CONF_RADIUS)
78 name = config.get(CONF_NAME)
79 categories = config.get(CONF_CATEGORIES)
80 unit_of_measurement = config.get(CONF_UNIT_OF_MEASUREMENT)
83 "latitude=%s, longitude=%s, url=%s, radius=%s",
94 (latitude, longitude), url, radius_in_km,
None, name, unit_of_measurement
96 devices.append(device)
98 for category
in categories:
100 (latitude, longitude),
107 devices.append(device)
112 """Representation of a Sensor."""
115 self, coordinates, url, radius, category, service_name, unit_of_measurement
117 """Initialize the sensor."""
127 filter_radius=radius,
128 filter_categories=
None if not category
else [category],
133 """Return the name of the sensor."""
134 return f
"{self._service_name} {'Any' if self._category is None else self._category}"
138 """Return the state of the sensor."""
143 """Return the unit of measurement."""
148 """Return the default icon to use in the frontend."""
153 """Return the state attributes."""
157 """Update this sensor from the GeoRSS service."""
160 if status == UPDATE_OK:
162 "Adding events to sensor %s: %s", self.
entity_identity_id, feed_entries
164 self.
_state_state = len(feed_entries)
167 for entry
in feed_entries:
168 matrix[entry.title] = (
169 f
"{entry.distance_to_home:.0f}{UnitOfLength.KILOMETERS}"
172 elif status == UPDATE_OK_NO_DATA:
173 _LOGGER.debug(
"Update successful, but no data received from %s", self.
_feed_feed)
177 "Update not successful, no data received from %s", self.
_feed_feed
def add_entities(account, async_add_entities, tracked)