Introduce supervisor object (#7800)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Joakim Sørensen 2020-11-25 18:22:05 +01:00 committed by GitHub
parent 7de7d1d926
commit 6f0c79ec25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 211 additions and 280 deletions

View File

@ -12,7 +12,7 @@ import { atLeastVersion } from "../../../src/common/config/version";
import { navigate } from "../../../src/common/navigate";
import { compare } from "../../../src/common/string/compare";
import "../../../src/components/ha-card";
import { HassioAddonInfo } from "../../../src/data/hassio/addon";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
import "../components/hassio-card-content";
@ -22,14 +22,14 @@ import { hassioStyle } from "../resources/hassio-style";
class HassioAddons extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addons?: HassioAddonInfo[];
@property({ attribute: false }) public supervisor!: Supervisor;
protected render(): TemplateResult {
return html`
<div class="content">
<h1>Add-ons</h1>
<div class="card-group">
${!this.addons?.length
${!this.supervisor.supervisor.addons?.length
? html`
<ha-card>
<div class="card-content">
@ -41,7 +41,7 @@ class HassioAddons extends LitElement {
</div>
</ha-card>
`
: this.addons
: this.supervisor.supervisor.addons
.sort((a, b) => compare(a.name, b.name))
.map(
(addon) => html`

View File

@ -7,11 +7,7 @@ import {
property,
TemplateResult,
} from "lit-element";
import { HassioHassOSInfo } from "../../../src/data/hassio/host";
import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
} from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-tabs-subpage";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types";
@ -23,16 +19,12 @@ import "./hassio-update";
class HassioDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public supervisorInfo!: HassioSupervisorInfo;
@property({ attribute: false }) public hassInfo!: HassioHomeAssistantInfo;
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
protected render(): TemplateResult {
return html`
<hass-tabs-subpage
@ -47,13 +39,11 @@ class HassioDashboard extends LitElement {
<div class="content">
<hassio-update
.hass=${this.hass}
.hassInfo=${this.hassInfo}
.supervisorInfo=${this.supervisorInfo}
.hassOsInfo=${this.hassOsInfo}
.supervisor=${this.supervisor}
></hassio-update>
<hassio-addons
.hass=${this.hass}
.addons=${this.supervisorInfo.addons}
.supervisor=${this.supervisor}
></hassio-addons>
</div>
</hass-tabs-subpage>

View File

@ -23,6 +23,7 @@ import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
} from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
@ -35,31 +36,20 @@ import { hassioStyle } from "../resources/hassio-style";
export class HassioUpdate extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public hassInfo?: HassioHomeAssistantInfo;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public hassOsInfo?: HassioHassOSInfo;
@property({ attribute: false }) public supervisorInfo?: HassioSupervisorInfo;
private _pendingUpdates = memoizeOne(
(
core?: HassioHomeAssistantInfo,
supervisor?: HassioSupervisorInfo,
os?: HassioHassOSInfo
): number => {
return [core, supervisor, os].filter(
(value) => !!value && value?.update_available
).length;
}
);
private _pendingUpdates = memoizeOne((supervisor: Supervisor): number => {
return Object.keys(supervisor).filter(
(value) => supervisor[value].update_available
).length;
});
protected render(): TemplateResult {
const updatesAvailable = this._pendingUpdates(
this.hassInfo,
this.supervisorInfo,
this.hassOsInfo
);
if (!this.supervisor) {
return html``;
}
const updatesAvailable = this._pendingUpdates(this.supervisor);
if (!updatesAvailable) {
return html``;
}
@ -74,26 +64,26 @@ export class HassioUpdate extends LitElement {
<div class="card-group">
${this._renderUpdateCard(
"Home Assistant Core",
this.hassInfo!,
this.supervisor.core,
"hassio/homeassistant/update",
`https://${
this.hassInfo?.version_latest.includes("b") ? "rc" : "www"
this.supervisor.core.version_latest.includes("b") ? "rc" : "www"
}.home-assistant.io/latest-release-notes/`
)}
${this._renderUpdateCard(
"Supervisor",
this.supervisorInfo!,
this.supervisor.supervisor,
"hassio/supervisor/update",
`https://github.com//home-assistant/hassio/releases/tag/${
this.supervisorInfo!.version_latest
this.supervisor.supervisor.version_latest
}`
)}
${this.hassOsInfo
${this.supervisor.host.features.includes("hassos")
? this._renderUpdateCard(
"Operating System",
this.hassOsInfo,
this.supervisor.os,
"hassio/os/update",
`https://github.com//home-assistant/hassos/releases/tag/${this.hassOsInfo.version_latest}`
`https://github.com//home-assistant/hassos/releases/tag/${this.supervisor.os.version_latest}`
)
: ""}
</div>

View File

@ -1,29 +1,22 @@
import {
html,
PropertyValues,
customElement,
LitElement,
property,
} from "lit-element";
import { html, PropertyValues, customElement, property } from "lit-element";
import "./hassio-router";
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
import { HomeAssistant, Route } from "../../src/types";
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
import { fireEvent } from "../../src/common/dom/fire_event";
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
import { atLeastVersion } from "../../src/common/config/version";
import { SupervisorBaseElement } from "./supervisor-base-element";
@customElement("hassio-main")
export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) {
export class HassioMain extends SupervisorBaseElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public panel!: HassioPanelInfo;
@property({ attribute: false }) public panel!: HassioPanelInfo;
@property() public narrow!: boolean;
@property({ type: Boolean }) public narrow!: boolean;
@property() public route?: Route;
@property({ attribute: false }) public route?: Route;
protected firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps);
@ -77,9 +70,13 @@ export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) {
}
protected render() {
if (!this.supervisor || !this.hass) {
return html``;
}
return html`
<hassio-router
.hass=${this.hass}
.supervisor=${this.supervisor}
.route=${this.route}
.panel=${this.panel}
.narrow=${this.narrow}

View File

@ -1,10 +1,5 @@
import { customElement, property } from "lit-element";
import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host";
import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
HassioInfo,
} from "../../src/data/hassio/supervisor";
import { Supervisor } from "../../src/data/supervisor/supervisor";
import {
HassRouterPage,
RouterOptions,
@ -21,20 +16,12 @@ import "./system/hassio-system";
class HassioPanelRouter extends HassRouterPage {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ attribute: false }) public route!: Route;
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public supervisorInfo?: HassioSupervisorInfo;
@property({ attribute: false }) public hassioInfo!: HassioInfo;
@property({ attribute: false }) public hostInfo?: HassioHostInfo;
@property({ attribute: false }) public hassInfo?: HassioHomeAssistantInfo;
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
protected routerOptions: RouterOptions = {
routes: {
dashboard: {
@ -54,13 +41,9 @@ class HassioPanelRouter extends HassRouterPage {
protected updatePageEl(el) {
el.hass = this.hass;
el.supervisor = this.supervisor;
el.route = this.route;
el.narrow = this.narrow;
el.supervisorInfo = this.supervisorInfo;
el.hassioInfo = this.hassioInfo;
el.hostInfo = this.hostInfo;
el.hassInfo = this.hassInfo;
el.hassOsInfo = this.hassOsInfo;
}
}

View File

@ -1,18 +1,13 @@
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
css,
CSSResult,
} from "lit-element";
import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host";
import {
HassioHomeAssistantInfo,
HassioSupervisorInfo,
HassioInfo,
} from "../../src/data/hassio/supervisor";
import { Supervisor } from "../../src/data/supervisor/supervisor";
import { HomeAssistant, Route } from "../../src/types";
import "./hassio-panel-router";
@ -20,34 +15,19 @@ import "./hassio-panel-router";
class HassioPanel extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public supervisorInfo!: HassioSupervisorInfo;
@property({ attribute: false }) public hassioInfo!: HassioInfo;
@property({ attribute: false }) public hostInfo!: HassioHostInfo;
@property({ attribute: false }) public hassInfo!: HassioHomeAssistantInfo;
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
protected render(): TemplateResult {
if (!this.supervisorInfo) {
return html``;
}
return html`
<hassio-panel-router
.route=${this.route}
.hass=${this.hass}
.supervisor=${this.supervisor}
.route=${this.route}
.narrow=${this.narrow}
.supervisorInfo=${this.supervisorInfo}
.hassioInfo=${this.hassioInfo}
.hostInfo=${this.hostInfo}
.hassInfo=${this.hassInfo}
.hassOsInfo=${this.hassOsInfo}
></hassio-panel-router>
`;
}

View File

@ -1,24 +1,6 @@
import {
customElement,
property,
internalProperty,
PropertyValues,
} from "lit-element";
import {
fetchHassioHassOsInfo,
fetchHassioHostInfo,
HassioHassOSInfo,
HassioHostInfo,
} from "../../src/data/hassio/host";
import {
fetchHassioHomeAssistantInfo,
fetchHassioSupervisorInfo,
fetchHassioInfo,
HassioHomeAssistantInfo,
HassioInfo,
HassioPanelInfo,
HassioSupervisorInfo,
} from "../../src/data/hassio/supervisor";
import { customElement, property } from "lit-element";
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
import { Supervisor } from "../../src/data/supervisor/supervisor";
import {
HassRouterPage,
RouterOptions,
@ -32,9 +14,11 @@ import "./hassio-panel";
class HassioRouter extends HassRouterPage {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public panel!: HassioPanelInfo;
@property({ attribute: false }) public supervisor!: Supervisor;
@property() public narrow!: boolean;
@property({ attribute: false }) public panel!: HassioPanelInfo;
@property({ type: Boolean }) public narrow!: boolean;
protected routerOptions: RouterOptions = {
// Hass.io has a page with tabs, so we route all non-matching routes to it.
@ -60,32 +44,13 @@ class HassioRouter extends HassRouterPage {
},
};
@internalProperty() private _supervisorInfo?: HassioSupervisorInfo;
@internalProperty() private _hostInfo?: HassioHostInfo;
@internalProperty() private _hassioInfo?: HassioInfo;
@internalProperty() private _hassOsInfo?: HassioHassOSInfo;
@internalProperty() private _hassInfo?: HassioHomeAssistantInfo;
protected firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps);
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
}
protected updatePageEl(el) {
// the tabs page does its own routing so needs full route.
const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail;
el.hass = this.hass;
el.supervisor = this.supervisor;
el.narrow = this.narrow;
el.supervisorInfo = this._supervisorInfo;
el.hassioInfo = this._hassioInfo;
el.hostInfo = this._hostInfo;
el.hassInfo = this._hassInfo;
el.hassOsInfo = this._hassOsInfo;
el.route = route;
if (el.localName === "hassio-ingress-view") {
@ -96,45 +61,12 @@ class HassioRouter extends HassRouterPage {
private async _fetchData() {
if (this.panel.config && this.panel.config.ingress) {
this._redirectIngress(this.panel.config.ingress);
return;
}
const [supervisorInfo, hostInfo, hassInfo, hassioInfo] = await Promise.all([
fetchHassioSupervisorInfo(this.hass),
fetchHassioHostInfo(this.hass),
fetchHassioHomeAssistantInfo(this.hass),
fetchHassioInfo(this.hass),
]);
this._supervisorInfo = supervisorInfo;
this._hassioInfo = hassioInfo;
this._hostInfo = hostInfo;
this._hassInfo = hassInfo;
if (this._hostInfo.features && this._hostInfo.features.includes("hassos")) {
this._hassOsInfo = await fetchHassioHassOsInfo(this.hass);
}
}
private _redirectIngress(addonSlug: string) {
this.route = { prefix: "/hassio", path: `/ingress/${addonSlug}` };
}
private _apiCalled(ev) {
if (!ev.detail.success) {
return;
}
let tries = 1;
const tryUpdate = () => {
this._fetchData().catch(() => {
tries += 1;
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
});
};
tryUpdate();
}
}
declare global {

View File

@ -26,7 +26,6 @@ import {
TemplateResult,
} from "lit-element";
import { atLeastVersion } from "../../../src/common/config/version";
import { fireEvent } from "../../../src/common/dom/fire_event";
import "../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-button-menu";
import "../../../src/components/ha-card";
@ -41,7 +40,7 @@ import {
HassioSnapshot,
reloadHassioSnapshots,
} from "../../../src/data/hassio/snapshot";
import { HassioSupervisorInfo } from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-tabs-subpage";
import { PolymerChangedEvent } from "../../../src/polymer-types";
import { haStyle } from "../../../src/resources/styles";
@ -67,7 +66,7 @@ class HassioSnapshots extends LitElement {
@property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public supervisorInfo!: HassioSupervisorInfo;
@property({ attribute: false }) public supervisor!: Supervisor;
@internalProperty() private _snapshotName = "";
@ -266,7 +265,7 @@ class HassioSnapshots extends LitElement {
protected updated(changedProps: PropertyValues) {
if (changedProps.has("supervisorInfo")) {
this._addonList = this.supervisorInfo.addons
this._addonList = this.supervisor.supervisor.addons
.map((addon) => ({
slug: addon.slug,
name: addon.name,
@ -372,7 +371,6 @@ class HassioSnapshots extends LitElement {
await createHassioPartialSnapshot(this.hass, data);
}
this._updateSnapshots();
fireEvent(this, "hass-api-called", { success: true, response: null });
} catch (err) {
this._error = extractApiErrorMessage(err);
}

View File

@ -0,0 +1,69 @@
import { LitElement, property, PropertyValues } from "lit-element";
import {
fetchHassioHassOsInfo,
fetchHassioHostInfo,
} from "../../src/data/hassio/host";
import { fetchNetworkInfo } from "../../src/data/hassio/network";
import { fetchHassioResolution } from "../../src/data/hassio/resolution";
import {
fetchHassioHomeAssistantInfo,
fetchHassioInfo,
fetchHassioSupervisorInfo,
} from "../../src/data/hassio/supervisor";
import { Supervisor } from "../../src/data/supervisor/supervisor";
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
declare global {
interface HASSDomEvents {
"supervisor-update": Partial<Supervisor>;
}
}
export class SupervisorBaseElement extends urlSyncMixin(
ProvideHassLitMixin(LitElement)
) {
@property({ attribute: false }) public supervisor?: Supervisor;
protected _updateSupervisor(obj: Partial<Supervisor>): void {
this.supervisor = { ...this.supervisor!, ...obj };
}
protected firstUpdated(changedProps: PropertyValues): void {
super.firstUpdated(changedProps);
this._initSupervisor();
this.addEventListener("supervisor-update", (ev) =>
this._updateSupervisor(ev.detail)
);
}
private async _initSupervisor(): Promise<void> {
const [
supervisor,
host,
core,
info,
os,
network,
resolution,
] = await Promise.all([
fetchHassioSupervisorInfo(this.hass),
fetchHassioHostInfo(this.hass),
fetchHassioHomeAssistantInfo(this.hass),
fetchHassioInfo(this.hass),
fetchHassioHassOsInfo(this.hass),
fetchNetworkInfo(this.hass),
fetchHassioResolution(this.hass),
]);
this.supervisor = {
supervisor,
host,
core,
info,
os,
network,
resolution,
};
}
}

View File

@ -8,12 +8,12 @@ import {
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../src/common/dom/fire_event";
import "../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-button-menu";
import "../../../src/components/ha-card";
@ -27,8 +27,6 @@ import {
changeHostOptions,
configSyncOS,
fetchHassioHostInfo,
HassioHassOSInfo,
HassioHostInfo as HassioHostInfoType,
rebootHost,
shutdownHost,
updateOS,
@ -37,7 +35,7 @@ import {
fetchNetworkInfo,
NetworkInfo,
} from "../../../src/data/hassio/network";
import { HassioInfo } from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
@ -53,28 +51,22 @@ import { hassioStyle } from "../resources/hassio-style";
class HassioHostInfo extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public hostInfo!: HassioHostInfoType;
@property({ attribute: false }) public hassioInfo!: HassioInfo;
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
@internalProperty() public _networkInfo?: NetworkInfo;
@property({ attribute: false }) public supervisor!: Supervisor;
protected render(): TemplateResult | void {
const primaryIpAddress = this.hostInfo.features.includes("network")
? this._primaryIpAddress(this._networkInfo!)
const primaryIpAddress = this.supervisor.host.features.includes("network")
? this._primaryIpAddress(this.supervisor.network!)
: "";
return html`
<ha-card header="Host System">
<div class="card-content">
${this.hostInfo.features.includes("hostname")
${this.supervisor.host.features.includes("hostname")
? html`<ha-settings-row>
<span slot="heading">
Hostname
</span>
<span slot="description">
${this.hostInfo.hostname}
${this.supervisor.host.hostname}
</span>
<mwc-button
title="Change the hostname"
@ -84,7 +76,7 @@ class HassioHostInfo extends LitElement {
</mwc-button>
</ha-settings-row>`
: ""}
${this.hostInfo.features.includes("network")
${this.supervisor.host.features.includes("network")
? html` <ha-settings-row>
<span slot="heading">
IP Address
@ -106,10 +98,9 @@ class HassioHostInfo extends LitElement {
Operating System
</span>
<span slot="description">
${this.hostInfo.operating_system}
${this.supervisor.host.operating_system}
</span>
${this.hostInfo.features.includes("hassos") &&
this.hassOsInfo.update_available
${this.supervisor.os.update_available
? html`
<ha-progress-button
title="Update the host OS"
@ -120,29 +111,29 @@ class HassioHostInfo extends LitElement {
`
: ""}
</ha-settings-row>
${!this.hostInfo.features.includes("hassos")
${!this.supervisor.host.features.includes("hassos")
? html`<ha-settings-row>
<span slot="heading">
Docker version
</span>
<span slot="description">
${this.hassioInfo.docker}
${this.supervisor.info.docker}
</span>
</ha-settings-row>`
: ""}
${this.hostInfo.deployment
${this.supervisor.host.deployment
? html`<ha-settings-row>
<span slot="heading">
Deployment
</span>
<span slot="description">
${this.hostInfo.deployment}
${this.supervisor.host.deployment}
</span>
</ha-settings-row>`
: ""}
</div>
<div class="card-actions">
${this.hostInfo.features.includes("reboot")
${this.supervisor.host.features.includes("reboot")
? html`
<ha-progress-button
title="Reboot the host OS"
@ -153,7 +144,7 @@ class HassioHostInfo extends LitElement {
</ha-progress-button>
`
: ""}
${this.hostInfo.features.includes("shutdown")
${this.supervisor.host.features.includes("shutdown")
? html`
<ha-progress-button
title="Shutdown the host OS"
@ -175,7 +166,7 @@ class HassioHostInfo extends LitElement {
<mwc-list-item title="Show a list of hardware">
Hardware
</mwc-list-item>
${this.hostInfo.features.includes("hassos")
${this.supervisor.host.features.includes("hassos")
? html`<mwc-list-item
title="Load HassOS configs or updates from USB"
>
@ -314,13 +305,13 @@ class HassioHostInfo extends LitElement {
private async _changeNetworkClicked(): Promise<void> {
showNetworkDialog(this, {
network: this._networkInfo!,
network: this.supervisor.network!,
loadData: () => this._loadData(),
});
}
private async _changeHostnameClicked(): Promise<void> {
const curHostname: string = this.hostInfo.hostname;
const curHostname: string = this.supervisor.host.hostname;
const hostname = await showPromptDialog(this, {
title: "Change Hostname",
inputLabel: "Please enter a new hostname:",
@ -331,7 +322,8 @@ class HassioHostInfo extends LitElement {
if (hostname && hostname !== curHostname) {
try {
await changeHostOptions(this.hass, { hostname });
this.hostInfo = await fetchHassioHostInfo(this.hass);
const host = await fetchHassioHostInfo(this.hass);
fireEvent(this, "supervisor-update", { host });
} catch (err) {
showAlertDialog(this, {
title: "Setting hostname failed",
@ -344,7 +336,8 @@ class HassioHostInfo extends LitElement {
private async _importFromUSB(): Promise<void> {
try {
await configSyncOS(this.hass);
this.hostInfo = await fetchHassioHostInfo(this.hass);
const host = await fetchHassioHostInfo(this.hass);
fireEvent(this, "supervisor-update", { host });
} catch (err) {
showAlertDialog(this, {
title: "Failed to import from USB",
@ -354,7 +347,8 @@ class HassioHostInfo extends LitElement {
}
private async _loadData(): Promise<void> {
this._networkInfo = await fetchNetworkInfo(this.hass);
const network = await fetchNetworkInfo(this.hass);
fireEvent(this, "supervisor-update", { network });
}
static get styles(): CSSResult[] {

View File

@ -13,17 +13,15 @@ import "../../../src/components/ha-card";
import "../../../src/components/ha-settings-row";
import "../../../src/components/ha-switch";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import { HassioHostInfo as HassioHostInfoType } from "../../../src/data/hassio/host";
import { fetchHassioResolution } from "../../../src/data/hassio/resolution";
import {
fetchHassioSupervisorInfo,
HassioSupervisorInfo as HassioSupervisorInfoType,
reloadSupervisor,
restartSupervisor,
setSupervisorOption,
SupervisorOptions,
updateSupervisor,
} from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import {
showAlertDialog,
showConfirmationDialog,
@ -87,15 +85,9 @@ const UNHEALTHY_REASON = {
class HassioSupervisorInfo extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false })
public supervisorInfo!: HassioSupervisorInfoType;
@property({ attribute: false }) public hostInfo!: HassioHostInfoType;
@property({ attribute: false }) public supervisor!: Supervisor;
protected render(): TemplateResult | void {
if (!this.hass || !this.supervisorInfo || !this.hostInfo) {
return html``;
}
return html`
<ha-card header="Supervisor">
<div class="card-content">
@ -104,7 +96,7 @@ class HassioSupervisorInfo extends LitElement {
Version
</span>
<span slot="description">
${this.supervisorInfo.version}
${this.supervisor.supervisor.version}
</span>
</ha-settings-row>
<ha-settings-row>
@ -112,9 +104,9 @@ class HassioSupervisorInfo extends LitElement {
Newest Version
</span>
<span slot="description">
${this.supervisorInfo.version_latest}
${this.supervisor.supervisor.version_latest}
</span>
${this.supervisorInfo.update_available
${this.supervisor.supervisor.update_available
? html`
<ha-progress-button
title="Update the supervisor"
@ -130,9 +122,9 @@ class HassioSupervisorInfo extends LitElement {
Channel
</span>
<span slot="description">
${this.supervisorInfo.channel}
${this.supervisor.supervisor.channel}
</span>
${this.supervisorInfo.channel === "beta"
${this.supervisor.supervisor.channel === "beta"
? html`
<ha-progress-button
@click=${this._toggleBeta}
@ -141,7 +133,7 @@ class HassioSupervisorInfo extends LitElement {
Leave beta channel
</ha-progress-button>
`
: this.supervisorInfo.channel === "stable"
: this.supervisor.supervisor.channel === "stable"
? html`
<ha-progress-button
@click=${this._toggleBeta}
@ -153,7 +145,7 @@ class HassioSupervisorInfo extends LitElement {
: ""}
</ha-settings-row>
${this.supervisorInfo.supported
${this.supervisor.supervisor.supported
? html` <ha-settings-row three-line>
<span slot="heading">
Share Diagnostics
@ -170,7 +162,7 @@ class HassioSupervisorInfo extends LitElement {
</div>
<ha-switch
haptic
.checked=${this.supervisorInfo.diagnostics}
.checked=${this.supervisor.supervisor.diagnostics}
@change=${this._toggleDiagnostics}
></ha-switch>
</ha-settings-row>`
@ -184,7 +176,7 @@ class HassioSupervisorInfo extends LitElement {
Learn more
</button>
</div>`}
${!this.supervisorInfo.healthy
${!this.supervisor.supervisor.healthy
? html`<div class="error">
Your installtion is running in an unhealthy state.
<button
@ -220,7 +212,7 @@ class HassioSupervisorInfo extends LitElement {
const button = ev.currentTarget as any;
button.progress = true;
if (this.supervisorInfo.channel === "stable") {
if (this.supervisor.supervisor.channel === "stable") {
const confirmed = await showConfirmationDialog(this, {
title: "WARNING",
text: html` Beta releases are for testers and early adopters and can
@ -249,11 +241,11 @@ class HassioSupervisorInfo extends LitElement {
try {
const data: Partial<SupervisorOptions> = {
channel: this.supervisorInfo.channel === "stable" ? "beta" : "stable",
channel:
this.supervisor.supervisor.channel === "stable" ? "beta" : "stable",
};
await setSupervisorOption(this.hass, data);
await reloadSupervisor(this.hass);
fireEvent(this, "hass-api-called", { success: true, response: null });
await this._reloadSupervisor();
} catch (err) {
showAlertDialog(this, {
title: "Failed to set supervisor option",
@ -269,8 +261,7 @@ class HassioSupervisorInfo extends LitElement {
button.progress = true;
try {
await reloadSupervisor(this.hass);
this.supervisorInfo = await fetchHassioSupervisorInfo(this.hass);
await this._reloadSupervisor();
} catch (err) {
showAlertDialog(this, {
title: "Failed to reload the supervisor",
@ -281,6 +272,12 @@ class HassioSupervisorInfo extends LitElement {
}
}
private async _reloadSupervisor(): Promise<void> {
await reloadSupervisor(this.hass);
const supervisor = await fetchHassioSupervisorInfo(this.hass);
fireEvent(this, "supervisor-update", { supervisor });
}
private async _supervisorRestart(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
@ -303,7 +300,7 @@ class HassioSupervisorInfo extends LitElement {
const confirmed = await showConfirmationDialog(this, {
title: "Update Supervisor",
text: `Are you sure you want to update supervisor to version ${this.supervisorInfo.version_latest}?`,
text: `Are you sure you want to update supervisor to version ${this.supervisor.supervisor.version_latest}?`,
confirmText: "update",
dismissText: "cancel",
});
@ -341,13 +338,12 @@ class HassioSupervisorInfo extends LitElement {
}
private async _unsupportedDialog(): Promise<void> {
const resolution = await fetchHassioResolution(this.hass);
await showAlertDialog(this, {
title: "You are running an unsupported installation",
text: html`Below is a list of issues found with your installation, click
on the links to learn how you can resolve the issues. <br /><br />
<ul>
${resolution.unsupported.map(
${this.supervisor.resolution.unsupported.map(
(issue) => html`
<li>
${UNSUPPORTED_REASON[issue]
@ -370,14 +366,13 @@ class HassioSupervisorInfo extends LitElement {
}
private async _unhealthyDialog(): Promise<void> {
const resolution = await fetchHassioResolution(this.hass);
await showAlertDialog(this, {
title: "Your installation is unhealthy",
text: html`Running an unhealthy installation will cause issues. Below is a
list of issues found with your installation, click on the links to learn
how you can resolve the issues. <br /><br />
<ul>
${resolution.unhealthy.map(
${this.supervisor.resolution.unhealthy.map(
(issue) => html`
<li>
${UNHEALTHY_REASON[issue]
@ -402,7 +397,7 @@ class HassioSupervisorInfo extends LitElement {
private async _toggleDiagnostics(): Promise<void> {
try {
const data: SupervisorOptions = {
diagnostics: !this.supervisorInfo?.diagnostics,
diagnostics: !this.supervisor.supervisor?.diagnostics,
};
await setSupervisorOption(this.hass, data);
} catch (err) {

View File

@ -19,6 +19,7 @@ import "../../../src/components/ha-card";
import "../../../src/components/ha-settings-row";
import { fetchHassioStats, HassioStats } from "../../../src/data/hassio/common";
import { HassioHostInfo } from "../../../src/data/hassio/host";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
import { bytesToString } from "../../../src/util/bytes-to-string";
@ -32,7 +33,7 @@ import { hassioStyle } from "../resources/hassio-style";
class HassioSystemMetrics extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public hostInfo!: HassioHostInfo;
@property({ attribute: false }) public supervisor!: Supervisor;
@internalProperty() private _supervisorMetrics?: HassioStats;
@ -64,8 +65,8 @@ class HassioSystemMetrics extends LitElement {
},
{
description: "Used Space",
value: this._getUsedSpace(this.hostInfo),
tooltip: `${this.hostInfo.disk_used} GB/${this.hostInfo.disk_total} GB`,
value: this._getUsedSpace(this.supervisor.host),
tooltip: `${this.supervisor.host.disk_used} GB/${this.supervisor.host.disk_total} GB`,
},
];

View File

@ -7,14 +7,7 @@ import {
property,
TemplateResult,
} from "lit-element";
import {
HassioHassOSInfo,
HassioHostInfo,
} from "../../../src/data/hassio/host";
import {
HassioInfo,
HassioSupervisorInfo,
} from "../../../src/data/hassio/supervisor";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import "../../../src/layouts/hass-tabs-subpage";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types";
@ -29,18 +22,12 @@ import "./hassio-system-metrics";
class HassioSystem extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public supervisor!: Supervisor;
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public route!: Route;
@property() public supervisorInfo!: HassioSupervisorInfo;
@property({ attribute: false }) public hassioInfo!: HassioInfo;
@property() public hostInfo!: HassioHostInfo;
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
protected render(): TemplateResult | void {
return html`
<hass-tabs-subpage
@ -56,18 +43,15 @@ class HassioSystem extends LitElement {
<div class="card-group">
<hassio-supervisor-info
.hass=${this.hass}
.hostInfo=${this.hostInfo}
.supervisorInfo=${this.supervisorInfo}
.supervisor=${this.supervisor}
></hassio-supervisor-info>
<hassio-host-info
.hass=${this.hass}
.hassioInfo=${this.hassioInfo}
.hostInfo=${this.hostInfo}
.hassOsInfo=${this.hassOsInfo}
.supervisor=${this.supervisor}
></hassio-host-info>
<hassio-system-metrics
.hass=${this.hass}
.hostInfo=${this.hostInfo}
.supervisor=${this.supervisor}
></hassio-system-metrics>
</div>
<hassio-supervisor-log .hass=${this.hass}></hassio-supervisor-log>

View File

@ -15,11 +15,11 @@ export type HassioHostInfo = {
};
export interface HassioHassOSInfo {
board: string;
boot: string;
board: string | null;
boot: string | null;
update_available: boolean;
version_latest: string;
version: string;
version_latest: string | null;
version: string | null;
}
export const fetchHassioHostInfo = async (hass: HomeAssistant) => {

View File

@ -0,0 +1,18 @@
import { HassioHassOSInfo, HassioHostInfo } from "../hassio/host";
import { NetworkInfo } from "../hassio/network";
import { HassioResolution } from "../hassio/resolution";
import {
HassioHomeAssistantInfo,
HassioInfo,
HassioSupervisorInfo,
} from "../hassio/supervisor";
export interface Supervisor {
host: HassioHostInfo;
supervisor: HassioSupervisorInfo;
info: HassioInfo;
core: HassioHomeAssistantInfo;
network: NetworkInfo;
resolution: HassioResolution;
os: HassioHassOSInfo;
}