From e8c30cabcae4eca084a1c95a891b97ff4614ea7c Mon Sep 17 00:00:00 2001 From: Zack Barett Date: Mon, 25 Apr 2022 18:24:58 -0500 Subject: [PATCH] Show usage stats in System Health (#12424) --- src/common/util/subscribe-polling.ts | 18 +++ src/panels/config/ha-panel-config.ts | 2 +- .../system-health/ha-config-system-health.ts | 143 +++++++++++++++--- src/translations/en.json | 7 +- 4 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/common/util/subscribe-polling.ts diff --git a/src/common/util/subscribe-polling.ts b/src/common/util/subscribe-polling.ts new file mode 100644 index 0000000000..e4770be8ec --- /dev/null +++ b/src/common/util/subscribe-polling.ts @@ -0,0 +1,18 @@ +import { HomeAssistant } from "../../types"; + +export const subscribePollingCollection = ( + hass: HomeAssistant, + updateData: (hass: HomeAssistant) => void, + interval: number +) => { + let timeout; + const fetchData = async () => { + try { + await updateData(hass); + } finally { + timeout = setTimeout(() => fetchData(), interval); + } + }; + fetchData(); + return () => clearTimeout(timeout); +}; diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts index 74836d5d34..81b97537ef 100644 --- a/src/panels/config/ha-panel-config.ts +++ b/src/panels/config/ha-panel-config.ts @@ -322,7 +322,7 @@ export const configSections: { [name: string]: PageNavigation[] } = { translationKey: "ui.panel.config.system_health.caption", iconPath: mdiHeart, iconColor: "#507FfE", - component: "system_health", + components: ["system_health", "hassio"], }, ], about: [ diff --git a/src/panels/config/system-health/ha-config-system-health.ts b/src/panels/config/system-health/ha-config-system-health.ts index 2df1526a38..48103bdc33 100644 --- a/src/panels/config/system-health/ha-config-system-health.ts +++ b/src/panels/config/system-health/ha-config-system-health.ts @@ -1,13 +1,19 @@ import { ActionDetail } from "@material/mwc-list"; import "@material/mwc-list/mwc-list-item"; import { mdiContentCopy } from "@mdi/js"; +import { UnsubscribeFunc } from "home-assistant-js-websocket/dist/types"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { formatDateTime } from "../../../common/datetime/format_date_time"; import { copyToClipboard } from "../../../common/util/copy-clipboard"; +import { subscribePollingCollection } from "../../../common/util/subscribe-polling"; +import "../../../components/ha-alert"; import "../../../components/ha-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-circular-progress"; +import "../../../components/ha-metric"; +import { fetchHassioStats, HassioStats } from "../../../data/hassio/common"; import { domainToName } from "../../../data/integration"; import { subscribeSystemHealthInfo, @@ -15,6 +21,7 @@ import { SystemHealthInfo, } from "../../../data/system_health"; import "../../../layouts/hass-subpage"; +import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import type { HomeAssistant } from "../../../types"; import { showToast } from "../../../util/toast"; @@ -35,21 +42,52 @@ const sortKeys = (a: string, b: string) => { }; @customElement("ha-config-system-health") -class HaConfigSystemHealth extends LitElement { +class HaConfigSystemHealth extends SubscribeMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; @property({ type: Boolean }) public narrow!: boolean; @state() private _info?: SystemHealthInfo; + @state() private _supervisorStats?: HassioStats; + + @state() private _coreStats?: HassioStats; + + @state() private _error?: { code: string; message: string }; + + public hassSubscribe(): Array> { + const subs: Array> = []; + if (isComponentLoaded(this.hass, "system_health")) { + subs.push( + subscribeSystemHealthInfo(this.hass!, (info) => { + this._info = info; + }) + ); + } + + if (isComponentLoaded(this.hass, "hassio")) { + subs.push( + subscribePollingCollection( + this.hass, + async () => { + this._supervisorStats = await fetchHassioStats( + this.hass, + "supervisor" + ); + this._coreStats = await fetchHassioStats(this.hass, "core"); + }, + 10000 + ) + ); + } + + return subs; + } + protected firstUpdated(changedProps) { super.firstUpdated(changedProps); this.hass!.loadBackendTranslation("system_health"); - - subscribeSystemHealthInfo(this.hass!, (info) => { - this._info = info; - }); } protected render(): TemplateResult { @@ -152,27 +190,88 @@ class HaConfigSystemHealth extends LitElement { back-path="/config/system" .header=${this.hass.localize("ui.panel.config.system_health.caption")} > - - - - ${this.hass.localize("ui.panel.config.info.copy_raw")} - - - ${this.hass.localize("ui.panel.config.info.copy_github")} - - + ${this._error + ? html` + ${this._error.message || this._error.code} + ` + : ""} + ${this._info + ? html` + + + + ${this.hass.localize("ui.panel.config.info.copy_raw")} + + + ${this.hass.localize("ui.panel.config.info.copy_github")} + + + ` + : ""}
${sections}
+ ${!this._coreStats && !this._supervisorStats + ? "" + : html` + +
+ ${this._coreStats + ? html` +

+ ${this.hass.localize( + "ui.panel.config.system_health.core_stats" + )} +

+ + + ` + : ""} + ${this._supervisorStats + ? html` +

+ ${this.hass.localize( + "ui.panel.config.system_health.supervisor_stats" + )} +

+ + + ` + : ""} +
+
+ `}
`; diff --git a/src/translations/en.json b/src/translations/en.json index 6179127c20..09f01e1a1b 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1677,7 +1677,6 @@ } } }, - "automation": { "caption": "Automations", "description": "Create custom behavior rules for your home", @@ -3167,7 +3166,11 @@ } }, "system_health": { - "caption": "System Health" + "caption": "System Health", + "cpu_usage": "CPU Usage", + "ram_usage": "RAM Usage", + "core_stats": "Core Stats", + "supervisor_stats": "Supervisor Stats" } }, "lovelace": {