mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Add ability to configure map icons for PurpleAir (#86124)
This commit is contained in:
parent
522d2496df
commit
39e0662fc8
@ -1,6 +1,9 @@
|
||||
"""The PurpleAir integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from aiopurpleair.models.sensors import SensorModel
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
@ -9,7 +12,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import CONF_SHOW_ON_MAP, DOMAIN
|
||||
from .coordinator import PurpleAirDataUpdateCoordinator
|
||||
|
||||
PLATFORMS = [Platform.SENSOR]
|
||||
@ -60,16 +63,30 @@ class PurpleAirEntity(CoordinatorEntity[PurpleAirDataUpdateCoordinator]):
|
||||
self._attr_device_info = DeviceInfo(
|
||||
configuration_url=self.coordinator.async_get_map_url(sensor_index),
|
||||
hw_version=self.sensor_data.hardware,
|
||||
identifiers={(DOMAIN, str(self._sensor_index))},
|
||||
identifiers={(DOMAIN, str(sensor_index))},
|
||||
manufacturer="PurpleAir, Inc.",
|
||||
model=self.sensor_data.model,
|
||||
name=self.sensor_data.name,
|
||||
sw_version=self.sensor_data.firmware_version,
|
||||
)
|
||||
self._attr_extra_state_attributes = {
|
||||
ATTR_LATITUDE: self.sensor_data.latitude,
|
||||
ATTR_LONGITUDE: self.sensor_data.longitude,
|
||||
}
|
||||
self._entry = entry
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> Mapping[str, Any]:
|
||||
"""Return entity specific state attributes."""
|
||||
attrs = {}
|
||||
|
||||
# Displaying the geography on the map relies upon putting the latitude/longitude
|
||||
# in the entity attributes with "latitude" and "longitude" as the keys.
|
||||
# Conversely, we can hide the location on the map by using other keys, like
|
||||
# "lati" and "long":
|
||||
if self._entry.options.get(CONF_SHOW_ON_MAP):
|
||||
attrs[ATTR_LATITUDE] = self.sensor_data.latitude
|
||||
attrs[ATTR_LONGITUDE] = self.sensor_data.longitude
|
||||
else:
|
||||
attrs["lati"] = self.sensor_data.latitude
|
||||
attrs["long"] = self.sensor_data.longitude
|
||||
return attrs
|
||||
|
||||
@property
|
||||
def sensor_data(self) -> SensorModel:
|
||||
|
@ -31,7 +31,7 @@ from homeassistant.helpers.selector import (
|
||||
SelectSelectorMode,
|
||||
)
|
||||
|
||||
from .const import CONF_SENSOR_INDICES, DOMAIN, LOGGER
|
||||
from .const import CONF_SENSOR_INDICES, CONF_SHOW_ON_MAP, DOMAIN, LOGGER
|
||||
|
||||
CONF_DISTANCE = "distance"
|
||||
CONF_NEARBY_SENSOR_OPTIONS = "nearby_sensor_options"
|
||||
@ -318,6 +318,22 @@ class PurpleAirOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
self._flow_data: dict[str, Any] = {}
|
||||
self.config_entry = config_entry
|
||||
|
||||
@property
|
||||
def settings_schema(self) -> vol.Schema:
|
||||
"""Return the settings schema."""
|
||||
return vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_SHOW_ON_MAP,
|
||||
description={
|
||||
"suggested_value": self.config_entry.options.get(
|
||||
CONF_SHOW_ON_MAP
|
||||
)
|
||||
},
|
||||
): bool
|
||||
}
|
||||
)
|
||||
|
||||
async def async_step_add_sensor(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
@ -352,7 +368,7 @@ class PurpleAirOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
async def async_step_choose_sensor(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Handle the selection of a sensor."""
|
||||
"""Choose a sensor."""
|
||||
if user_input is None:
|
||||
options = self._flow_data.pop(CONF_NEARBY_SENSOR_OPTIONS)
|
||||
return self.async_show_form(
|
||||
@ -375,13 +391,13 @@ class PurpleAirOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Manage the options."""
|
||||
return self.async_show_menu(
|
||||
step_id="init",
|
||||
menu_options=["add_sensor", "remove_sensor"],
|
||||
menu_options=["add_sensor", "remove_sensor", "settings"],
|
||||
)
|
||||
|
||||
async def async_step_remove_sensor(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Add a sensor."""
|
||||
"""Remove a sensor."""
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
step_id="remove_sensor",
|
||||
@ -437,3 +453,15 @@ class PurpleAirOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
options[CONF_SENSOR_INDICES].remove(removed_sensor_index)
|
||||
|
||||
return self.async_create_entry(data=options)
|
||||
|
||||
async def async_step_settings(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Manage settings."""
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
step_id="settings", data_schema=self.settings_schema
|
||||
)
|
||||
|
||||
options = deepcopy({**self.config_entry.options})
|
||||
return self.async_create_entry(data=options | user_input)
|
||||
|
@ -7,3 +7,4 @@ LOGGER = logging.getLogger(__package__)
|
||||
|
||||
CONF_READ_KEY = "read_key"
|
||||
CONF_SENSOR_INDICES = "sensor_indices"
|
||||
CONF_SHOW_ON_MAP = "show_on_map"
|
||||
|
@ -79,7 +79,8 @@
|
||||
"init": {
|
||||
"menu_options": {
|
||||
"add_sensor": "Add sensor",
|
||||
"remove_sensor": "Remove sensor"
|
||||
"remove_sensor": "Remove sensor",
|
||||
"settings": "Settings"
|
||||
}
|
||||
},
|
||||
"remove_sensor": {
|
||||
@ -90,6 +91,12 @@
|
||||
"data_description": {
|
||||
"sensor_device_id": "The sensor to remove"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"data": {
|
||||
"show_on_map": "Show configured sensor locations on the map"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
|
@ -302,3 +302,29 @@ async def test_options_remove_sensor(
|
||||
# Unload to make sure the update does not run after the
|
||||
# mock is removed.
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_options_settings(
|
||||
hass: HomeAssistant, config_entry, setup_config_entry
|
||||
) -> None:
|
||||
"""Test setting settings via the options flow."""
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.MENU
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={"next_step_id": "settings"}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "settings"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={"show_on_map": True}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
"sensor_indices": [TEST_SENSOR_INDEX1],
|
||||
"show_on_map": True,
|
||||
}
|
||||
|
||||
assert config_entry.options["show_on_map"] is True
|
||||
|
Loading…
x
Reference in New Issue
Block a user