From d8bab6aba943d256799766de1113e9b574cf316e Mon Sep 17 00:00:00 2001
From: Paulus Schoutsen
Date: Mon, 31 May 2021 15:40:50 -0700
Subject: [PATCH] Add support for disable polling system option (#9316)
---
gallery/src/demos/demo-integration-card.ts | 12 +-
src/data/config_entries.ts | 17 +-
.../dialog-config-entry-system-options.ts | 166 ++++++++++--------
...show-dialog-config-entry-system-options.ts | 7 +-
.../integrations/ha-integration-card.ts | 6 +
.../integrations/ha-integration-header.ts | 14 +-
src/translations/en.json | 6 +-
7 files changed, 138 insertions(+), 90 deletions(-)
diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts
index 1e23303bc4..97e581f2cc 100644
--- a/gallery/src/demos/demo-integration-card.ts
+++ b/gallery/src/demos/demo-integration-card.ts
@@ -28,10 +28,13 @@ const createConfigEntry = (
title,
source: "zeroconf",
state: "loaded",
- connection_class: "local_push",
supports_options: false,
supports_unload: true,
disabled_by: null,
+ system_options: {
+ disable_new_entities: false,
+ disable_polling: false,
+ },
reason: null,
...override,
});
@@ -64,6 +67,12 @@ const configPanelEntry = createConfigEntry("Config Panel", {
const optionsFlowEntry = createConfigEntry("Options Flow", {
supports_options: true,
});
+const disabledPollingEntry = createConfigEntry("Disabled Polling", {
+ system_options: {
+ disable_new_entities: false,
+ disable_polling: true,
+ },
+});
const setupErrorEntry = createConfigEntry("Setup Error", {
state: "setup_error",
});
@@ -136,6 +145,7 @@ const configEntries: Array<{
{ items: [loadedEntry] },
{ items: [configPanelEntry] },
{ items: [optionsFlowEntry] },
+ { items: [disabledPollingEntry] },
{ items: [nameAsDomainEntry] },
{ items: [longNameEntry] },
{ items: [longNonBreakingNameEntry] },
diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts
index 9bb203c942..8e4de41a9e 100644
--- a/src/data/config_entries.ts
+++ b/src/data/config_entries.ts
@@ -12,9 +12,9 @@ export interface ConfigEntry {
| "setup_retry"
| "not_loaded"
| "failed_unload";
- connection_class: string;
supports_options: boolean;
supports_unload: boolean;
+ system_options: ConfigEntrySystemOptions;
disabled_by: "user" | null;
reason: string | null;
}
@@ -25,6 +25,7 @@ export interface ConfigEntryMutableParams {
export interface ConfigEntrySystemOptions {
disable_new_entities: boolean;
+ disable_polling: boolean;
}
export const getConfigEntries = (hass: HomeAssistant) =>
@@ -72,21 +73,15 @@ export const enableConfigEntry = (hass: HomeAssistant, configEntryId: string) =>
disabled_by: null,
});
-export const getConfigEntrySystemOptions = (
- hass: HomeAssistant,
- configEntryId: string
-) =>
- hass.callWS({
- type: "config_entries/system_options/list",
- entry_id: configEntryId,
- });
-
export const updateConfigEntrySystemOptions = (
hass: HomeAssistant,
configEntryId: string,
params: Partial
) =>
- hass.callWS({
+ hass.callWS<{
+ require_restart: boolean;
+ system_options: ConfigEntrySystemOptions;
+ }>({
type: "config_entries/system_options/update",
entry_id: configEntryId,
...params,
diff --git a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts
index bd1f6bbcd1..92cac06fef 100644
--- a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts
+++ b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts
@@ -3,17 +3,14 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import { computeRTLDirection } from "../../common/util/compute_rtl";
-import "../../components/ha-circular-progress";
import "../../components/ha-dialog";
import "../../components/ha-formfield";
import "../../components/ha-switch";
import type { HaSwitch } from "../../components/ha-switch";
-import {
- getConfigEntrySystemOptions,
- updateConfigEntrySystemOptions,
-} from "../../data/config_entries";
+import { updateConfigEntrySystemOptions } from "../../data/config_entries";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
+import { showAlertDialog } from "../generic/show-dialog-box";
import { ConfigEntrySystemOptionsDialogParams } from "./show-dialog-config-entry-system-options";
@customElement("dialog-config-entry-system-options")
@@ -22,12 +19,12 @@ class DialogConfigEntrySystemOptions extends LitElement {
@state() private _disableNewEntities!: boolean;
+ @state() private _disablePolling!: boolean;
+
@state() private _error?: string;
@state() private _params?: ConfigEntrySystemOptionsDialogParams;
- @state() private _loading = false;
-
@state() private _submitting = false;
public async showDialog(
@@ -35,13 +32,8 @@ class DialogConfigEntrySystemOptions extends LitElement {
): Promise {
this._params = params;
this._error = undefined;
- this._loading = true;
- const systemOptions = await getConfigEntrySystemOptions(
- this.hass,
- params.entry.entry_id
- );
- this._loading = false;
- this._disableNewEntities = systemOptions.disable_new_entities;
+ this._disableNewEntities = params.entry.system_options.disable_new_entities;
+ this._disablePolling = params.entry.system_options.disable_polling;
}
public closeDialog(): void {
@@ -66,45 +58,57 @@ class DialogConfigEntrySystemOptions extends LitElement {
this._params.entry.domain
)}
>
-
- ${this._loading
- ? html`
-
-
-
- `
- : html`
- ${this._error
- ? html`
${this._error}
`
- : ""}
-
- `}
-
+ ${this._error ? html` ${this._error}
` : ""}
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_new_entities_label"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_new_entities_description",
+ "integration",
+ this.hass.localize(
+ `component.${this._params.entry.domain}.title`
+ ) || this._params.entry.domain
+ )}
+
`}
+ .dir=${computeRTLDirection(this.hass)}
+ >
+
+
+ ${this._allowUpdatePolling()
+ ? html`
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_polling_label"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_polling_description",
+ "integration",
+ this.hass.localize(
+ `component.${this._params.entry.domain}.title`
+ ) || this._params.entry.domain
+ )}
+
`}
+ .dir=${computeRTLDirection(this.hass)}
+ >
+
+
+ `
+ : ""}
${this.hass.localize("ui.dialogs.config_entry_system_options.update")}
@@ -123,21 +127,53 @@ class DialogConfigEntrySystemOptions extends LitElement {
`;
}
+ private _allowUpdatePolling() {
+ return (
+ this._params!.manifest &&
+ (this._params!.manifest.iot_class === "local_polling" ||
+ this._params!.manifest.iot_class === "cloud_polling")
+ );
+ }
+
private _disableNewEntitiesChanged(ev: Event): void {
this._error = undefined;
this._disableNewEntities = !(ev.target as HaSwitch).checked;
}
+ private _disablePollingChanged(ev: Event): void {
+ this._error = undefined;
+ this._disablePolling = !(ev.target as HaSwitch).checked;
+ }
+
private async _updateEntry(): Promise {
this._submitting = true;
+ const data: Parameters[2] = {
+ disable_new_entities: this._disableNewEntities,
+ };
+ if (this._allowUpdatePolling()) {
+ data.disable_polling = this._disablePolling;
+ }
try {
- await updateConfigEntrySystemOptions(
+ const result = await updateConfigEntrySystemOptions(
this.hass,
this._params!.entry.entry_id,
- {
- disable_new_entities: this._disableNewEntities,
- }
+ data
);
+ if (result.require_restart) {
+ await showAlertDialog(this, {
+ text: this.hass.localize(
+ "ui.dialogs.config_entry_system_options.restart_home_assistant"
+ ),
+ });
+ }
+ const curEntry = this._params!.entry;
+ this._params!.entryUpdated({
+ ...curEntry,
+ system_options: {
+ ...curEntry.system_options,
+ ...data,
+ },
+ });
this._params = undefined;
} catch (err) {
this._error = err.message || "Unknown error";
@@ -150,20 +186,6 @@ class DialogConfigEntrySystemOptions extends LitElement {
return [
haStyleDialog,
css`
- .init-spinner {
- padding: 50px 100px;
- text-align: center;
- }
-
- .form {
- padding-top: 6px;
- padding-bottom: 24px;
- color: var(--primary-text-color);
- }
- .secondary {
- color: var(--secondary-text-color);
- }
-
.error {
color: var(--error-color);
}
diff --git a/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts
index 6b8a6c0329..77415e02cd 100644
--- a/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts
+++ b/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts
@@ -1,12 +1,11 @@
import { fireEvent } from "../../common/dom/fire_event";
import { ConfigEntry } from "../../data/config_entries";
+import { IntegrationManifest } from "../../data/integration";
export interface ConfigEntrySystemOptionsDialogParams {
entry: ConfigEntry;
- // updateEntry: (
- // updates: Partial
- // ) => Promise;
- // removeEntry: () => Promise;
+ manifest?: IntegrationManifest;
+ entryUpdated(entry: ConfigEntry): void;
}
export const loadConfigEntrySystemOptionsDialog = () =>
diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts
index cbd7de5aab..4e2a103c48 100644
--- a/src/panels/config/integrations/ha-integration-card.ts
+++ b/src/panels/config/integrations/ha-integration-card.ts
@@ -110,6 +110,7 @@ export class HaIntegrationCard extends LitElement {
: undefined}
.localizedDomainName=${item ? item.localized_domain_name : undefined}
.manifest=${this.manifest}
+ .configEntry=${item}
>
${this.items.length > 1
? html`
@@ -466,6 +467,11 @@ export class HaIntegrationCard extends LitElement {
private _showSystemOptions(configEntry: ConfigEntry) {
showConfigEntrySystemOptionsDialog(this, {
entry: configEntry,
+ manifest: this.manifest,
+ entryUpdated: (entry) =>
+ fireEvent(this, "entry-updated", {
+ entry,
+ }),
});
}
diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts
index cd189da48b..d18ba01670 100644
--- a/src/panels/config/integrations/ha-integration-header.ts
+++ b/src/panels/config/integrations/ha-integration-header.ts
@@ -1,8 +1,9 @@
-import { mdiCloud, mdiPackageVariant } from "@mdi/js";
+import { mdiCloud, mdiPackageVariant, mdiSyncOff } from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-svg-icon";
+import { ConfigEntry } from "../../../data/config_entries";
import { domainToName, IntegrationManifest } from "../../../data/integration";
import { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
@@ -21,6 +22,8 @@ export class HaIntegrationHeader extends LitElement {
@property({ attribute: false }) public manifest?: IntegrationManifest;
+ @property({ attribute: false }) public configEntry?: ConfigEntry;
+
protected render(): TemplateResult {
let primary: string;
let secondary: string | undefined;
@@ -59,6 +62,15 @@ export class HaIntegrationHeader extends LitElement {
),
]);
}
+
+ if (this.configEntry?.system_options.disable_polling) {
+ icons.push([
+ mdiSyncOff,
+ this.hass.localize(
+ "ui.panel.config.integrations.config_entry.disabled_polling"
+ ),
+ ]);
+ }
}
return html`
diff --git a/src/translations/en.json b/src/translations/en.json
index 584e25f33e..dae343b3c2 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -759,7 +759,10 @@
"config_entry_system_options": {
"title": "System Options for {integration}",
"enable_new_entities_label": "Enable newly added entities.",
- "enable_new_entities_description": "If disabled, newly discovered entities for {integration} will not be automatically added to Home Assistant.",
+ "enable_new_entities_description": "If newly discovered devices for {integration} should be automatically added.",
+ "enable_polling_label": "Enable polling for updates.",
+ "enable_polling_description": "If Home Assistant should automatically poll {integration} entities for updates.",
+ "restart_home_assistant": "You need to restart Home Assistant for your changes to take effect.",
"update": "Update"
},
"zha_reconfigure_device": {
@@ -2182,6 +2185,7 @@
},
"provided_by_custom_integration": "Provided by a custom integration",
"depends_on_cloud": "Depends on the cloud",
+ "disabled_polling": "Automatic polling for updated data disabled",
"state": {
"loaded": "Loaded",
"setup_error": "Failed to set up",