From 5d07dd2c424a1e500be79a7258c6adb2d76ea0e2 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 22 Apr 2025 16:18:23 +0200 Subject: [PATCH] Add country to Supervisor info (#5826) Similar to timezone also add country information to the Supervisor info. This is useful to set country specific configurations such as Wireless radio regulatory setting. This is also useful for add-ons which need country information but only have hassio API access. --- supervisor/api/supervisor.py | 6 ++++++ supervisor/config.py | 15 +++++++++++++++ supervisor/const.py | 1 + supervisor/validate.py | 2 ++ tests/api/test_supervisor.py | 15 +++++++++++++++ 5 files changed, 39 insertions(+) diff --git a/supervisor/api/supervisor.py b/supervisor/api/supervisor.py index c17037e1f..294451507 100644 --- a/supervisor/api/supervisor.py +++ b/supervisor/api/supervisor.py @@ -17,6 +17,7 @@ from ..const import ( ATTR_BLK_WRITE, ATTR_CHANNEL, ATTR_CONTENT_TRUST, + ATTR_COUNTRY, ATTR_CPU_PERCENT, ATTR_DEBUG, ATTR_DEBUG_BLOCK, @@ -76,6 +77,7 @@ SCHEMA_OPTIONS = vol.Schema( vol.Optional(ATTR_FORCE_SECURITY): vol.Boolean(), vol.Optional(ATTR_AUTO_UPDATE): vol.Boolean(), vol.Optional(ATTR_DETECT_BLOCKING_IO): vol.Coerce(DetectBlockingIO), + vol.Optional(ATTR_COUNTRY): str, } ) @@ -109,6 +111,7 @@ class APISupervisor(CoreSysAttributes): ATTR_DIAGNOSTICS: self.sys_config.diagnostics, ATTR_AUTO_UPDATE: self.sys_updater.auto_update, ATTR_DETECT_BLOCKING_IO: blockbuster_enabled(), + ATTR_COUNTRY: self.sys_config.country, # Depricated ATTR_WAIT_BOOT: self.sys_config.wait_boot, ATTR_ADDONS: [ @@ -147,6 +150,9 @@ class APISupervisor(CoreSysAttributes): if ATTR_CHANNEL in body: self.sys_updater.channel = body[ATTR_CHANNEL] + if ATTR_COUNTRY in body: + self.sys_config.country = body[ATTR_COUNTRY] + if ATTR_DEBUG in body: self.sys_config.debug = body[ATTR_DEBUG] diff --git a/supervisor/config.py b/supervisor/config.py index ac6ee1a4b..ee6433224 100644 --- a/supervisor/config.py +++ b/supervisor/config.py @@ -10,6 +10,7 @@ from awesomeversion import AwesomeVersion from .const import ( ATTR_ADDONS_CUSTOM_LIST, + ATTR_COUNTRY, ATTR_DEBUG, ATTR_DEBUG_BLOCK, ATTR_DETECT_BLOCKING_IO, @@ -93,6 +94,20 @@ class CoreConfig(FileConfiguration): None, get_time_zone, value ) + @property + def country(self) -> str | None: + """Return supervisor country. + + The format follows what Home Assistant Core provides, which today is + ISO 3166-1 alpha-2. + """ + return self._data.get(ATTR_COUNTRY) + + @country.setter + def country(self, value: str | None) -> None: + """Set supervisor country.""" + self._data[ATTR_COUNTRY] = value + @property def version(self) -> AwesomeVersion: """Return supervisor version.""" diff --git a/supervisor/const.py b/supervisor/const.py index 5769b63c4..13504d80b 100644 --- a/supervisor/const.py +++ b/supervisor/const.py @@ -140,6 +140,7 @@ ATTR_CONNECTIONS = "connections" ATTR_CONTAINERS = "containers" ATTR_CONTENT = "content" ATTR_CONTENT_TRUST = "content_trust" +ATTR_COUNTRY = "country" ATTR_CPE = "cpe" ATTR_CPU_PERCENT = "cpu_percent" ATTR_CRYPTO = "crypto" diff --git a/supervisor/validate.py b/supervisor/validate.py index 0bfcf16b7..bfbfa79d4 100644 --- a/supervisor/validate.py +++ b/supervisor/validate.py @@ -13,6 +13,7 @@ from .const import ( ATTR_CHANNEL, ATTR_CLI, ATTR_CONTENT_TRUST, + ATTR_COUNTRY, ATTR_DEBUG, ATTR_DEBUG_BLOCK, ATTR_DETECT_BLOCKING_IO, @@ -164,6 +165,7 @@ SCHEMA_SUPERVISOR_CONFIG = vol.Schema( vol.Optional(ATTR_DEBUG_BLOCK, default=False): vol.Boolean(), vol.Optional(ATTR_DIAGNOSTICS, default=None): vol.Maybe(vol.Boolean()), vol.Optional(ATTR_DETECT_BLOCKING_IO, default=False): vol.Boolean(), + vol.Optional(ATTR_COUNTRY): str, }, extra=vol.REMOVE_EXTRA, ) diff --git a/tests/api/test_supervisor.py b/tests/api/test_supervisor.py index b2a5634fa..064c2c658 100644 --- a/tests/api/test_supervisor.py +++ b/tests/api/test_supervisor.py @@ -252,6 +252,21 @@ async def test_api_supervisor_options_timezone( assert coresys.timezone == "Europe/Zurich" +async def test_api_supervisor_options_country(api_client: TestClient, coresys: CoreSys): + """Test setting supervisor country via API.""" + assert coresys.config.country is None + + resp = await api_client.post("/supervisor/options", json={"country": "CH"}) + assert resp.status == 200 + + assert coresys.config.country == "CH" + + resp = await api_client.get("/supervisor/info") + assert resp.status == 200 + body = await resp.json() + assert body["data"]["country"] == "CH" + + @pytest.mark.parametrize( ("blockbuster", "option_value", "config_value"), [("no_blockbuster", "on", False), ("no_blockbuster", "on_at_startup", True)],