mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Use websockets (#8403)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
17410874e3
commit
09e7600d86
@ -48,7 +48,7 @@ class HcCast extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this.lovelaceConfig === undefined) {
|
if (this.lovelaceConfig === undefined) {
|
||||||
return html` <hass-loading-screen no-toolbar></hass-loading-screen>> `;
|
return html`<hass-loading-screen no-toolbar></hass-loading-screen>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const error =
|
const error =
|
||||||
|
@ -11,19 +11,18 @@ import {
|
|||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { html, TemplateResult } from "lit-html";
|
import { html, TemplateResult } from "lit-html";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
import { atLeastVersion } from "../../../src/common/config/version";
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import "../../../src/common/search/search-input";
|
import "../../../src/common/search/search-input";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
import "../../../src/components/ha-svg-icon";
|
import "../../../src/components/ha-svg-icon";
|
||||||
import {
|
import {
|
||||||
fetchHassioAddonsInfo,
|
|
||||||
HassioAddonInfo,
|
HassioAddonInfo,
|
||||||
HassioAddonRepository,
|
HassioAddonRepository,
|
||||||
reloadHassioAddons,
|
reloadHassioAddons,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
import { fetchHassioSupervisorInfo } from "../../../src/data/hassio/supervisor";
|
|
||||||
import "../../../src/layouts/hass-loading-screen";
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
import "../../../src/layouts/hass-tabs-subpage";
|
import "../../../src/layouts/hass-tabs-subpage";
|
||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
@ -51,46 +50,27 @@ const sortRepos = (a: HassioAddonRepository, b: HassioAddonRepository) => {
|
|||||||
class HassioAddonStore extends LitElement {
|
class HassioAddonStore extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||||
|
|
||||||
@property({ type: Boolean }) public narrow!: boolean;
|
@property({ type: Boolean }) public narrow!: boolean;
|
||||||
|
|
||||||
@property({ attribute: false }) public route!: Route;
|
@property({ attribute: false }) public route!: Route;
|
||||||
|
|
||||||
@property({ attribute: false }) private _addons?: HassioAddonInfo[];
|
|
||||||
|
|
||||||
@property({ attribute: false }) private _repos?: HassioAddonRepository[];
|
|
||||||
|
|
||||||
@internalProperty() private _filter?: string;
|
@internalProperty() private _filter?: string;
|
||||||
|
|
||||||
public async refreshData() {
|
public async refreshData() {
|
||||||
this._repos = undefined;
|
|
||||||
this._addons = undefined;
|
|
||||||
this._filter = undefined;
|
|
||||||
await reloadHassioAddons(this.hass);
|
await reloadHassioAddons(this.hass);
|
||||||
await this._loadData();
|
await this._loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const repos: TemplateResult[] = [];
|
let repos: TemplateResult[] = [];
|
||||||
|
|
||||||
if (this._repos) {
|
if (this.supervisor.addon.repositories) {
|
||||||
for (const repo of this._repos) {
|
repos = this.addonRepositories(
|
||||||
const addons = this._addons!.filter(
|
this.supervisor.addon.repositories,
|
||||||
(addon) => addon.repository === repo.slug
|
this.supervisor.addon.addons
|
||||||
);
|
);
|
||||||
|
|
||||||
if (addons.length === 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
repos.push(html`
|
|
||||||
<hassio-addon-repository
|
|
||||||
.hass=${this.hass}
|
|
||||||
.repo=${repo}
|
|
||||||
.addons=${addons}
|
|
||||||
.filter=${this._filter!}
|
|
||||||
></hassio-addon-repository>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
@ -159,6 +139,27 @@ class HassioAddonStore extends LitElement {
|
|||||||
this._loadData();
|
this._loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addonRepositories = memoizeOne(
|
||||||
|
(repositories: HassioAddonRepository[], addons: HassioAddonInfo[]) => {
|
||||||
|
return repositories.sort(sortRepos).map((repo) => {
|
||||||
|
const filteredAddons = addons.filter(
|
||||||
|
(addon) => addon.repository === repo.slug
|
||||||
|
);
|
||||||
|
|
||||||
|
return filteredAddons.length !== 0
|
||||||
|
? html`
|
||||||
|
<hassio-addon-repository
|
||||||
|
.hass=${this.hass}
|
||||||
|
.repo=${repo}
|
||||||
|
.addons=${filteredAddons}
|
||||||
|
.filter=${this._filter!}
|
||||||
|
></hassio-addon-repository>
|
||||||
|
`
|
||||||
|
: html``;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
||||||
switch (ev.detail.index) {
|
switch (ev.detail.index) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -181,7 +182,7 @@ class HassioAddonStore extends LitElement {
|
|||||||
|
|
||||||
private async _manageRepositories() {
|
private async _manageRepositories() {
|
||||||
showRepositoriesDialog(this, {
|
showRepositoriesDialog(this, {
|
||||||
repos: this._repos!,
|
repos: this.supervisor.addon.repositories,
|
||||||
loadData: () => this._loadData(),
|
loadData: () => this._loadData(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -191,18 +192,8 @@ class HassioAddonStore extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _loadData() {
|
private async _loadData() {
|
||||||
try {
|
fireEvent(this, "supervisor-store-refresh", { store: "addon" });
|
||||||
const [addonsInfo, supervisor] = await Promise.all([
|
fireEvent(this, "supervisor-store-refresh", { store: "supervisor" });
|
||||||
fetchHassioAddonsInfo(this.hass),
|
|
||||||
fetchHassioSupervisorInfo(this.hass),
|
|
||||||
]);
|
|
||||||
fireEvent(this, "supervisor-update", { supervisor });
|
|
||||||
this._repos = addonsInfo.repositories;
|
|
||||||
this._repos.sort(sortRepos);
|
|
||||||
this._addons = addonsInfo.addons;
|
|
||||||
} catch (err) {
|
|
||||||
alert(extractApiErrorMessage(err));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _filterChanged(e) {
|
private async _filterChanged(e) {
|
||||||
|
@ -24,9 +24,7 @@ import {
|
|||||||
HassioAddonDetails,
|
HassioAddonDetails,
|
||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||||
import { fetchHassioSupervisorInfo } from "../../../src/data/hassio/supervisor";
|
|
||||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||||
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
|
||||||
import "../../../src/layouts/hass-error-screen";
|
import "../../../src/layouts/hass-error-screen";
|
||||||
import "../../../src/layouts/hass-loading-screen";
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
import "../../../src/layouts/hass-tabs-subpage";
|
import "../../../src/layouts/hass-tabs-subpage";
|
||||||
@ -192,7 +190,7 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
const path: string = pathSplit[pathSplit.length - 1];
|
const path: string = pathSplit[pathSplit.length - 1];
|
||||||
|
|
||||||
if (["uninstall", "install", "update", "start", "stop"].includes(path)) {
|
if (["uninstall", "install", "update", "start", "stop"].includes(path)) {
|
||||||
await this._updateSupervisor();
|
fireEvent(this, "supervisor-store-refresh", { store: "supervisor" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path === "uninstall") {
|
if (path === "uninstall") {
|
||||||
@ -221,18 +219,6 @@ class HassioAddonDashboard extends LitElement {
|
|||||||
this.addon = undefined;
|
this.addon = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _updateSupervisor(): Promise<void> {
|
|
||||||
try {
|
|
||||||
const supervisor = await fetchHassioSupervisorInfo(this.hass);
|
|
||||||
fireEvent(this, "supervisor-update", { supervisor });
|
|
||||||
} catch (err) {
|
|
||||||
showAlertDialog(this, {
|
|
||||||
title: "Failed to fetch supervisor information",
|
|
||||||
text: extractApiErrorMessage(err),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -43,10 +43,13 @@ import {
|
|||||||
HassioAddonSetOptionParams,
|
HassioAddonSetOptionParams,
|
||||||
HassioAddonSetSecurityParams,
|
HassioAddonSetSecurityParams,
|
||||||
installHassioAddon,
|
installHassioAddon,
|
||||||
|
restartHassioAddon,
|
||||||
setHassioAddonOption,
|
setHassioAddonOption,
|
||||||
setHassioAddonSecurity,
|
setHassioAddonSecurity,
|
||||||
startHassioAddon,
|
startHassioAddon,
|
||||||
|
stopHassioAddon,
|
||||||
uninstallHassioAddon,
|
uninstallHassioAddon,
|
||||||
|
updateHassioAddon,
|
||||||
validateHassioAddonOption,
|
validateHassioAddonOption,
|
||||||
} from "../../../../src/data/hassio/addon";
|
} from "../../../../src/data/hassio/addon";
|
||||||
import {
|
import {
|
||||||
@ -196,13 +199,9 @@ class HassioAddonInfo extends LitElement {
|
|||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-call-api-button
|
<ha-progress-button @click=${this._updateClicked}>
|
||||||
.hass=${this.hass}
|
|
||||||
.disabled=${!this.addon.available}
|
|
||||||
path="hassio/addons/${this.addon.slug}/update"
|
|
||||||
>
|
|
||||||
Update
|
Update
|
||||||
</ha-call-api-button>
|
</ha-progress-button>
|
||||||
${this.addon.changelog
|
${this.addon.changelog
|
||||||
? html`
|
? html`
|
||||||
<mwc-button @click=${this._openChangelog}>
|
<mwc-button @click=${this._openChangelog}>
|
||||||
@ -579,20 +578,18 @@ class HassioAddonInfo extends LitElement {
|
|||||||
${this.addon.version
|
${this.addon.version
|
||||||
? this._computeIsRunning
|
? this._computeIsRunning
|
||||||
? html`
|
? html`
|
||||||
<ha-call-api-button
|
<ha-progress-button
|
||||||
class="warning"
|
class="warning"
|
||||||
.hass=${this.hass}
|
@click=${this._stopClicked}
|
||||||
.path="hassio/addons/${this.addon.slug}/stop"
|
|
||||||
>
|
>
|
||||||
Stop
|
Stop
|
||||||
</ha-call-api-button>
|
</ha-progress-button>
|
||||||
<ha-call-api-button
|
<ha-progress-button
|
||||||
class="warning"
|
class="warning"
|
||||||
.hass=${this.hass}
|
@click=${this._restartClicked}
|
||||||
.path="hassio/addons/${this.addon.slug}/restart"
|
|
||||||
>
|
>
|
||||||
Restart
|
Restart
|
||||||
</ha-call-api-button>
|
</ha-progress-button>
|
||||||
`
|
`
|
||||||
: html`
|
: html`
|
||||||
<ha-progress-button @click=${this._startClicked}>
|
<ha-progress-button @click=${this._startClicked}>
|
||||||
@ -883,6 +880,82 @@ class HassioAddonInfo extends LitElement {
|
|||||||
button.progress = false;
|
button.progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _stopClicked(ev: CustomEvent): Promise<void> {
|
||||||
|
const button = ev.currentTarget as any;
|
||||||
|
button.progress = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await stopHassioAddon(this.hass, this.addon.slug);
|
||||||
|
const eventdata = {
|
||||||
|
success: true,
|
||||||
|
response: undefined,
|
||||||
|
path: "stop",
|
||||||
|
};
|
||||||
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
|
} catch (err) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "Failed to stop addon",
|
||||||
|
text: extractApiErrorMessage(err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
button.progress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _restartClicked(ev: CustomEvent): Promise<void> {
|
||||||
|
const button = ev.currentTarget as any;
|
||||||
|
button.progress = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await restartHassioAddon(this.hass, this.addon.slug);
|
||||||
|
const eventdata = {
|
||||||
|
success: true,
|
||||||
|
response: undefined,
|
||||||
|
path: "stop",
|
||||||
|
};
|
||||||
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
|
} catch (err) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "Failed to restart addon",
|
||||||
|
text: extractApiErrorMessage(err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
button.progress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _updateClicked(ev: CustomEvent): Promise<void> {
|
||||||
|
const button = ev.currentTarget as any;
|
||||||
|
button.progress = true;
|
||||||
|
|
||||||
|
const confirmed = await showConfirmationDialog(this, {
|
||||||
|
title: this.addon.name,
|
||||||
|
text: "Are you sure you want to update this add-on?",
|
||||||
|
confirmText: "update add-on",
|
||||||
|
dismissText: "no",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) {
|
||||||
|
button.progress = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._error = undefined;
|
||||||
|
try {
|
||||||
|
await updateHassioAddon(this.hass, this.addon.slug);
|
||||||
|
const eventdata = {
|
||||||
|
success: true,
|
||||||
|
response: undefined,
|
||||||
|
path: "update",
|
||||||
|
};
|
||||||
|
fireEvent(this, "hass-api-called", eventdata);
|
||||||
|
} catch (err) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "Failed to update addon",
|
||||||
|
text: extractApiErrorMessage(err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
button.progress = false;
|
||||||
|
}
|
||||||
|
|
||||||
private async _startClicked(ev: CustomEvent): Promise<void> {
|
private async _startClicked(ev: CustomEvent): Promise<void> {
|
||||||
const button = ev.currentTarget as any;
|
const button = ev.currentTarget as any;
|
||||||
button.progress = true;
|
button.progress = true;
|
||||||
@ -891,10 +964,10 @@ class HassioAddonInfo extends LitElement {
|
|||||||
this.hass,
|
this.hass,
|
||||||
this.addon.slug
|
this.addon.slug
|
||||||
);
|
);
|
||||||
if (!validate.data.valid) {
|
if (!validate.valid) {
|
||||||
await showConfirmationDialog(this, {
|
await showConfirmationDialog(this, {
|
||||||
title: "Failed to start addon - configuration validation failed!",
|
title: "Failed to start addon - configuration validation failed!",
|
||||||
text: validate.data.message.split(" Got ")[0],
|
text: validate.message.split(" Got ")[0],
|
||||||
confirm: () => this._openConfiguration(),
|
confirm: () => this._openConfiguration(),
|
||||||
confirmText: "Go to configuration",
|
confirmText: "Go to configuration",
|
||||||
dismissText: "Cancel",
|
dismissText: "Cancel",
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import "../../../src/components/buttons/ha-progress-button";
|
import "../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import "../../../src/components/ha-svg-icon";
|
import "../../../src/components/ha-svg-icon";
|
||||||
@ -64,6 +65,7 @@ export class HassioUpdate extends LitElement {
|
|||||||
<div class="card-group">
|
<div class="card-group">
|
||||||
${this._renderUpdateCard(
|
${this._renderUpdateCard(
|
||||||
"Home Assistant Core",
|
"Home Assistant Core",
|
||||||
|
"core",
|
||||||
this.supervisor.core,
|
this.supervisor.core,
|
||||||
"hassio/homeassistant/update",
|
"hassio/homeassistant/update",
|
||||||
`https://${
|
`https://${
|
||||||
@ -72,6 +74,7 @@ export class HassioUpdate extends LitElement {
|
|||||||
)}
|
)}
|
||||||
${this._renderUpdateCard(
|
${this._renderUpdateCard(
|
||||||
"Supervisor",
|
"Supervisor",
|
||||||
|
"supervisor",
|
||||||
this.supervisor.supervisor,
|
this.supervisor.supervisor,
|
||||||
"hassio/supervisor/update",
|
"hassio/supervisor/update",
|
||||||
`https://github.com//home-assistant/hassio/releases/tag/${this.supervisor.supervisor.version_latest}`
|
`https://github.com//home-assistant/hassio/releases/tag/${this.supervisor.supervisor.version_latest}`
|
||||||
@ -79,6 +82,7 @@ export class HassioUpdate extends LitElement {
|
|||||||
${this.supervisor.host.features.includes("hassos")
|
${this.supervisor.host.features.includes("hassos")
|
||||||
? this._renderUpdateCard(
|
? this._renderUpdateCard(
|
||||||
"Operating System",
|
"Operating System",
|
||||||
|
"os",
|
||||||
this.supervisor.os,
|
this.supervisor.os,
|
||||||
"hassio/os/update",
|
"hassio/os/update",
|
||||||
`https://github.com//home-assistant/hassos/releases/tag/${this.supervisor.os.version_latest}`
|
`https://github.com//home-assistant/hassos/releases/tag/${this.supervisor.os.version_latest}`
|
||||||
@ -91,6 +95,7 @@ export class HassioUpdate extends LitElement {
|
|||||||
|
|
||||||
private _renderUpdateCard(
|
private _renderUpdateCard(
|
||||||
name: string,
|
name: string,
|
||||||
|
key: string,
|
||||||
object: HassioHomeAssistantInfo | HassioSupervisorInfo | HassioHassOSInfo,
|
object: HassioHomeAssistantInfo | HassioSupervisorInfo | HassioHassOSInfo,
|
||||||
apiPath: string,
|
apiPath: string,
|
||||||
releaseNotesUrl: string
|
releaseNotesUrl: string
|
||||||
@ -116,6 +121,7 @@ export class HassioUpdate extends LitElement {
|
|||||||
<ha-progress-button
|
<ha-progress-button
|
||||||
.apiPath=${apiPath}
|
.apiPath=${apiPath}
|
||||||
.name=${name}
|
.name=${name}
|
||||||
|
.key=${key}
|
||||||
.version=${object.version_latest}
|
.version=${object.version_latest}
|
||||||
@click=${this._confirmUpdate}
|
@click=${this._confirmUpdate}
|
||||||
>
|
>
|
||||||
@ -142,6 +148,7 @@ export class HassioUpdate extends LitElement {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
|
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
|
||||||
|
fireEvent(this, "supervisor-store-refresh", { store: item.key });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Only show an error if the status code was not expected (user behind proxy)
|
// Only show an error if the status code was not expected (user behind proxy)
|
||||||
// or no status at all(connection terminated)
|
// or no status at all(connection terminated)
|
||||||
|
@ -3,7 +3,9 @@ import { atLeastVersion } from "../../src/common/config/version";
|
|||||||
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
||||||
import { fireEvent } from "../../src/common/dom/fire_event";
|
import { fireEvent } from "../../src/common/dom/fire_event";
|
||||||
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
||||||
|
import { supervisorStore } from "../../src/data/supervisor/supervisor";
|
||||||
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
||||||
|
import "../../src/layouts/hass-loading-screen";
|
||||||
import { HomeAssistant, Route } from "../../src/types";
|
import { HomeAssistant, Route } from "../../src/types";
|
||||||
import "./hassio-router";
|
import "./hassio-router";
|
||||||
import { SupervisorBaseElement } from "./supervisor-base-element";
|
import { SupervisorBaseElement } from "./supervisor-base-element";
|
||||||
@ -71,8 +73,15 @@ export class HassioMain extends SupervisorBaseElement {
|
|||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.supervisor || !this.hass) {
|
if (!this.supervisor || !this.hass) {
|
||||||
return html``;
|
return html`<hass-loading-screen></hass-loading-screen>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
Object.keys(supervisorStore).some((store) => !this.supervisor![store])
|
||||||
|
) {
|
||||||
|
return html`<hass-loading-screen></hass-loading-screen>`;
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hassio-router
|
<hassio-router
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
@ -53,12 +53,13 @@ class HassioRouter extends HassRouterPage {
|
|||||||
const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail;
|
const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail;
|
||||||
|
|
||||||
el.hass = this.hass;
|
el.hass = this.hass;
|
||||||
el.supervisor = this.supervisor;
|
|
||||||
el.narrow = this.narrow;
|
el.narrow = this.narrow;
|
||||||
el.route = route;
|
el.route = route;
|
||||||
|
|
||||||
if (el.localName === "hassio-ingress-view") {
|
if (el.localName === "hassio-ingress-view") {
|
||||||
el.ingressPanel = this.panel.config && this.panel.config.ingress;
|
el.ingressPanel = this.panel.config && this.panel.config.ingress;
|
||||||
|
} else {
|
||||||
|
el.supervisor = this.supervisor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
import { LitElement, property, PropertyValues } from "lit-element";
|
import { Collection, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
|
import {
|
||||||
|
internalProperty,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
PropertyValues,
|
||||||
|
} from "lit-element";
|
||||||
|
import { atLeastVersion } from "../../src/common/config/version";
|
||||||
|
import { fetchHassioAddonsInfo } from "../../src/data/hassio/addon";
|
||||||
|
import { HassioResponse } from "../../src/data/hassio/common";
|
||||||
import {
|
import {
|
||||||
fetchHassioHassOsInfo,
|
fetchHassioHassOsInfo,
|
||||||
fetchHassioHostInfo,
|
fetchHassioHostInfo,
|
||||||
@ -10,13 +19,20 @@ import {
|
|||||||
fetchHassioInfo,
|
fetchHassioInfo,
|
||||||
fetchHassioSupervisorInfo,
|
fetchHassioSupervisorInfo,
|
||||||
} from "../../src/data/hassio/supervisor";
|
} from "../../src/data/hassio/supervisor";
|
||||||
import { Supervisor } from "../../src/data/supervisor/supervisor";
|
import {
|
||||||
|
getSupervisorEventCollection,
|
||||||
|
subscribeSupervisorEvents,
|
||||||
|
Supervisor,
|
||||||
|
SupervisorObject,
|
||||||
|
supervisorStore,
|
||||||
|
} from "../../src/data/supervisor/supervisor";
|
||||||
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
||||||
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
|
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"supervisor-update": Partial<Supervisor>;
|
"supervisor-update": Partial<Supervisor>;
|
||||||
|
"supervisor-store-refresh": { store: SupervisorObject };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +41,20 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
) {
|
) {
|
||||||
@property({ attribute: false }) public supervisor?: Supervisor;
|
@property({ attribute: false }) public supervisor?: Supervisor;
|
||||||
|
|
||||||
|
@internalProperty() private _unsubs: Record<string, UnsubscribeFunc> = {};
|
||||||
|
|
||||||
|
@internalProperty() private _collections: Record<
|
||||||
|
string,
|
||||||
|
Collection<unknown>
|
||||||
|
> = {};
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
Object.keys(this._unsubs).forEach((unsub) => {
|
||||||
|
this._unsubs[unsub]();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected _updateSupervisor(obj: Partial<Supervisor>): void {
|
protected _updateSupervisor(obj: Partial<Supervisor>): void {
|
||||||
this.supervisor = { ...this.supervisor!, ...obj };
|
this.supervisor = { ...this.supervisor!, ...obj };
|
||||||
}
|
}
|
||||||
@ -32,13 +62,59 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
protected firstUpdated(changedProps: PropertyValues): void {
|
protected firstUpdated(changedProps: PropertyValues): void {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this._initSupervisor();
|
this._initSupervisor();
|
||||||
this.addEventListener("supervisor-update", (ev) =>
|
}
|
||||||
this._updateSupervisor(ev.detail)
|
|
||||||
|
private async _handleSupervisorStoreRefreshEvent(ev) {
|
||||||
|
const store = ev.detail.store;
|
||||||
|
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
|
||||||
|
this._collections[store].refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await this.hass.callApi<HassioResponse<any>>(
|
||||||
|
"GET",
|
||||||
|
`hassio${supervisorStore[store]}`
|
||||||
);
|
);
|
||||||
|
this._updateSupervisor({ [store]: response.data });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _initSupervisor(): Promise<void> {
|
private async _initSupervisor(): Promise<void> {
|
||||||
|
this.addEventListener(
|
||||||
|
"supervisor-store-refresh",
|
||||||
|
this._handleSupervisorStoreRefreshEvent
|
||||||
|
);
|
||||||
|
|
||||||
|
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
|
||||||
|
Object.keys(supervisorStore).forEach((store) => {
|
||||||
|
this._unsubs[store] = subscribeSupervisorEvents(
|
||||||
|
this.hass,
|
||||||
|
(data) => this._updateSupervisor({ [store]: data }),
|
||||||
|
store,
|
||||||
|
supervisorStore[store]
|
||||||
|
);
|
||||||
|
if (this._collections[store]) {
|
||||||
|
this._collections[store].refresh();
|
||||||
|
} else {
|
||||||
|
this._collections[store] = getSupervisorEventCollection(
|
||||||
|
this.hass.connection,
|
||||||
|
store,
|
||||||
|
supervisorStore[store]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.supervisor === undefined) {
|
||||||
|
Object.keys(this._collections).forEach((collection) =>
|
||||||
|
this._updateSupervisor({
|
||||||
|
[collection]: this._collections[collection].state,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const [
|
const [
|
||||||
|
addon,
|
||||||
supervisor,
|
supervisor,
|
||||||
host,
|
host,
|
||||||
core,
|
core,
|
||||||
@ -47,6 +123,7 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
network,
|
network,
|
||||||
resolution,
|
resolution,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
|
fetchHassioAddonsInfo(this.hass),
|
||||||
fetchHassioSupervisorInfo(this.hass),
|
fetchHassioSupervisorInfo(this.hass),
|
||||||
fetchHassioHostInfo(this.hass),
|
fetchHassioHostInfo(this.hass),
|
||||||
fetchHassioHomeAssistantInfo(this.hass),
|
fetchHassioHomeAssistantInfo(this.hass),
|
||||||
@ -57,6 +134,7 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
this.supervisor = {
|
this.supervisor = {
|
||||||
|
addon,
|
||||||
supervisor,
|
supervisor,
|
||||||
host,
|
host,
|
||||||
core,
|
core,
|
||||||
@ -65,5 +143,9 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
network,
|
network,
|
||||||
resolution,
|
resolution,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.addEventListener("supervisor-update", (ev) =>
|
||||||
|
this._updateSupervisor(ev.detail)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import "../../../src/components/buttons/ha-progress-button";
|
import "../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
@ -166,6 +167,7 @@ class HassioCoreInfo extends LitElement {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await updateCore(this.hass);
|
await updateCore(this.hass);
|
||||||
|
fireEvent(this, "supervisor-store-refresh", { store: "core" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Failed to update Home Assistant Core",
|
title: "Failed to update Home Assistant Core",
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
import "../../../src/components/buttons/ha-progress-button";
|
import "../../../src/components/buttons/ha-progress-button";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
@ -26,7 +27,6 @@ import { fetchHassioHardwareInfo } from "../../../src/data/hassio/hardware";
|
|||||||
import {
|
import {
|
||||||
changeHostOptions,
|
changeHostOptions,
|
||||||
configSyncOS,
|
configSyncOS,
|
||||||
fetchHassioHostInfo,
|
|
||||||
rebootHost,
|
rebootHost,
|
||||||
shutdownHost,
|
shutdownHost,
|
||||||
updateOS,
|
updateOS,
|
||||||
@ -340,6 +340,7 @@ class HassioHostInfo extends LitElement {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await updateOS(this.hass);
|
await updateOS(this.hass);
|
||||||
|
fireEvent(this, "supervisor-store-refresh", { store: "os" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Failed to update",
|
title: "Failed to update",
|
||||||
@ -368,8 +369,7 @@ class HassioHostInfo extends LitElement {
|
|||||||
if (hostname && hostname !== curHostname) {
|
if (hostname && hostname !== curHostname) {
|
||||||
try {
|
try {
|
||||||
await changeHostOptions(this.hass, { hostname });
|
await changeHostOptions(this.hass, { hostname });
|
||||||
const host = await fetchHassioHostInfo(this.hass);
|
fireEvent(this, "supervisor-store-refresh", { store: "host" });
|
||||||
fireEvent(this, "supervisor-update", { host });
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Setting hostname failed",
|
title: "Setting hostname failed",
|
||||||
@ -382,8 +382,7 @@ class HassioHostInfo extends LitElement {
|
|||||||
private async _importFromUSB(): Promise<void> {
|
private async _importFromUSB(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await configSyncOS(this.hass);
|
await configSyncOS(this.hass);
|
||||||
const host = await fetchHassioHostInfo(this.hass);
|
fireEvent(this, "supervisor-store-refresh", { store: "host" });
|
||||||
fireEvent(this, "supervisor-update", { host });
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Failed to import from USB",
|
title: "Failed to import from USB",
|
||||||
@ -393,8 +392,12 @@ class HassioHostInfo extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
private async _loadData(): Promise<void> {
|
||||||
const network = await fetchNetworkInfo(this.hass);
|
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
|
||||||
fireEvent(this, "supervisor-update", { network });
|
fireEvent(this, "supervisor-store-refresh", { store: "network" });
|
||||||
|
} else {
|
||||||
|
const network = await fetchNetworkInfo(this.hass);
|
||||||
|
fireEvent(this, "supervisor-update", { network });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
|
@ -19,7 +19,6 @@ import {
|
|||||||
HassioStats,
|
HassioStats,
|
||||||
} from "../../../src/data/hassio/common";
|
} from "../../../src/data/hassio/common";
|
||||||
import {
|
import {
|
||||||
fetchHassioSupervisorInfo,
|
|
||||||
reloadSupervisor,
|
reloadSupervisor,
|
||||||
restartSupervisor,
|
restartSupervisor,
|
||||||
setSupervisorOption,
|
setSupervisorOption,
|
||||||
@ -318,8 +317,7 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
|
|
||||||
private async _reloadSupervisor(): Promise<void> {
|
private async _reloadSupervisor(): Promise<void> {
|
||||||
await reloadSupervisor(this.hass);
|
await reloadSupervisor(this.hass);
|
||||||
const supervisor = await fetchHassioSupervisorInfo(this.hass);
|
fireEvent(this, "supervisor-store-refresh", { store: "supervisor" });
|
||||||
fireEvent(this, "supervisor-update", { supervisor });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _supervisorRestart(ev: CustomEvent): Promise<void> {
|
private async _supervisorRestart(ev: CustomEvent): Promise<void> {
|
||||||
@ -368,6 +366,7 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await updateSupervisor(this.hass);
|
await updateSupervisor(this.hass);
|
||||||
|
fireEvent(this, "supervisor-store-refresh", { store: "supervisor" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Failed to update the supervisor",
|
title: "Failed to update the supervisor",
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
export const atLeastVersion = (
|
export const atLeastVersion = (
|
||||||
version: string,
|
version: string,
|
||||||
major: number,
|
major: number,
|
||||||
minor: number
|
minor: number,
|
||||||
|
patch?: number
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const [haMajor, haMinor] = version.split(".", 2);
|
const [haMajor, haMinor, haPatch] = version.split(".", 3);
|
||||||
return (
|
return (
|
||||||
Number(haMajor) > major ||
|
Number(haMajor) > major ||
|
||||||
(Number(haMajor) === major && Number(haMinor) >= minor)
|
(Number(haMajor) === major && Number(haMinor) >= minor) ||
|
||||||
|
(patch !== undefined &&
|
||||||
|
Number(haMajor) === major && Number(haMinor) === minor &&
|
||||||
|
Number(haPatch) >= patch)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HaFormSchema } from "../../components/ha-form/ha-form";
|
import { HaFormSchema } from "../../components/ha-form/ha-form";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { SupervisorArch } from "../supervisor/supervisor";
|
import { SupervisorArch } from "../supervisor/supervisor";
|
||||||
@ -102,10 +103,28 @@ export interface HassioAddonSetOptionParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const reloadHassioAddons = async (hass: HomeAssistant) => {
|
export const reloadHassioAddons = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/addons/reload",
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await hass.callApi<HassioResponse<void>>("POST", `hassio/addons/reload`);
|
await hass.callApi<HassioResponse<void>>("POST", `hassio/addons/reload`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchHassioAddonsInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioAddonsInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioAddonsInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/addons",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioAddonsInfo>>("GET", `hassio/addons`)
|
await hass.callApi<HassioResponse<HassioAddonsInfo>>("GET", `hassio/addons`)
|
||||||
);
|
);
|
||||||
@ -114,7 +133,15 @@ export const fetchHassioAddonsInfo = async (hass: HomeAssistant) => {
|
|||||||
export const fetchHassioAddonInfo = async (
|
export const fetchHassioAddonInfo = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
slug: string
|
slug: string
|
||||||
) => {
|
): Promise<HassioAddonDetails> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/info`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioAddonDetails>>(
|
await hass.callApi<HassioResponse<HassioAddonDetails>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -149,6 +176,16 @@ export const setHassioAddonOption = async (
|
|||||||
slug: string,
|
slug: string,
|
||||||
data: HassioAddonSetOptionParams
|
data: HassioAddonSetOptionParams
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/options`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/addons/${slug}/options`,
|
`hassio/addons/${slug}/options`,
|
||||||
@ -159,21 +196,64 @@ export const setHassioAddonOption = async (
|
|||||||
export const validateHassioAddonOption = async (
|
export const validateHassioAddonOption = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
slug: string
|
slug: string
|
||||||
) => {
|
): Promise<{ message: string; valid: boolean }> => {
|
||||||
return await hass.callApi<
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
HassioResponse<{ message: string; valid: boolean }>
|
return await hass.callWS({
|
||||||
>("POST", `hassio/addons/${slug}/options/validate`);
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/options/validate`,
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
await hass.callApi<HassioResponse<{ message: string; valid: boolean }>>(
|
||||||
|
"POST",
|
||||||
|
`hassio/addons/${slug}/options/validate`
|
||||||
|
)
|
||||||
|
).data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const startHassioAddon = async (hass: HomeAssistant, slug: string) => {
|
export const startHassioAddon = async (hass: HomeAssistant, slug: string) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/start`,
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hass.callApi<string>("POST", `hassio/addons/${slug}/start`);
|
return hass.callApi<string>("POST", `hassio/addons/${slug}/start`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const stopHassioAddon = async (hass: HomeAssistant, slug: string) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/stop`,
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return hass.callApi<string>("POST", `hassio/addons/${slug}/stop`);
|
||||||
|
};
|
||||||
|
|
||||||
export const setHassioAddonSecurity = async (
|
export const setHassioAddonSecurity = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
slug: string,
|
slug: string,
|
||||||
data: HassioAddonSetSecurityParams
|
data: HassioAddonSetSecurityParams
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/security`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/addons/${slug}/security`,
|
`hassio/addons/${slug}/security`,
|
||||||
@ -181,15 +261,61 @@ export const setHassioAddonSecurity = async (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const installHassioAddon = async (hass: HomeAssistant, slug: string) => {
|
export const installHassioAddon = async (
|
||||||
return hass.callApi<HassioResponse<void>>(
|
hass: HomeAssistant,
|
||||||
|
slug: string
|
||||||
|
): Promise<void> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/install`,
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/addons/${slug}/install`
|
`hassio/addons/${slug}/install`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const restartHassioAddon = async (hass: HomeAssistant, slug: string) => {
|
export const updateHassioAddon = async (
|
||||||
return hass.callApi<HassioResponse<void>>(
|
hass: HomeAssistant,
|
||||||
|
slug: string
|
||||||
|
): Promise<void> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/update`,
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.callApi<HassioResponse<void>>(
|
||||||
|
"POST",
|
||||||
|
`hassio/addons/${slug}/update`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const restartHassioAddon = async (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
slug: string
|
||||||
|
): Promise<void> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/restart`,
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/addons/${slug}/restart`
|
`hassio/addons/${slug}/restart`
|
||||||
);
|
);
|
||||||
@ -199,6 +325,16 @@ export const uninstallHassioAddon = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
slug: string
|
slug: string
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/addons/${slug}/uninstall`,
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/addons/${slug}/uninstall`
|
`hassio/addons/${slug}/uninstall`
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
export interface HassioResponse<T> {
|
export interface HassioResponse<T> {
|
||||||
@ -33,6 +34,14 @@ export const fetchHassioStats = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
container: string
|
container: string
|
||||||
): Promise<HassioStats> => {
|
): Promise<HassioStats> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/${container}/stats`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioStats>>(
|
await hass.callApi<HassioResponse<HassioStats>>(
|
||||||
"GET",
|
"GET",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -5,7 +6,17 @@ interface HassioDockerRegistries {
|
|||||||
[key: string]: { username: string; password?: string };
|
[key: string]: { username: string; password?: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchHassioDockerRegistries = async (hass: HomeAssistant) => {
|
export const fetchHassioDockerRegistries = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioDockerRegistries> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/docker/registries`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioDockerRegistries>>(
|
await hass.callApi<HassioResponse<HassioDockerRegistries>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -18,6 +29,16 @@ export const addHassioDockerRegistry = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
data: HassioDockerRegistries
|
data: HassioDockerRegistries
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/docker/registries`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<HassioDockerRegistries>>(
|
await hass.callApi<HassioResponse<HassioDockerRegistries>>(
|
||||||
"POST",
|
"POST",
|
||||||
"hassio/docker/registries",
|
"hassio/docker/registries",
|
||||||
@ -29,6 +50,15 @@ export const removeHassioDockerRegistry = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
registry: string
|
registry: string
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/docker/registries/${registry}`,
|
||||||
|
method: "delete",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"DELETE",
|
"DELETE",
|
||||||
`hassio/docker/registries/${registry}`
|
`hassio/docker/registries/${registry}`
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -21,7 +22,17 @@ export interface HassioHardwareInfo {
|
|||||||
audio: Record<string, unknown>;
|
audio: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchHassioHardwareAudio = async (hass: HomeAssistant) => {
|
export const fetchHassioHardwareAudio = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioHardwareAudioList> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/hardware/audio`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioHardwareAudioList>>(
|
await hass.callApi<HassioResponse<HassioHardwareAudioList>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -30,7 +41,17 @@ export const fetchHassioHardwareAudio = async (hass: HomeAssistant) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchHassioHardwareInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioHardwareInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioHardwareInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/hardware/info`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioHardwareInfo>>(
|
await hass.callApi<HassioResponse<HassioHardwareInfo>>(
|
||||||
"GET",
|
"GET",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -23,7 +24,17 @@ export interface HassioHassOSInfo {
|
|||||||
version: string | null;
|
version: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchHassioHostInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioHostInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioHostInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/host/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const response = await hass.callApi<HassioResponse<HassioHostInfo>>(
|
const response = await hass.callApi<HassioResponse<HassioHostInfo>>(
|
||||||
"GET",
|
"GET",
|
||||||
"hassio/host/info"
|
"hassio/host/info"
|
||||||
@ -31,7 +42,17 @@ export const fetchHassioHostInfo = async (hass: HomeAssistant) => {
|
|||||||
return hassioApiResultExtractor(response);
|
return hassioApiResultExtractor(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchHassioHassOsInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioHassOsInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioHassOSInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/os/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioHassOSInfo>>(
|
await hass.callApi<HassioResponse<HassioHassOSInfo>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -41,22 +62,67 @@ export const fetchHassioHassOsInfo = async (hass: HomeAssistant) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const rebootHost = async (hass: HomeAssistant) => {
|
export const rebootHost = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/host/reboot",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hass.callApi<HassioResponse<void>>("POST", "hassio/host/reboot");
|
return hass.callApi<HassioResponse<void>>("POST", "hassio/host/reboot");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const shutdownHost = async (hass: HomeAssistant) => {
|
export const shutdownHost = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/host/shutdown",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hass.callApi<HassioResponse<void>>("POST", "hassio/host/shutdown");
|
return hass.callApi<HassioResponse<void>>("POST", "hassio/host/shutdown");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateOS = async (hass: HomeAssistant) => {
|
export const updateOS = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/os/update",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hass.callApi<HassioResponse<void>>("POST", "hassio/os/update");
|
return hass.callApi<HassioResponse<void>>("POST", "hassio/os/update");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const configSyncOS = async (hass: HomeAssistant) => {
|
export const configSyncOS = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "os/config/sync",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hass.callApi<HassioResponse<void>>("POST", "hassio/os/config/sync");
|
return hass.callApi<HassioResponse<void>>("POST", "hassio/os/config/sync");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const changeHostOptions = async (hass: HomeAssistant, options: any) => {
|
export const changeHostOptions = async (hass: HomeAssistant, options: any) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/host/options",
|
||||||
|
method: "post",
|
||||||
|
data: options,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hass.callApi<HassioResponse<void>>(
|
return hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
"hassio/host/options",
|
"hassio/host/options",
|
||||||
|
@ -1,26 +1,49 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { HassioResponse } from "./common";
|
import { HassioResponse } from "./common";
|
||||||
import { CreateSessionResponse } from "./supervisor";
|
import { CreateSessionResponse } from "./supervisor";
|
||||||
|
|
||||||
export const createHassioSession = async (hass: HomeAssistant) => {
|
function setIngressCookie(session: string): string {
|
||||||
const response = await hass.callApi<HassioResponse<CreateSessionResponse>>(
|
document.cookie = `ingress_session=${session};path=/api/hassio_ingress/;SameSite=Strict${
|
||||||
"POST",
|
|
||||||
"hassio/ingress/session"
|
|
||||||
);
|
|
||||||
document.cookie = `ingress_session=${
|
|
||||||
response.data.session
|
|
||||||
};path=/api/hassio_ingress/;SameSite=Strict${
|
|
||||||
location.protocol === "https:" ? ";Secure" : ""
|
location.protocol === "https:" ? ";Secure" : ""
|
||||||
}`;
|
}`;
|
||||||
return response.data.session;
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createHassioSession = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<string> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
const wsResponse: { session: string } = await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/ingress/session",
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
return setIngressCookie(wsResponse.session);
|
||||||
|
}
|
||||||
|
|
||||||
|
const restResponse: { data: { session: string } } = await hass.callApi<
|
||||||
|
HassioResponse<CreateSessionResponse>
|
||||||
|
>("POST", "hassio/ingress/session");
|
||||||
|
return setIngressCookie(restResponse.data.session);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateHassioSession = async (
|
export const validateHassioSession = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
session: string
|
session: string
|
||||||
) =>
|
): Promise<void> => {
|
||||||
await hass.callApi<HassioResponse<null>>(
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/ingress/validate_session",
|
||||||
|
method: "post",
|
||||||
|
data: session,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
"hassio/ingress/validate_session",
|
"hassio/ingress/validate_session",
|
||||||
{ session }
|
{ session }
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -51,7 +52,17 @@ export interface NetworkInfo {
|
|||||||
docker: DockerNetwork;
|
docker: DockerNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchNetworkInfo = async (hass: HomeAssistant) => {
|
export const fetchNetworkInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<NetworkInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/network/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<NetworkInfo>>(
|
await hass.callApi<HassioResponse<NetworkInfo>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -65,6 +76,17 @@ export const updateNetworkInterface = async (
|
|||||||
network_interface: string,
|
network_interface: string,
|
||||||
options: Partial<NetworkInterface>
|
options: Partial<NetworkInterface>
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/network/interface/${network_interface}/update`,
|
||||||
|
method: "post",
|
||||||
|
data: options,
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<NetworkInfo>>(
|
await hass.callApi<HassioResponse<NetworkInfo>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/network/interface/${network_interface}/update`,
|
`hassio/network/interface/${network_interface}/update`,
|
||||||
@ -75,7 +97,16 @@ export const updateNetworkInterface = async (
|
|||||||
export const accesspointScan = async (
|
export const accesspointScan = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
network_interface: string
|
network_interface: string
|
||||||
) => {
|
): Promise<AccessPoints> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/network/interface/${network_interface}/accesspoints`,
|
||||||
|
method: "get",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<AccessPoints>>(
|
await hass.callApi<HassioResponse<AccessPoints>>(
|
||||||
"GET",
|
"GET",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -8,7 +9,17 @@ export interface HassioResolution {
|
|||||||
suggestions: string[];
|
suggestions: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchHassioResolution = async (hass: HomeAssistant) => {
|
export const fetchHassioResolution = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioResolution> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/resolution/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioResolution>>(
|
await hass.callApi<HassioResponse<HassioResolution>>(
|
||||||
"GET",
|
"GET",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||||
|
|
||||||
@ -33,7 +34,18 @@ export interface HassioPartialSnapshotCreateParams {
|
|||||||
password?: string;
|
password?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchHassioSnapshots = async (hass: HomeAssistant) => {
|
export const fetchHassioSnapshots = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioSnapshot[]> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
const data: { snapshots: HassioSnapshot[] } = await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/snapshots`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
return data.snapshots;
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<{ snapshots: HassioSnapshot[] }>>(
|
await hass.callApi<HassioResponse<{ snapshots: HassioSnapshot[] }>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -45,8 +57,15 @@ export const fetchHassioSnapshots = async (hass: HomeAssistant) => {
|
|||||||
export const fetchHassioSnapshotInfo = async (
|
export const fetchHassioSnapshotInfo = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
snapshot: string
|
snapshot: string
|
||||||
) => {
|
): Promise<HassioSnapshotDetail> => {
|
||||||
if (hass) {
|
if (hass) {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: `/snapshots/${snapshot}/info`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioSnapshotDetail>>(
|
await hass.callApi<HassioResponse<HassioSnapshotDetail>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -63,6 +82,15 @@ export const fetchHassioSnapshotInfo = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const reloadHassioSnapshots = async (hass: HomeAssistant) => {
|
export const reloadHassioSnapshots = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/snapshots/reload",
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>("POST", `hassio/snapshots/reload`);
|
await hass.callApi<HassioResponse<void>>("POST", `hassio/snapshots/reload`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,6 +98,15 @@ export const createHassioFullSnapshot = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
data: HassioFullSnapshotCreateParams
|
data: HassioFullSnapshotCreateParams
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/snapshots/new/full",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/snapshots/new/full`,
|
`hassio/snapshots/new/full`,
|
||||||
@ -81,6 +118,17 @@ export const createHassioPartialSnapshot = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
data: HassioFullSnapshotCreateParams
|
data: HassioFullSnapshotCreateParams
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/snapshots/new/partial",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
`hassio/snapshots/new/partial`,
|
`hassio/snapshots/new/partial`,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant, PanelInfo } from "../../types";
|
import { HomeAssistant, PanelInfo } from "../../types";
|
||||||
import { SupervisorArch } from "../supervisor/supervisor";
|
import { SupervisorArch } from "../supervisor/supervisor";
|
||||||
import { HassioAddonInfo, HassioAddonRepository } from "./addon";
|
import { HassioAddonInfo, HassioAddonRepository } from "./addon";
|
||||||
@ -83,18 +84,57 @@ export interface SupervisorOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const reloadSupervisor = async (hass: HomeAssistant) => {
|
export const reloadSupervisor = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/supervisor/reload",
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>("POST", `hassio/supervisor/reload`);
|
await hass.callApi<HassioResponse<void>>("POST", `hassio/supervisor/reload`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const restartSupervisor = async (hass: HomeAssistant) => {
|
export const restartSupervisor = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/supervisor/restart",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>("POST", `hassio/supervisor/restart`);
|
await hass.callApi<HassioResponse<void>>("POST", `hassio/supervisor/restart`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateSupervisor = async (hass: HomeAssistant) => {
|
export const updateSupervisor = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/supervisor/update",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>("POST", `hassio/supervisor/update`);
|
await hass.callApi<HassioResponse<void>>("POST", `hassio/supervisor/update`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchHassioHomeAssistantInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioHomeAssistantInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioHomeAssistantInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/core/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioHomeAssistantInfo>>(
|
await hass.callApi<HassioResponse<HassioHomeAssistantInfo>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -103,7 +143,17 @@ export const fetchHassioHomeAssistantInfo = async (hass: HomeAssistant) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchHassioSupervisorInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioSupervisorInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioSupervisorInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/supervisor/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioSupervisorInfo>>(
|
await hass.callApi<HassioResponse<HassioSupervisorInfo>>(
|
||||||
"GET",
|
"GET",
|
||||||
@ -112,7 +162,17 @@ export const fetchHassioSupervisorInfo = async (hass: HomeAssistant) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchHassioInfo = async (hass: HomeAssistant) => {
|
export const fetchHassioInfo = async (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<HassioInfo> => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
return await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/info",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return hassioApiResultExtractor(
|
return hassioApiResultExtractor(
|
||||||
await hass.callApi<HassioResponse<HassioInfo>>("GET", "hassio/info")
|
await hass.callApi<HassioResponse<HassioInfo>>("GET", "hassio/info")
|
||||||
);
|
);
|
||||||
@ -129,6 +189,16 @@ export const setSupervisorOption = async (
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
data: SupervisorOptions
|
data: SupervisorOptions
|
||||||
) => {
|
) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/supervisor/options",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>(
|
await hass.callApi<HassioResponse<void>>(
|
||||||
"POST",
|
"POST",
|
||||||
"hassio/supervisor/options",
|
"hassio/supervisor/options",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { atLeastVersion } from "../../common/config/version";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { HassioResponse } from "../hassio/common";
|
import { HassioResponse } from "../hassio/common";
|
||||||
|
|
||||||
@ -6,5 +7,15 @@ export const restartCore = async (hass: HomeAssistant) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const updateCore = async (hass: HomeAssistant) => {
|
export const updateCore = async (hass: HomeAssistant) => {
|
||||||
|
if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
|
||||||
|
await hass.callWS({
|
||||||
|
type: "supervisor/api",
|
||||||
|
endpoint: "/core/update",
|
||||||
|
method: "post",
|
||||||
|
timeout: null,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await hass.callApi<HassioResponse<void>>("POST", `hassio/core/update`);
|
await hass.callApi<HassioResponse<void>>("POST", `hassio/core/update`);
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import { Connection, getCollection } from "home-assistant-js-websocket";
|
||||||
|
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
import { HassioAddonsInfo } from "../hassio/addon";
|
||||||
import { HassioHassOSInfo, HassioHostInfo } from "../hassio/host";
|
import { HassioHassOSInfo, HassioHostInfo } from "../hassio/host";
|
||||||
import { NetworkInfo } from "../hassio/network";
|
import { NetworkInfo } from "../hassio/network";
|
||||||
import { HassioResolution } from "../hassio/resolution";
|
import { HassioResolution } from "../hassio/resolution";
|
||||||
@ -7,7 +11,46 @@ import {
|
|||||||
HassioSupervisorInfo,
|
HassioSupervisorInfo,
|
||||||
} from "../hassio/supervisor";
|
} from "../hassio/supervisor";
|
||||||
|
|
||||||
|
export const supervisorWSbaseCommand = {
|
||||||
|
type: "supervisor/api",
|
||||||
|
method: "GET",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const supervisorStore = {
|
||||||
|
host: "/host/info",
|
||||||
|
supervisor: "/supervisor/info",
|
||||||
|
info: "/info",
|
||||||
|
core: "/core/info",
|
||||||
|
network: "/network/info",
|
||||||
|
resolution: "/resolution/info",
|
||||||
|
os: "/os/info",
|
||||||
|
addon: "/addons",
|
||||||
|
};
|
||||||
|
|
||||||
export type SupervisorArch = "armhf" | "armv7" | "aarch64" | "i386" | "amd64";
|
export type SupervisorArch = "armhf" | "armv7" | "aarch64" | "i386" | "amd64";
|
||||||
|
export type SupervisorObject =
|
||||||
|
| "host"
|
||||||
|
| "supervisor"
|
||||||
|
| "info"
|
||||||
|
| "core"
|
||||||
|
| "network"
|
||||||
|
| "resolution"
|
||||||
|
| "os"
|
||||||
|
| "addon";
|
||||||
|
|
||||||
|
interface supervisorApiRequest {
|
||||||
|
endpoint: string;
|
||||||
|
method?: "get" | "post" | "delete" | "put";
|
||||||
|
force_rest?: boolean;
|
||||||
|
data?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SupervisorEvent {
|
||||||
|
event: string;
|
||||||
|
update_key?: SupervisorObject;
|
||||||
|
data?: any;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Supervisor {
|
export interface Supervisor {
|
||||||
host: HassioHostInfo;
|
host: HassioHostInfo;
|
||||||
@ -17,4 +60,77 @@ export interface Supervisor {
|
|||||||
network: NetworkInfo;
|
network: NetworkInfo;
|
||||||
resolution: HassioResolution;
|
resolution: HassioResolution;
|
||||||
os: HassioHassOSInfo;
|
os: HassioHassOSInfo;
|
||||||
|
addon: HassioAddonsInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const supervisorApiWsRequest = <T>(
|
||||||
|
conn: Connection,
|
||||||
|
request: supervisorApiRequest
|
||||||
|
): Promise<T> =>
|
||||||
|
conn.sendMessagePromise<T>({ ...supervisorWSbaseCommand, ...request });
|
||||||
|
|
||||||
|
async function processEvent(
|
||||||
|
conn: Connection,
|
||||||
|
store: Store<any>,
|
||||||
|
event: SupervisorEvent,
|
||||||
|
key: string
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!event.data ||
|
||||||
|
event.data.event !== "supervisor-update" ||
|
||||||
|
event.data.update_key !== key
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(event.data.data).length === 0) {
|
||||||
|
const data = await supervisorApiWsRequest<any>(conn, {
|
||||||
|
endpoint: supervisorStore[key],
|
||||||
|
});
|
||||||
|
store.setState(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = store.state;
|
||||||
|
if (state === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
store.setState({
|
||||||
|
...state,
|
||||||
|
...event.data.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const subscribeSupervisorEventUpdates = (
|
||||||
|
conn: Connection,
|
||||||
|
store: Store<unknown>,
|
||||||
|
key: string
|
||||||
|
) =>
|
||||||
|
conn.subscribeEvents(
|
||||||
|
(event) => processEvent(conn, store, event as SupervisorEvent, key),
|
||||||
|
"supervisor_event"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getSupervisorEventCollection = (
|
||||||
|
conn: Connection,
|
||||||
|
key: string,
|
||||||
|
endpoint: string
|
||||||
|
) =>
|
||||||
|
getCollection(
|
||||||
|
conn,
|
||||||
|
`_supervisor${key}Event`,
|
||||||
|
() => supervisorApiWsRequest(conn, { endpoint }),
|
||||||
|
(connection, store) =>
|
||||||
|
subscribeSupervisorEventUpdates(connection, store, key)
|
||||||
|
);
|
||||||
|
|
||||||
|
export const subscribeSupervisorEvents = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
onChange: (event) => void,
|
||||||
|
key: string,
|
||||||
|
endpoint: string
|
||||||
|
) =>
|
||||||
|
getSupervisorEventCollection(hass.connection, key, endpoint).subscribe(
|
||||||
|
onChange
|
||||||
|
);
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
import * as assert from "assert";
|
import * as assert from "assert";
|
||||||
import { createHassioSession } from "../../src/data/hassio/ingress";
|
import { createHassioSession } from "../../src/data/hassio/ingress";
|
||||||
|
|
||||||
const sessionID = "fhdsu73rh3io4h8f3irhjel8ousafehf8f3yh";
|
|
||||||
|
|
||||||
describe("Create hassio session", function () {
|
describe("Create hassio session", function () {
|
||||||
|
const hass = {
|
||||||
|
config: { version: "1.0.0" },
|
||||||
|
callApi: async function () {
|
||||||
|
return { data: { session: "fhdsu73rh3io4h8f3irhjel8ousafehf8f3yh" } };
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
it("Test create session without HTTPS", async function () {
|
it("Test create session without HTTPS", async function () {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.document = {};
|
global.document = {};
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.location = {};
|
global.location = {};
|
||||||
await createHassioSession({
|
// @ts-ignore
|
||||||
// @ts-ignore
|
await createHassioSession(hass);
|
||||||
callApi: async function () {
|
|
||||||
return { data: { session: sessionID } };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.document.cookie,
|
global.document.cookie,
|
||||||
@ -26,12 +27,8 @@ describe("Create hassio session", function () {
|
|||||||
global.document = {};
|
global.document = {};
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.location = { protocol: "https:" };
|
global.location = { protocol: "https:" };
|
||||||
await createHassioSession({
|
// @ts-ignore
|
||||||
// @ts-ignore
|
await createHassioSession(hass);
|
||||||
callApi: async function () {
|
|
||||||
return { data: { session: sessionID } };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.document.cookie,
|
global.document.cookie,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user