Add currency core configuration (#53541)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
514d97f144
commit
1968b95829
9 changed files with 210 additions and 2 deletions
|
@ -43,6 +43,7 @@ from homeassistant.helpers.system_info import async_get_system_info
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_BASE_URL = "base_url"
|
||||
ATTR_CURRENCY = "currency"
|
||||
ATTR_EXTERNAL_URL = "external_url"
|
||||
ATTR_INTERNAL_URL = "internal_url"
|
||||
ATTR_LOCATION_NAME = "location_name"
|
||||
|
@ -195,6 +196,7 @@ class APIDiscoveryView(HomeAssistantView):
|
|||
# always needs authentication
|
||||
ATTR_REQUIRES_API_PASSWORD: True,
|
||||
ATTR_VERSION: __version__,
|
||||
ATTR_CURRENCY: None,
|
||||
}
|
||||
|
||||
with suppress(NoURLAvailableError):
|
||||
|
|
|
@ -46,6 +46,7 @@ class CheckConfigView(HomeAssistantView):
|
|||
vol.Optional("time_zone"): cv.time_zone,
|
||||
vol.Optional("external_url"): vol.Any(cv.url, None),
|
||||
vol.Optional("internal_url"): vol.Any(cv.url, None),
|
||||
vol.Optional("currency"): cv.currency,
|
||||
}
|
||||
)
|
||||
async def websocket_update_config(hass, connection, msg):
|
||||
|
|
|
@ -28,6 +28,7 @@ from homeassistant.const import (
|
|||
CONF_ALLOWLIST_EXTERNAL_URLS,
|
||||
CONF_AUTH_MFA_MODULES,
|
||||
CONF_AUTH_PROVIDERS,
|
||||
CONF_CURRENCY,
|
||||
CONF_CUSTOMIZE,
|
||||
CONF_CUSTOMIZE_DOMAIN,
|
||||
CONF_CUSTOMIZE_GLOB,
|
||||
|
@ -238,6 +239,7 @@ CORE_CONFIG_SCHEMA = CUSTOMIZE_CONFIG_SCHEMA.extend(
|
|||
# pylint: disable=no-value-for-parameter
|
||||
vol.Optional(CONF_MEDIA_DIRS): cv.schema_with_slug_keys(vol.IsDir()),
|
||||
vol.Optional(CONF_LEGACY_TEMPLATES): cv.boolean,
|
||||
vol.Optional(CONF_CURRENCY): cv.currency,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -520,6 +522,7 @@ async def async_process_ha_core_config(hass: HomeAssistant, config: dict) -> Non
|
|||
CONF_UNIT_SYSTEM,
|
||||
CONF_EXTERNAL_URL,
|
||||
CONF_INTERNAL_URL,
|
||||
CONF_CURRENCY,
|
||||
)
|
||||
):
|
||||
hac.config_source = SOURCE_YAML
|
||||
|
@ -533,6 +536,7 @@ async def async_process_ha_core_config(hass: HomeAssistant, config: dict) -> Non
|
|||
(CONF_EXTERNAL_URL, "external_url"),
|
||||
(CONF_MEDIA_DIRS, "media_dirs"),
|
||||
(CONF_LEGACY_TEMPLATES, "legacy_templates"),
|
||||
(CONF_CURRENCY, "currency"),
|
||||
):
|
||||
if key in config:
|
||||
setattr(hac, attr, config[key])
|
||||
|
|
|
@ -1545,6 +1545,7 @@ class Config:
|
|||
self.units: UnitSystem = METRIC_SYSTEM
|
||||
self.internal_url: str | None = None
|
||||
self.external_url: str | None = None
|
||||
self.currency: str = "EUR"
|
||||
|
||||
self.config_source: str = "default"
|
||||
|
||||
|
@ -1650,6 +1651,7 @@ class Config:
|
|||
"state": self.hass.state.value,
|
||||
"external_url": self.external_url,
|
||||
"internal_url": self.internal_url,
|
||||
"currency": self.currency,
|
||||
}
|
||||
|
||||
def set_time_zone(self, time_zone_str: str) -> None:
|
||||
|
@ -1676,6 +1678,7 @@ class Config:
|
|||
# pylint: disable=dangerous-default-value # _UNDEFs not modified
|
||||
external_url: str | dict | None = _UNDEF,
|
||||
internal_url: str | dict | None = _UNDEF,
|
||||
currency: str | None = None,
|
||||
) -> None:
|
||||
"""Update the configuration from a dictionary."""
|
||||
self.config_source = source
|
||||
|
@ -1698,6 +1701,8 @@ class Config:
|
|||
self.external_url = cast(Optional[str], external_url)
|
||||
if internal_url is not _UNDEF:
|
||||
self.internal_url = cast(Optional[str], internal_url)
|
||||
if currency is not None:
|
||||
self.currency = currency
|
||||
|
||||
async def async_update(self, **kwargs: Any) -> None:
|
||||
"""Update the configuration from a dictionary."""
|
||||
|
@ -1723,6 +1728,7 @@ class Config:
|
|||
time_zone=data.get("time_zone"),
|
||||
external_url=data.get("external_url", _UNDEF),
|
||||
internal_url=data.get("internal_url", _UNDEF),
|
||||
currency=data.get("currency"),
|
||||
)
|
||||
|
||||
async def async_store(self) -> None:
|
||||
|
@ -1736,6 +1742,7 @@ class Config:
|
|||
"time_zone": self.time_zone,
|
||||
"external_url": self.external_url,
|
||||
"internal_url": self.internal_url,
|
||||
"currency": self.currency,
|
||||
}
|
||||
|
||||
store = self.hass.helpers.storage.Store(
|
||||
|
|
|
@ -1269,3 +1269,167 @@ ACTION_TYPE_SCHEMAS: dict[str, Callable[[Any], dict]] = {
|
|||
SCRIPT_ACTION_WAIT_FOR_TRIGGER: _SCRIPT_WAIT_FOR_TRIGGER_SCHEMA,
|
||||
SCRIPT_ACTION_VARIABLES: _SCRIPT_SET_SCHEMA,
|
||||
}
|
||||
|
||||
|
||||
# Validate currencies adopted by countries
|
||||
currency = vol.In(
|
||||
{
|
||||
"AED",
|
||||
"AFN",
|
||||
"ALL",
|
||||
"AMD",
|
||||
"ANG",
|
||||
"AOA",
|
||||
"ARS",
|
||||
"AUD",
|
||||
"AWG",
|
||||
"AZN",
|
||||
"BAM",
|
||||
"BBD",
|
||||
"BDT",
|
||||
"BGN",
|
||||
"BHD",
|
||||
"BIF",
|
||||
"BMD",
|
||||
"BND",
|
||||
"BOB",
|
||||
"BRL",
|
||||
"BSD",
|
||||
"BTN",
|
||||
"BWP",
|
||||
"BYR",
|
||||
"BZD",
|
||||
"CAD",
|
||||
"CDF",
|
||||
"CHF",
|
||||
"CLP",
|
||||
"CNY",
|
||||
"COP",
|
||||
"CRC",
|
||||
"CUP",
|
||||
"CVE",
|
||||
"CZK",
|
||||
"DJF",
|
||||
"DKK",
|
||||
"DOP",
|
||||
"DZD",
|
||||
"EGP",
|
||||
"ERN",
|
||||
"ETB",
|
||||
"EUR",
|
||||
"FJD",
|
||||
"FKP",
|
||||
"GBP",
|
||||
"GEL",
|
||||
"GHS",
|
||||
"GIP",
|
||||
"GMD",
|
||||
"GNF",
|
||||
"GTQ",
|
||||
"GYD",
|
||||
"HKD",
|
||||
"HNL",
|
||||
"HRK",
|
||||
"HTG",
|
||||
"HUF",
|
||||
"IDR",
|
||||
"ILS",
|
||||
"INR",
|
||||
"IQD",
|
||||
"IRR",
|
||||
"ISK",
|
||||
"JMD",
|
||||
"JOD",
|
||||
"JPY",
|
||||
"KES",
|
||||
"KGS",
|
||||
"KHR",
|
||||
"KMF",
|
||||
"KPW",
|
||||
"KRW",
|
||||
"KWD",
|
||||
"KYD",
|
||||
"KZT",
|
||||
"LAK",
|
||||
"LBP",
|
||||
"LKR",
|
||||
"LRD",
|
||||
"LSL",
|
||||
"LTL",
|
||||
"LYD",
|
||||
"MAD",
|
||||
"MDL",
|
||||
"MGA",
|
||||
"MKD",
|
||||
"MMK",
|
||||
"MNT",
|
||||
"MOP",
|
||||
"MRO",
|
||||
"MUR",
|
||||
"MVR",
|
||||
"MWK",
|
||||
"MXN",
|
||||
"MYR",
|
||||
"MZN",
|
||||
"NAD",
|
||||
"NGN",
|
||||
"NIO",
|
||||
"NOK",
|
||||
"NPR",
|
||||
"NZD",
|
||||
"OMR",
|
||||
"PAB",
|
||||
"PEN",
|
||||
"PGK",
|
||||
"PHP",
|
||||
"PKR",
|
||||
"PLN",
|
||||
"PYG",
|
||||
"QAR",
|
||||
"RON",
|
||||
"RSD",
|
||||
"RUB",
|
||||
"RWF",
|
||||
"SAR",
|
||||
"SBD",
|
||||
"SCR",
|
||||
"SDG",
|
||||
"SEK",
|
||||
"SGD",
|
||||
"SHP",
|
||||
"SLL",
|
||||
"SOS",
|
||||
"SRD",
|
||||
"SSP",
|
||||
"STD",
|
||||
"SYP",
|
||||
"SZL",
|
||||
"THB",
|
||||
"TJS",
|
||||
"TMT",
|
||||
"TND",
|
||||
"TOP",
|
||||
"TRY",
|
||||
"TTD",
|
||||
"TWD",
|
||||
"TZS",
|
||||
"UAH",
|
||||
"UGX",
|
||||
"USD",
|
||||
"UYU",
|
||||
"UZS",
|
||||
"VEF",
|
||||
"VND",
|
||||
"VUV",
|
||||
"WST",
|
||||
"XAF",
|
||||
"XCD",
|
||||
"XOF",
|
||||
"XPF",
|
||||
"YER",
|
||||
"ZAR",
|
||||
"ZMK",
|
||||
"ZWL",
|
||||
},
|
||||
msg="invalid ISO 4217 formatted currency",
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""Test hassbian config."""
|
||||
"""Test core config."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
@ -60,6 +60,7 @@ async def test_websocket_core_update(hass, client):
|
|||
assert hass.config.time_zone != "America/New_York"
|
||||
assert hass.config.external_url != "https://www.example.com"
|
||||
assert hass.config.internal_url != "http://example.com"
|
||||
assert hass.config.currency == "EUR"
|
||||
|
||||
with patch("homeassistant.util.dt.set_default_time_zone") as mock_set_tz:
|
||||
await client.send_json(
|
||||
|
@ -74,6 +75,7 @@ async def test_websocket_core_update(hass, client):
|
|||
"time_zone": "America/New_York",
|
||||
"external_url": "https://www.example.com",
|
||||
"internal_url": "http://example.local",
|
||||
"currency": "USD",
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -89,6 +91,7 @@ async def test_websocket_core_update(hass, client):
|
|||
assert hass.config.units.name == CONF_UNIT_SYSTEM_IMPERIAL
|
||||
assert hass.config.external_url == "https://www.example.com"
|
||||
assert hass.config.internal_url == "http://example.local"
|
||||
assert hass.config.currency == "USD"
|
||||
|
||||
assert len(mock_set_tz.mock_calls) == 1
|
||||
assert mock_set_tz.mock_calls[0][1][0] == dt_util.get_time_zone("America/New_York")
|
||||
|
|
|
@ -1085,3 +1085,18 @@ def test_whitespace():
|
|||
|
||||
for value in (" ", " "):
|
||||
assert schema(value)
|
||||
|
||||
|
||||
def test_currency():
|
||||
"""Test currency validator."""
|
||||
schema = vol.Schema(cv.currency)
|
||||
|
||||
for value in (
|
||||
None,
|
||||
"BTC",
|
||||
):
|
||||
with pytest.raises(vol.MultipleInvalid):
|
||||
schema(value)
|
||||
|
||||
for value in ("EUR", "USD"):
|
||||
assert schema(value)
|
||||
|
|
|
@ -193,6 +193,7 @@ def test_core_config_schema():
|
|||
{"longitude": -181},
|
||||
{"external_url": "not an url"},
|
||||
{"internal_url": "not an url"},
|
||||
{"currency", 100},
|
||||
{"customize": "bla"},
|
||||
{"customize": {"light.sensor": 100}},
|
||||
{"customize": {"entity_id": []}},
|
||||
|
@ -208,6 +209,7 @@ def test_core_config_schema():
|
|||
"external_url": "https://www.example.com",
|
||||
"internal_url": "http://example.local",
|
||||
CONF_UNIT_SYSTEM: CONF_UNIT_SYSTEM_METRIC,
|
||||
"currency": "USD",
|
||||
"customize": {"sensor.temperature": {"hidden": True}},
|
||||
}
|
||||
)
|
||||
|
@ -360,6 +362,7 @@ async def test_loading_configuration_from_storage(hass, hass_storage):
|
|||
"unit_system": "metric",
|
||||
"external_url": "https://www.example.com",
|
||||
"internal_url": "http://example.local",
|
||||
"currency": "EUR",
|
||||
},
|
||||
"key": "core.config",
|
||||
"version": 1,
|
||||
|
@ -376,6 +379,7 @@ async def test_loading_configuration_from_storage(hass, hass_storage):
|
|||
assert hass.config.time_zone == "Europe/Copenhagen"
|
||||
assert hass.config.external_url == "https://www.example.com"
|
||||
assert hass.config.internal_url == "http://example.local"
|
||||
assert hass.config.currency == "EUR"
|
||||
assert len(hass.config.allowlist_external_dirs) == 3
|
||||
assert "/etc" in hass.config.allowlist_external_dirs
|
||||
assert hass.config.config_source == SOURCE_STORAGE
|
||||
|
@ -423,6 +427,7 @@ async def test_updating_configuration(hass, hass_storage):
|
|||
"unit_system": "metric",
|
||||
"external_url": "https://www.example.com",
|
||||
"internal_url": "http://example.local",
|
||||
"currency": "BTC",
|
||||
},
|
||||
"key": "core.config",
|
||||
"version": 1,
|
||||
|
@ -431,12 +436,14 @@ async def test_updating_configuration(hass, hass_storage):
|
|||
await config_util.async_process_ha_core_config(
|
||||
hass, {"allowlist_external_dirs": "/etc"}
|
||||
)
|
||||
await hass.config.async_update(latitude=50)
|
||||
await hass.config.async_update(latitude=50, currency="USD")
|
||||
|
||||
new_core_data = copy.deepcopy(core_data)
|
||||
new_core_data["data"]["latitude"] = 50
|
||||
new_core_data["data"]["currency"] = "USD"
|
||||
assert hass_storage["core.config"] == new_core_data
|
||||
assert hass.config.latitude == 50
|
||||
assert hass.config.currency == "USD"
|
||||
|
||||
|
||||
async def test_override_stored_configuration(hass, hass_storage):
|
||||
|
@ -484,6 +491,7 @@ async def test_loading_configuration(hass):
|
|||
"internal_url": "http://example.local",
|
||||
"media_dirs": {"mymedia": "/usr"},
|
||||
"legacy_templates": True,
|
||||
"currency": "EUR",
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -501,6 +509,7 @@ async def test_loading_configuration(hass):
|
|||
assert hass.config.media_dirs == {"mymedia": "/usr"}
|
||||
assert hass.config.config_source == config_util.SOURCE_YAML
|
||||
assert hass.config.legacy_templates is True
|
||||
assert hass.config.currency == "EUR"
|
||||
|
||||
|
||||
async def test_loading_configuration_temperature_unit(hass):
|
||||
|
@ -528,6 +537,7 @@ async def test_loading_configuration_temperature_unit(hass):
|
|||
assert hass.config.external_url == "https://www.example.com"
|
||||
assert hass.config.internal_url == "http://example.local"
|
||||
assert hass.config.config_source == config_util.SOURCE_YAML
|
||||
assert hass.config.currency == "EUR"
|
||||
|
||||
|
||||
async def test_loading_configuration_default_media_dirs_docker(hass):
|
||||
|
|
|
@ -912,6 +912,7 @@ def test_config_defaults():
|
|||
assert config.media_dirs == {}
|
||||
assert config.safe_mode is False
|
||||
assert config.legacy_templates is False
|
||||
assert config.currency == "EUR"
|
||||
|
||||
|
||||
def test_config_path_with_file():
|
||||
|
@ -952,6 +953,7 @@ def test_config_as_dict():
|
|||
"state": "RUNNING",
|
||||
"external_url": None,
|
||||
"internal_url": None,
|
||||
"currency": "EUR",
|
||||
}
|
||||
|
||||
assert expected == config.as_dict()
|
||||
|
|
Loading…
Add table
Reference in a new issue