Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 33 additions & 91 deletions homeassistant/components/openuv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
CONF_ELEVATION,
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_MONITORED_CONDITIONS,
CONF_SENSORS,
)
from homeassistant.exceptions import ConfigEntryNotReady
Expand Down Expand Up @@ -52,60 +51,6 @@
TYPE_SAFE_EXPOSURE_TIME_5 = "safe_exposure_time_type_5"
TYPE_SAFE_EXPOSURE_TIME_6 = "safe_exposure_time_type_6"

BINARY_SENSORS = {TYPE_PROTECTION_WINDOW: ("Protection Window", "mdi:sunglasses")}

BINARY_SENSOR_SCHEMA = vol.Schema(
{
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(BINARY_SENSORS)): vol.All(
cv.ensure_list, [vol.In(BINARY_SENSORS)]
)
}
)

SENSORS = {
TYPE_CURRENT_OZONE_LEVEL: ("Current Ozone Level", "mdi:vector-triangle", "du"),
TYPE_CURRENT_UV_INDEX: ("Current UV Index", "mdi:weather-sunny", "index"),
TYPE_CURRENT_UV_LEVEL: ("Current UV Level", "mdi:weather-sunny", None),
TYPE_MAX_UV_INDEX: ("Max UV Index", "mdi:weather-sunny", "index"),
TYPE_SAFE_EXPOSURE_TIME_1: (
"Skin Type 1 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_2: (
"Skin Type 2 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_3: (
"Skin Type 3 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_4: (
"Skin Type 4 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_5: (
"Skin Type 5 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_6: (
"Skin Type 6 Safe Exposure Time",
"mdi:timer",
"minutes",
),
}

SENSOR_SCHEMA = vol.Schema(
{
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSORS)): vol.All(
cv.ensure_list, [vol.In(SENSORS)]
)
}
)

CONFIG_SCHEMA = vol.Schema(
{
Expand All @@ -115,8 +60,6 @@
vol.Optional(CONF_ELEVATION): float,
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_BINARY_SENSORS, default={}): BINARY_SENSOR_SCHEMA,
vol.Optional(CONF_SENSORS, default={}): SENSOR_SCHEMA,
}
)
},
Expand All @@ -142,12 +85,7 @@ async def async_setup(hass, config):
if identifier in configured_instances(hass):
return True

data = {
CONF_API_KEY: conf[CONF_API_KEY],
CONF_BINARY_SENSORS: conf[CONF_BINARY_SENSORS],
CONF_SENSORS: conf[CONF_SENSORS],
}

data = {CONF_API_KEY: conf[CONF_API_KEY]}
if CONF_LATITUDE in conf:
data[CONF_LATITUDE] = conf[CONF_LATITUDE]
if CONF_LONGITUDE in conf:
Expand Down Expand Up @@ -178,13 +116,7 @@ async def async_setup_entry(hass, config_entry):
config_entry.data.get(CONF_LONGITUDE, hass.config.longitude),
websession,
altitude=config_entry.data.get(CONF_ELEVATION, hass.config.elevation),
),
config_entry.data.get(CONF_BINARY_SENSORS, {}).get(
CONF_MONITORED_CONDITIONS, list(BINARY_SENSORS)
),
config_entry.data.get(CONF_SENSORS, {}).get(
CONF_MONITORED_CONDITIONS, list(SENSORS)
),
)
)
await openuv.async_update()
hass.data[DOMAIN][DATA_OPENUV_CLIENT][config_entry.entry_id] = openuv
Expand Down Expand Up @@ -243,39 +175,49 @@ async def async_unload_entry(hass, config_entry):
return True


async def async_migrate_entry(hass, config_entry):
"""Migrate the config entry upon new versions."""
version = config_entry.version
data = {**config_entry.data}

_LOGGER.debug("Migrating from version %s", version)

# 1 -> 2: Remove unused condition data:
if version == 1:
data.pop(CONF_BINARY_SENSORS, None)
data.pop(CONF_SENSORS, None)
version = config_entry.version = 2
hass.config_entries.async_update_entry(config_entry, data=data)
_LOGGER.debug("Migration to version %s successful", version)

return True


class OpenUV:
"""Define a generic OpenUV object."""

def __init__(self, client, binary_sensor_conditions, sensor_conditions):
def __init__(self, client):
"""Initialize."""
self.binary_sensor_conditions = binary_sensor_conditions
self.client = client
self.data = {}
self.sensor_conditions = sensor_conditions

async def async_update_protection_data(self):
"""Update binary sensor (protection window) data."""

if TYPE_PROTECTION_WINDOW in self.binary_sensor_conditions:
try:
resp = await self.client.uv_protection_window()
self.data[DATA_PROTECTION_WINDOW] = resp["result"]
except OpenUvError as err:
_LOGGER.error("Error during protection data update: %s", err)
self.data[DATA_PROTECTION_WINDOW] = {}
return
try:
resp = await self.client.uv_protection_window()
self.data[DATA_PROTECTION_WINDOW] = resp["result"]
except OpenUvError as err:
_LOGGER.error("Error during protection data update: %s", err)
self.data[DATA_PROTECTION_WINDOW] = {}

async def async_update_uv_index_data(self):
"""Update sensor (uv index, etc) data."""

if any(c in self.sensor_conditions for c in SENSORS):
try:
data = await self.client.uv_index()
self.data[DATA_UV] = data
except OpenUvError as err:
_LOGGER.error("Error during uv index data update: %s", err)
self.data[DATA_UV] = {}
return
try:
data = await self.client.uv_index()
self.data[DATA_UV] = data
except OpenUvError as err:
_LOGGER.error("Error during uv index data update: %s", err)
self.data[DATA_UV] = {}

async def async_update(self):
"""Update sensor/binary sensor data."""
Expand Down
10 changes: 6 additions & 4 deletions homeassistant/components/openuv/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from homeassistant.util.dt import as_local, parse_datetime, utcnow

from . import (
BINARY_SENSORS,
DATA_OPENUV_CLIENT,
DATA_PROTECTION_WINDOW,
DOMAIN,
Expand All @@ -17,21 +16,24 @@
)

_LOGGER = logging.getLogger(__name__)

ATTR_PROTECTION_WINDOW_ENDING_TIME = "end_time"
ATTR_PROTECTION_WINDOW_ENDING_UV = "end_uv"
ATTR_PROTECTION_WINDOW_STARTING_TIME = "start_time"
ATTR_PROTECTION_WINDOW_STARTING_UV = "start_uv"

BINARY_SENSORS = {TYPE_PROTECTION_WINDOW: ("Protection Window", "mdi:sunglasses")}


async def async_setup_entry(hass, entry, async_add_entities):
"""Set up an OpenUV sensor based on a config entry."""
openuv = hass.data[DOMAIN][DATA_OPENUV_CLIENT][entry.entry_id]

binary_sensors = []
for sensor_type in openuv.binary_sensor_conditions:
name, icon = BINARY_SENSORS[sensor_type]
for kind, attrs in BINARY_SENSORS.items():
name, icon = attrs
binary_sensors.append(
OpenUvBinarySensor(openuv, sensor_type, name, icon, entry.entry_id)
OpenUvBinarySensor(openuv, kind, name, icon, entry.entry_id)
)

async_add_entities(binary_sensors, True)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/openuv/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def configured_instances(hass):
class OpenUvFlowHandler(config_entries.ConfigFlow):
"""Handle an OpenUV config flow."""

VERSION = 1
VERSION = 2
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL

def __init__(self):
Expand Down
46 changes: 40 additions & 6 deletions homeassistant/components/openuv/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
DATA_OPENUV_CLIENT,
DATA_UV,
DOMAIN,
SENSORS,
TOPIC_UPDATE,
TYPE_CURRENT_OZONE_LEVEL,
TYPE_CURRENT_UV_INDEX,
Expand Down Expand Up @@ -43,17 +42,52 @@
UV_LEVEL_MODERATE = "Moderate"
UV_LEVEL_LOW = "Low"

SENSORS = {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the constants maybe into const.py inside integration?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I traditionally haven't done this; instead, I've followed the pattern used by HASS itself (centralize a constant into const.py if it is used in more than one place, otherwise define it where it is used). Should I not be doing that?

TYPE_CURRENT_OZONE_LEVEL: ("Current Ozone Level", "mdi:vector-triangle", "du"),
TYPE_CURRENT_UV_INDEX: ("Current UV Index", "mdi:weather-sunny", "index"),
TYPE_CURRENT_UV_LEVEL: ("Current UV Level", "mdi:weather-sunny", None),
TYPE_MAX_UV_INDEX: ("Max UV Index", "mdi:weather-sunny", "index"),
TYPE_SAFE_EXPOSURE_TIME_1: (
"Skin Type 1 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_2: (
"Skin Type 2 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_3: (
"Skin Type 3 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_4: (
"Skin Type 4 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_5: (
"Skin Type 5 Safe Exposure Time",
"mdi:timer",
"minutes",
),
TYPE_SAFE_EXPOSURE_TIME_6: (
"Skin Type 6 Safe Exposure Time",
"mdi:timer",
"minutes",
),
}


async def async_setup_entry(hass, entry, async_add_entities):
"""Set up a Nest sensor based on a config entry."""
openuv = hass.data[DOMAIN][DATA_OPENUV_CLIENT][entry.entry_id]

sensors = []
for sensor_type in openuv.sensor_conditions:
name, icon, unit = SENSORS[sensor_type]
sensors.append(
OpenUvSensor(openuv, sensor_type, name, icon, unit, entry.entry_id)
)
for kind, attrs in SENSORS.items():
name, icon, unit = attrs
sensors.append(OpenUvSensor(openuv, kind, name, icon, unit, entry.entry_id))

async_add_entities(sensors, True)

Expand Down