From 1ac4382dc53d91352d21874dcafeafab0f77132a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 21 Sep 2026 12:13:19 -0400 Subject: [PATCH] Correct Supervisor API types in the frontend (#54284) Compare the hassio and supervisor data modules with the Supervisor handlers that build the responses, and fix the mismatches. Add fields the API returns that were missing, including system_managed, boot_config, dns, host_uts, ingress_port, udev, usb and video. Correct two names that never matched the wire: services_role is services, and auto_uart is uart. Drop installed, which belongs to the store model rather than the app info payload, and drop repositories from the app list, which the list handler does not return. Mark the many fields the Supervisor can return as null, and replace the placeholder issue and suggestion string arrays in the resolution types with the objects the API sends. Claude-Session: https://claude.ai/code/session_01YDqKNfAAvMV7zJJNodsHfK Co-authored-by: Claude --- demo/src/stubs/hardware.ts | 1 + demo/src/stubs/hassio_supervisor.ts | 46 ++++++++--------- src/data/hardware.ts | 22 ++++----- src/data/hassio/addon.ts | 30 +++++++----- src/data/hassio/common.ts | 5 +- src/data/hassio/docker.ts | 10 ++-- src/data/hassio/hardware.ts | 1 + src/data/hassio/host.ts | 19 +++---- src/data/hassio/network.ts | 13 +++-- src/data/hassio/resolution.ts | 22 ++++++++- src/data/hassio/supervisor.ts | 49 ++++++++++++++----- src/data/network.ts | 9 ++-- src/data/supervisor/mounts.ts | 16 ++++-- src/data/supervisor/update.ts | 2 +- .../apps/app-view/info/supervisor-app-info.ts | 4 +- .../core/ha-config-system-navigation.ts | 6 +-- .../hardware/ha-config-hardware-overview.ts | 12 ++--- .../config/network/supervisor-hostname.ts | 2 +- .../repairs/dialog-system-information.ts | 4 +- .../config/storage/dialog-move-datadisk.ts | 4 +- 20 files changed, 174 insertions(+), 103 deletions(-) diff --git a/demo/src/stubs/hardware.ts b/demo/src/stubs/hardware.ts index a758285fed..a8b8394c2c 100644 --- a/demo/src/stubs/hardware.ts +++ b/demo/src/stubs/hardware.ts @@ -13,6 +13,7 @@ const HARDWARE_INFO: HardwareInfo = { hassio_board_id: "green", manufacturer: "homeassistant", model: "green", + revision: null, }, dongle: null, config_entries: [], diff --git a/demo/src/stubs/hassio_supervisor.ts b/demo/src/stubs/hassio_supervisor.ts index 919ab74a98..9200bcbf50 100644 --- a/demo/src/stubs/hassio_supervisor.ts +++ b/demo/src/stubs/hassio_supervisor.ts @@ -32,11 +32,11 @@ const DEMO_ADDONS: HassioAddonInfo[] = [ detached: false, homeassistant: "2025.7.0", icon: false, - installed: true, logo: false, repository: "d5369777", stage: "stable", state: "started", + system_managed: false, update_available: false, url: "https://github.com/music-assistant/home-assistant-addon", version: "2.6.3", @@ -53,11 +53,11 @@ const DEMO_ADDONS: HassioAddonInfo[] = [ detached: false, homeassistant: "2025.7.0", icon: false, - installed: true, logo: false, repository: "5c53de3b", stage: "stable", state: "started", + system_managed: false, update_available: false, url: "https://esphome.io/", version: "2025.7.3", @@ -114,13 +114,14 @@ const addonDetails = (addon: HassioAddonInfo): HassioAddonDetails => ({ audio_output: null, audio: false, auth_api: false, - auto_uart: false, auto_update: false, boot: "auto", + boot_config: "auto", changelog: false, devices: [], devicetree: false, discovery: [], + dns: [], docker_api: false, documentation: false, full_access: false, @@ -133,8 +134,10 @@ const addonDetails = (addon: HassioAddonInfo): HassioAddonDetails => ({ host_ipc: false, host_network: false, host_pid: false, + host_uts: false, ingress_entry: null, ingress_panel: false, + ingress_port: null, ingress_url: null, ingress: false, ip_address: "172.30.33.2", @@ -148,13 +151,16 @@ const addonDetails = (addon: HassioAddonInfo): HassioAddonDetails => ({ protected: true, rating: 6, schema: CONFIG_SCHEMAS[addon.slug] ?? null, - services_role: [], + services: [], signed: false, startup: "application", stdin: false, - system_managed: false, system_managed_config_entry: null, translations: {}, + uart: false, + udev: false, + usb: false, + video: false, watchdog: true, webui: null, }); @@ -181,11 +187,14 @@ const ADDON_STATS: HassioStats = { blk_read: 12300000, blk_write: 4500000, cpu_percent: 1.4, + cpu_system_usage: 1420000000000, + cpu_usage: 19800000000, memory_limit: 3900000000, memory_percent: 4.2, memory_usage: 163000000, network_rx: 8900000, network_tx: 2300000, + online_cpus: 4, }; export const mockHassioSupervisor = (hass: MockHomeAssistant) => { @@ -209,9 +218,13 @@ export const mockHassioSupervisor = (hass: MockHomeAssistant) => { wait_boot: 5, timezone: "Europe/Amsterdam", logging: "info", + auto_update: true, + country: "NL", debug: false, debug_block: false, + detect_blocking_io: false, diagnostics: true, + feature_flags: {}, addons: DEMO_ADDONS as any, addons_repositories: [ "https://github.com/music-assistant/home-assistant-addon", @@ -224,22 +237,6 @@ export const mockHassioSupervisor = (hass: MockHomeAssistant) => { if (msg.endpoint === "/addons") { const data: HassioAddonsInfo = { addons: DEMO_ADDONS, - repositories: [ - { - slug: "d5369777", - name: "Music Assistant", - source: "https://github.com/music-assistant/home-assistant-addon", - url: "https://github.com/music-assistant/home-assistant-addon", - maintainer: "Music Assistant", - }, - { - slug: "5c53de3b", - name: "ESPHome", - source: "https://github.com/esphome/home-assistant-addon", - url: "https://esphome.io/", - maintainer: "ESPHome", - }, - ], }; return data; } @@ -264,6 +261,7 @@ export const mockHassioSupervisor = (hass: MockHomeAssistant) => { hostname: "homeassistant", logging: "info", machine: "green", + machine_id: "0123456789abcdef0123456789abcdef", state: "running", operating_system: "Home Assistant OS 18.2", supervisor: "2026.07.1", @@ -301,6 +299,7 @@ export const mockHassioSupervisor = (hass: MockHomeAssistant) => { update_available: false, version: "18.2", version_latest: "18.2", + version_pending: null, data_disk: "Home Assistant Green (mmcblk0)", }; return data; @@ -334,8 +333,9 @@ export const mockHassioSupervisor = (hass: MockHomeAssistant) => { const data: NetworkInfo = { interfaces: [ { + connected: true, + mac: "aa:bb:cc:dd:ee:ff", primary: true, - privacy: false, interface: "eth0", enabled: true, type: "ethernet", @@ -354,6 +354,8 @@ export const mockHassioSupervisor = (hass: MockHomeAssistant) => { gateway: "172.30.32.1", interface: "hassio", }, + host_internet: true, + supervisor_internet: true, }; return data; } diff --git a/src/data/hardware.ts b/src/data/hardware.ts index accbf4d9ba..dea0be2b77 100644 --- a/src/data/hardware.ts +++ b/src/data/hardware.ts @@ -28,24 +28,24 @@ export interface HardwareInfo { export interface HardwareInfoEntry { board: HardwareInfoBoardInfo | null; dongle: HardwareInfoDongleInfo | null; - config_entries: string[]; - name: string; - url?: string; + config_entries: string[] | null; + name: string | null; + url: string | null; } export interface HardwareInfoBoardInfo { manufacturer: string; - model?: string; - revision?: string; - hassio_board_id?: string; + model: string | null; + revision: string | null; + hassio_board_id: string | null; } export interface HardwareInfoDongleInfo { - manufacturer: string; - description: string; - pid?: string; - vid?: string; - serial_number?: string; + manufacturer: string | null; + description: string | null; + pid: string; + vid: string; + serial_number: string | null; } export interface SystemStatusStreamMessage { diff --git a/src/data/hassio/addon.ts b/src/data/hassio/addon.ts index 749410ea47..399e98065a 100644 --- a/src/data/hassio/addon.ts +++ b/src/data/hassio/addon.ts @@ -17,11 +17,12 @@ export type AddonCapability = Exclude< >; export type AddonStage = "stable" | "experimental" | "deprecated"; export type AddonAppArmour = "disable" | "default" | "profile"; -export type AddonRole = "default" | "homeassistant" | "manager" | "admin"; +export type AddonRole = + "default" | "homeassistant" | "backup" | "manager" | "admin"; export type AddonStartup = "initialize" | "system" | "services" | "application" | "once"; export type AddonState = - "startup" | "started" | "stopped" | "unknown" | "error" | null; + "startup" | "started" | "stopped" | "unknown" | "error"; export type AddonRepository = "core" | "local" | string; interface AddonFieldTranslation { @@ -41,15 +42,15 @@ export interface HassioAddonInfo { build: boolean; description: string; detached: boolean; - homeassistant: string; + homeassistant: string | null; icon: boolean; - installed: boolean; logo: boolean; name: string; repository: AddonRepository; slug: string; stage: AddonStage; state: AddonState; + system_managed: boolean; update_available: boolean; url: string | null; version_latest: string; @@ -63,13 +64,14 @@ export interface HassioAddonDetails extends HassioAddonInfo { audio_output: null | string; audio: boolean; auth_api: boolean; - auto_uart: boolean; auto_update: boolean; boot: "auto" | "manual"; + boot_config: "auto" | "manual" | "manual_only"; changelog: boolean; devices: string[]; devicetree: boolean; discovery: string[]; + dns: string[]; docker_api: boolean; documentation: boolean; full_access: boolean; @@ -82,8 +84,10 @@ export interface HassioAddonDetails extends HassioAddonInfo { host_ipc: boolean; host_network: boolean; host_pid: boolean; + host_uts: boolean; ingress_entry: null | string; - ingress_panel: boolean; + ingress_panel: boolean | null; + ingress_port: number | null; ingress_url: null | string; ingress: boolean; ip_address: string; @@ -91,27 +95,29 @@ export interface HassioAddonDetails extends HassioAddonInfo { long_description: null | string; machine: any; network_description: null | Record; - network: null | Record; + network: null | Record; options: Record; privileged: any; protected: boolean; rating: number; schema: HaFormSchema[] | null; - services_role: string[]; + services: string[]; signed: boolean; slug: string; startup: AddonStartup; stdin: boolean; - system_managed: boolean; system_managed_config_entry: string | null; translations: Record; - watchdog: null | boolean; + uart: boolean; + udev: boolean; + usb: boolean; + video: boolean; + watchdog: boolean; webui: null | string; } export interface HassioAddonsInfo { addons: HassioAddonInfo[]; - repositories: HassioAddonRepository[]; } export interface HassioAddonSetSecurityParams { @@ -201,7 +207,7 @@ export const validateHassioAddonOption = async ( callWS: CallWS, slug: string, data?: any -): Promise<{ message: string; valid: boolean }> => { +): Promise<{ message: string; valid: boolean; pwned: boolean | null }> => { return callWS({ type: "supervisor/api", endpoint: `/addons/${slug}/options/validate`, diff --git a/src/data/hassio/common.ts b/src/data/hassio/common.ts index 0c8961c975..1c27c12e9f 100644 --- a/src/data/hassio/common.ts +++ b/src/data/hassio/common.ts @@ -13,12 +13,15 @@ export interface HassioResponse { export interface HassioStats { blk_read: number; blk_write: number; - cpu_percent: number; + cpu_percent: number | null; + cpu_system_usage: number; + cpu_usage: number; memory_limit: number; memory_percent: number; memory_usage: number; network_rx: number; network_tx: number; + online_cpus: number; } export const extractApiErrorMessage = (error: any): string => diff --git a/src/data/hassio/docker.ts b/src/data/hassio/docker.ts index d4cbf28573..6ed0545076 100644 --- a/src/data/hassio/docker.ts +++ b/src/data/hassio/docker.ts @@ -1,13 +1,15 @@ import type { HomeAssistant } from "../../types"; -type HassioDockerRegistries = Record< +type HassioDockerRegistries = Record; + +type HassioDockerRegistryCredentials = Record< string, - { username: string; password?: string } + { username: string; password: string } >; export const fetchHassioDockerRegistries = async ( hass: HomeAssistant -): Promise => +): Promise<{ registries: HassioDockerRegistries }> => hass.callWS({ type: "supervisor/api", endpoint: `/docker/registries`, @@ -16,7 +18,7 @@ export const fetchHassioDockerRegistries = async ( export const addHassioDockerRegistry = async ( hass: HomeAssistant, - data: HassioDockerRegistries + data: HassioDockerRegistryCredentials ) => { await hass.callWS({ type: "supervisor/api", diff --git a/src/data/hassio/hardware.ts b/src/data/hassio/hardware.ts index ca502e8b86..0d0be60bef 100644 --- a/src/data/hassio/hardware.ts +++ b/src/data/hassio/hardware.ts @@ -15,6 +15,7 @@ interface HassioHardwareAudioList { export interface HardwareDevice { attributes: Record; by_id: null | string; + children: string[]; dev_path: string; name: string; subsystem: string; diff --git a/src/data/hassio/host.ts b/src/data/hassio/host.ts index 6ac52353af..6283defb0a 100644 --- a/src/data/hassio/host.ts +++ b/src/data/hassio/host.ts @@ -2,19 +2,19 @@ import type { HomeAssistant } from "../../types"; export interface HassioHostInfo { agent_version: string; - chassis: string; - cpe: string; - deployment: string; + chassis: string | null; + cpe: string | null; + deployment: string | null; disk_life_time: number | null; disk_free: number; disk_total: number; disk_used: number; features: string[]; - hostname: string; - kernel: string; - operating_system: string; - boot_timestamp: number; - startup_time: number; + hostname: string | null; + kernel: string | null; + operating_system: string | null; + boot_timestamp: number | null; + startup_time: number | null; } export interface HassioHassOSInfo { @@ -23,7 +23,8 @@ export interface HassioHassOSInfo { update_available: boolean; version_latest: string | null; version: string | null; - data_disk: string; + version_pending: string | null; + data_disk: string | null; } export interface Datadisk { diff --git a/src/data/hassio/network.ts b/src/data/hassio/network.ts index a4c37e0bce..a6838ff7fb 100644 --- a/src/data/hassio/network.ts +++ b/src/data/hassio/network.ts @@ -5,15 +5,18 @@ interface IpConfiguration { gateway: string | null; method: "disabled" | "static" | "auto"; nameservers: string[]; + ready: boolean | null; + route_metric: number | null; } export interface NetworkInterface { + connected: boolean; + mac: string; primary: boolean; - privacy: boolean; interface: string; enabled: boolean; - ipv4?: Partial; - ipv6?: Partial; + ipv4?: Partial | null; + ipv6?: Partial | null; type: "ethernet" | "wireless" | "vlan"; wifi?: Partial | null; } @@ -41,13 +44,15 @@ export interface WifiConfiguration { mode: "infrastructure" | "mesh" | "adhoc" | "ap"; auth: "open" | "wep" | "wpa-psk"; ssid: string; - signal: number; + signal: number | null; psk?: string; } export interface NetworkInfo { interfaces: NetworkInterface[]; docker: DockerNetwork; + host_internet: boolean | null; + supervisor_internet: boolean; } export const fetchNetworkInfo = async ( diff --git a/src/data/hassio/resolution.ts b/src/data/hassio/resolution.ts index 383c0ba10d..e1e4790fa0 100644 --- a/src/data/hassio/resolution.ts +++ b/src/data/hassio/resolution.ts @@ -1,10 +1,28 @@ import type { HomeAssistant, TranslationDict } from "../../types"; +export interface ResolutionIssue { + type: string; + context: string; + reference: string | null; + reference_extra: Record | null; + uuid: string; +} + +export interface ResolutionSuggestion extends ResolutionIssue { + auto: boolean; +} + +export interface ResolutionCheck { + enabled: boolean; + slug: string; +} + export interface HassioResolution { unsupported: (keyof TranslationDict["ui"]["dialogs"]["unsupported"]["reasons"])[]; unhealthy: (keyof TranslationDict["ui"]["dialogs"]["unhealthy"]["reasons"])[]; - issues: string[]; - suggestions: string[]; + issues: ResolutionIssue[]; + suggestions: ResolutionSuggestion[]; + checks: ResolutionCheck[]; } export const fetchHassioResolution = async ( diff --git a/src/data/hassio/supervisor.ts b/src/data/hassio/supervisor.ts index e4d3d874b1..a52b52723f 100644 --- a/src/data/hassio/supervisor.ts +++ b/src/data/hassio/supervisor.ts @@ -1,37 +1,59 @@ import type { HomeAssistant, PanelInfo } from "../../types"; import type { SupervisorArch } from "../supervisor/supervisor"; +import type { AddonState } from "./addon"; import { supervisorUrl, type HassioResponse } from "./common"; export interface HassioHomeAssistantInfo { - arch: SupervisorArch; + arch: SupervisorArch | null; audio_input: string | null; audio_output: string | null; + backups_exclude_database: boolean; boot: boolean; + duplicate_log_file: boolean; image: string; ip_address: string; - machine: string; + machine: string | null; port: number; ssl: boolean; update_available: boolean; - version_latest: string; - version: string; - wait_boot: number; + version_latest: string | null; + version: string | null; watchdog: boolean; } +export interface HassioSupervisorInfoAddon { + icon: boolean; + name: string; + repository: string; + slug: string; + state: AddonState; + update_available: boolean; + version: string; + version_latest: string; +} + +export interface HassioSupervisorInfoRepository { + name: string; + slug: string; +} + export interface HassioSupervisorInfo { - addons: string[]; - addons_repositories: string[]; + addons: HassioSupervisorInfoAddon[]; + addons_repositories: HassioSupervisorInfoRepository[]; arch: SupervisorArch; + auto_update: boolean; channel: string; + country: string | null; debug: boolean; debug_block: boolean; + detect_blocking_io: boolean; diagnostics: boolean | null; + feature_flags: Record; healthy: boolean; ip_address: string; logging: string; supported: boolean; - timezone: string; + timezone: string | null; update_available: boolean; version: string; version_latest: string; @@ -43,11 +65,12 @@ export interface HassioInfo { channel: string; docker: string; features: string[]; - hassos: null; - homeassistant: string; - hostname: string; + hassos: string | null; + homeassistant: string | null; + hostname: string | null; logging: string; - machine: string; + machine: string | null; + machine_id: string | null; state: | "initialize" | "setup" @@ -57,7 +80,7 @@ export interface HassioInfo { | "shutdown" | "stopping" | "close"; - operating_system: string; + operating_system: string | null; supervisor: string; supported: boolean; supported_arch: SupervisorArch[]; diff --git a/src/data/network.ts b/src/data/network.ts index 55a96c2410..8a4b823ef2 100644 --- a/src/data/network.ts +++ b/src/data/network.ts @@ -14,6 +14,7 @@ export interface IPv4ConfiguredAddress { export interface Adapter { name: string; + index: number | null; enabled: boolean; auto: boolean; default: boolean; @@ -27,9 +28,9 @@ export interface NetworkConfig { } export interface NetworkUrls { - internal: string; - external: string; - cloud: string; + internal: string | null; + external: string | null; + cloud: string | null; } export const getNetworkConfig = (hass: HomeAssistant) => @@ -41,7 +42,7 @@ export const setNetworkConfig = ( hass: HomeAssistant, configured_adapters: string[] ) => - hass.callWS({ + hass.callWS<{ configured_adapters: string[] }>({ type: "network/configure", config: { configured_adapters: configured_adapters, diff --git a/src/data/supervisor/mounts.ts b/src/data/supervisor/mounts.ts index b8c5ebeb9b..25cb7157ed 100644 --- a/src/data/supervisor/mounts.ts +++ b/src/data/supervisor/mounts.ts @@ -14,8 +14,12 @@ export enum SupervisorMountUsage { export enum SupervisorMountState { ACTIVE = "active", + ACTIVATING = "activating", + DEACTIVATING = "deactivating", FAILED = "failed", - UNKNOWN = "unknown", + INACTIVE = "inactive", + MAINTENANCE = "maintenance", + RELOADING = "reloading", } interface MountOptions { @@ -26,14 +30,16 @@ export type CIFSVersion = "auto" | "1.0" | "2.0"; interface SupervisorMountBase { name: string; - usage: SupervisorMountUsage; + usage: SupervisorMountUsage | null; type: SupervisorMountType; + read_only: boolean; server: string; - port: number; + port?: number; } export interface SupervisorMountResponse extends SupervisorMountBase { state: SupervisorMountState | null; + user_path: string | null; } export interface SupervisorNFSMount extends SupervisorMountResponse { @@ -44,7 +50,7 @@ export interface SupervisorNFSMount extends SupervisorMountResponse { export interface SupervisorCIFSMount extends SupervisorMountResponse { type: SupervisorMountType.CIFS; share: string; - version?: CIFSVersion; + version?: CIFSVersion | null; } export type SupervisorMount = SupervisorNFSMount | SupervisorCIFSMount; @@ -54,7 +60,7 @@ export type SupervisorNFSMountRequestParams = SupervisorNFSMount; export interface SupervisorCIFSMountRequestParams extends SupervisorCIFSMount { username?: string; password?: string; - version?: CIFSVersion; + version?: CIFSVersion | null; } export type SupervisorMountRequestParams = diff --git a/src/data/supervisor/update.ts b/src/data/supervisor/update.ts index 51986b36c5..b52c4b5d02 100644 --- a/src/data/supervisor/update.ts +++ b/src/data/supervisor/update.ts @@ -2,7 +2,7 @@ import type { HomeAssistant } from "../../types"; export interface SupervisorUpdateConfig { add_on_backup_before_update: boolean; - add_on_backup_retain_copies?: number; + add_on_backup_retain_copies: number; core_backup_before_update: boolean; } diff --git a/src/panels/config/apps/app-view/info/supervisor-app-info.ts b/src/panels/config/apps/app-view/info/supervisor-app-info.ts index cfb3a2ce62..b5e11e350b 100644 --- a/src/panels/config/apps/app-view/info/supervisor-app-info.ts +++ b/src/panels/config/apps/app-view/info/supervisor-app-info.ts @@ -897,7 +897,9 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) { this._uninstalling } @change=${this._panelToggled} - .checked=${this._currentAddon.ingress_panel} + .checked=${ + this._currentAddon.ingress_panel || false + } haptic > diff --git a/src/panels/config/core/ha-config-system-navigation.ts b/src/panels/config/core/ha-config-system-navigation.ts index 75fe1b96a1..38e8eb458d 100644 --- a/src/panels/config/core/ha-config-system-navigation.ts +++ b/src/panels/config/core/ha-config-system-navigation.ts @@ -194,9 +194,9 @@ class HaConfigSystemNavigation extends LitElement { const hardwareInfo: HardwareInfo = await this.hass.callWS({ type: "hardware/info", }); - this._boardName = hardwareInfo?.hardware.find( - (hw) => hw.board !== null - )?.name; + this._boardName = + hardwareInfo?.hardware.find((hw) => hw.board !== null)?.name ?? + undefined; } else if (isHassioLoaded) { const osData: HassioHassOSInfo = await fetchHassioHassOsInfo(this.hass); if (osData.board) { diff --git a/src/panels/config/hardware/ha-config-hardware-overview.ts b/src/panels/config/hardware/ha-config-hardware-overview.ts index 8cd93d3df7..04f5643a84 100644 --- a/src/panels/config/hardware/ha-config-hardware-overview.ts +++ b/src/panels/config/hardware/ha-config-hardware-overview.ts @@ -214,7 +214,7 @@ class HaConfigHardwareOverview extends SubscribeMixin(LitElement) { const dongles = this._hardwareInfo?.hardware.filter( (hw) => hw.dongle !== null && - (!hw.config_entries.length || + (!hw.config_entries?.length || hw.config_entries.some( (entryId) => this._configEntries?.[entryId] && @@ -223,19 +223,19 @@ class HaConfigHardwareOverview extends SubscribeMixin(LitElement) { ); if (boardData) { - boardConfigEntries = boardData.config_entries + boardConfigEntries = (boardData.config_entries ?? []) .map((id) => this._configEntries?.[id]) .filter( (entry) => entry?.supports_options && !entry.disabled_by ) as ConfigEntry[]; - boardId = boardData.board!.hassio_board_id; - boardName = boardData.name; + boardId = boardData.board!.hassio_board_id ?? undefined; + boardName = boardData.name ?? undefined; documentationURL = sanitizeHttpUrl(boardData.url); imageURL = hardwareBrandsUrl( { category: "boards", manufacturer: boardData.board!.manufacturer, - model: boardData.board!.model, + model: boardData.board!.model ?? undefined, darkOptimized: this.hass.themes?.darkMode, }, this.hass.auth.data.hassUrl @@ -355,7 +355,7 @@ class HaConfigHardwareOverview extends SubscribeMixin(LitElement) { dongles?.length ? html` ${dongles.map((dongle) => { - const configEntry = dongle.config_entries + const configEntry = (dongle.config_entries ?? []) .map((id) => this._configEntries?.[id]) .filter( (entry) => entry?.supports_options && !entry.disabled_by diff --git a/src/panels/config/network/supervisor-hostname.ts b/src/panels/config/network/supervisor-hostname.ts index e0dea18cbf..7d1464f09e 100644 --- a/src/panels/config/network/supervisor-hostname.ts +++ b/src/panels/config/network/supervisor-hostname.ts @@ -32,7 +32,7 @@ export class HassioHostname extends LitElement { private async _fetchHostInfo() { const hostInfo = await fetchHassioHostInfo(this.hass); - this._hostname = hostInfo.hostname; + this._hostname = hostInfo.hostname ?? undefined; } protected render() { diff --git a/src/panels/config/repairs/dialog-system-information.ts b/src/panels/config/repairs/dialog-system-information.ts index 1d9c9eb498..7c3aab496c 100644 --- a/src/panels/config/repairs/dialog-system-information.ts +++ b/src/panels/config/repairs/dialog-system-information.ts @@ -203,7 +203,7 @@ class DialogSystemInformation extends LitElement { .heading=${this.hass.localize( "ui.panel.config.system_health.cpu_usage" )} - .value=${this._coreStats.cpu_percent} + .value=${this._coreStats.cpu_percent ?? 0} > { // Assume a speed of 30 MB/s. const moveTime = (hostInfo.disk_used * 1000) / 60 / 30; - const rebootTime = (hostInfo.startup_time * 4) / 60; + const rebootTime = ((hostInfo.startup_time ?? 0) * 4) / 60; return Math.ceil((moveTime + rebootTime) / 10) * 10; }); @@ -145,7 +145,7 @@ class MoveDatadiskDialog extends DirtyStateProviderMixin( ${this.hass.localize( "ui.panel.config.storage.datadisk.description", { - current_path: this._osInfo.data_disk, + current_path: this._osInfo.data_disk ?? "", time: calculateMoveTime(this._hostInfo), } )}