-
-
-
+
`;
}
@@ -51,6 +68,16 @@ class DemoMoreInfos extends PolymerElement {
},
};
}
+
+ _showConfigToggled(ev) {
+ this._showConfig = ev.target.checked;
+ }
+
+ _darkThemeToggled(ev) {
+ applyThemesOnElement(this.$.container, { themes: {} }, "default", {
+ dark: ev.target.checked,
+ });
+ }
}
customElements.define("demo-more-infos", DemoMoreInfos);
diff --git a/gallery/src/data/plants.ts b/gallery/src/data/plants.ts
new file mode 100644
index 000000000000..362afaac7806
--- /dev/null
+++ b/gallery/src/data/plants.ts
@@ -0,0 +1,72 @@
+import { getEntity } from "../../../src/fake_data/entity";
+
+export const createPlantEntities = () => [
+ getEntity("plant", "lemon_tree", "ok", {
+ problem: "none",
+ sensors: {
+ moisture: "sensor.lemon_tree_moisture",
+ battery: "sensor.lemon_tree_battery",
+ temperature: "sensor.lemon_tree_temperature",
+ conductivity: "sensor.lemon_tree_conductivity",
+ brightness: "sensor.lemon_tree_brightness",
+ },
+ unit_of_measurement_dict: {
+ temperature: "°C",
+ moisture: "%",
+ brightness: "lx",
+ battery: "%",
+ conductivity: "μS/cm",
+ },
+ moisture: 54,
+ battery: 95,
+ temperature: 15.6,
+ conductivity: 1,
+ brightness: 12,
+ max_brightness: 20,
+ friendly_name: "Lemon Tree",
+ }),
+ getEntity("plant", "apple_tree", "ok", {
+ problem: "brightness",
+ sensors: {
+ moisture: "sensor.apple_tree_moisture",
+ battery: "sensor.apple_tree_battery",
+ temperature: "sensor.apple_tree_temperature",
+ conductivity: "sensor.apple_tree_conductivity",
+ brightness: "sensor.apple_tree_brightness",
+ },
+ unit_of_measurement_dict: {
+ temperature: "°C",
+ moisture: "%",
+ brightness: "lx",
+ battery: "%",
+ conductivity: "μS/cm",
+ },
+ moisture: 54,
+ battery: 2,
+ temperature: 15.6,
+ conductivity: 1,
+ brightness: 25,
+ max_brightness: 20,
+ friendly_name: "Apple Tree",
+ }),
+ getEntity("plant", "sunflowers", "ok", {
+ problem: "moisture, temperature, conductivity",
+ sensors: {
+ moisture: "sensor.sunflowers_moisture",
+ temperature: "sensor.sunflowers_temperature",
+ conductivity: "sensor.sunflowers_conductivity",
+ brightness: "sensor.sunflowers_brightness",
+ },
+ unit_of_measurement_dict: {
+ temperature: "°C",
+ moisture: "%",
+ brightness: "lx",
+ conductivity: "μS/cm",
+ },
+ moisture: 54,
+ temperature: 15.6,
+ conductivity: 1,
+ brightness: 25,
+ entity_picture: "/images/sunflowers.jpg",
+ }),
+];
diff --git a/gallery/src/demos/demo-hui-alarm-panel-card.ts b/gallery/src/demos/demo-hui-alarm-panel-card.ts
index efeacf5f191b..4c66b22559d5 100644
--- a/gallery/src/demos/demo-hui-alarm-panel-card.ts
+++ b/gallery/src/demos/demo-hui-alarm-panel-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -71,28 +76,19 @@ const CONFIGS = [
},
];
-class DemoAlarmPanelEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
-
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
- }
+@customElement("demo-hui-alarm-panel-card")
+class DemoAlarmPanelEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- public ready() {
- super.ready();
- this._setupDemo();
+ protected render(): TemplateResult {
+ return html`
`;
}
- private async _setupDemo() {
- const hass = provideHass(this.$.demos);
- await hass.updateTranslations(null, "en");
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
+ hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-conditional-card.ts b/gallery/src/demos/demo-hui-conditional-card.ts
index 561ad45376f1..cf70db64aa06 100644
--- a/gallery/src/demos/demo-hui-conditional-card.ts
+++ b/gallery/src/demos/demo-hui-conditional-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -53,24 +58,19 @@ const CONFIGS = [
},
];
-class DemoConditional extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-conditional-card")
+class DemoConditional extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-entities-card.ts b/gallery/src/demos/demo-hui-entities-card.ts
index bb0261e9d509..7511e061b520 100644
--- a/gallery/src/demos/demo-hui-entities-card.ts
+++ b/gallery/src/demos/demo-hui-entities-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -217,24 +222,19 @@ const CONFIGS = [
},
];
-class DemoEntities extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-entities-card")
+class DemoEntities extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-entity-button-card.ts b/gallery/src/demos/demo-hui-entity-button-card.ts
index 5c9430bf6431..1e3201fa10a6 100644
--- a/gallery/src/demos/demo-hui-entity-button-card.ts
+++ b/gallery/src/demos/demo-hui-entity-button-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -48,7 +53,7 @@ const CONFIGS = [
config: `
- type: button
entity: light.bed_light
- tap_action:
+ tap_action:
action: toggle
`,
},
@@ -69,24 +74,19 @@ const CONFIGS = [
},
];
-class DemoButtonEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-entity-button-card")
+class DemoButtonEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-entity-filter-card.ts b/gallery/src/demos/demo-hui-entity-filter-card.ts
index 66a0c08b706f..c3e22f0e4691 100644
--- a/gallery/src/demos/demo-hui-entity-filter-card.ts
+++ b/gallery/src/demos/demo-hui-entity-filter-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -43,7 +48,7 @@ const ENTITIES = [
const CONFIGS = [
{
- heading: "Controller",
+ heading: "Unfiltered controller",
config: `
- type: entities
entities:
@@ -53,7 +58,7 @@ const CONFIGS = [
`,
},
{
- heading: "Basic",
+ heading: "Filtered entities card",
config: `
- type: entity-filter
entities:
@@ -69,7 +74,27 @@ const CONFIGS = [
`,
},
{
- heading: "With card config",
+ heading: 'With "entities" card config',
+ config: `
+- type: entity-filter
+ entities:
+ - device_tracker.demo_anne_therese
+ - device_tracker.demo_home_boy
+ - device_tracker.demo_paulus
+ - light.bed_light
+ - light.ceiling_lights
+ - light.kitchen_lights
+ state_filter:
+ - "on"
+ - not_home
+ card:
+ type: entities
+ title: Custom Title
+ show_header_toggle: false
+ `,
+ },
+ {
+ heading: 'With "glance" card config',
config: `
- type: entity-filter
entities:
@@ -84,31 +109,27 @@ const CONFIGS = [
- not_home
card:
type: glance
- show_state: false
+ show_state: true
+ title: Custom Title
`,
},
];
-class DemoFilter extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-entity-filter-card")
+class DemoEntityFilter extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
-customElements.define("demo-hui-entity-filter-card", DemoFilter);
+customElements.define("demo-hui-entity-filter-card", DemoEntityFilter);
diff --git a/gallery/src/demos/demo-hui-gauge-card.ts b/gallery/src/demos/demo-hui-gauge-card.ts
index 1704d31f6ed1..35e794f317ad 100644
--- a/gallery/src/demos/demo-hui-gauge-card.ts
+++ b/gallery/src/demos/demo-hui-gauge-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -107,24 +112,19 @@ const CONFIGS = [
},
];
-class DemoGaugeEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-gauge-card")
+class DemoGaugeEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-glance-card.ts b/gallery/src/demos/demo-hui-glance-card.ts
index 5455232a3d73..2d3d83193ef9 100644
--- a/gallery/src/demos/demo-hui-glance-card.ts
+++ b/gallery/src/demos/demo-hui-glance-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -77,7 +82,8 @@ const CONFIGS = [
heading: "With title",
config: `
- type: glance
- title: This is glance
+ title: Custom title
+ columns: 4
entities:
- device_tracker.demo_paulus
- media_player.living_room
@@ -104,9 +110,10 @@ const CONFIGS = [
`,
},
{
- heading: "No name",
+ heading: "No entity names",
config: `
- type: glance
+ columns: 4
show_name: false
entities:
- device_tracker.demo_paulus
@@ -119,9 +126,10 @@ const CONFIGS = [
`,
},
{
- heading: "No state",
+ heading: "No state labels",
config: `
- type: glance
+ columns: 4
show_state: false
entities:
- device_tracker.demo_paulus
@@ -134,9 +142,10 @@ const CONFIGS = [
`,
},
{
- heading: "No name and no state",
+ heading: "No names and no state labels",
config: `
- type: glance
+ columns: 4
show_name: false
show_state: false
entities:
@@ -150,47 +159,24 @@ const CONFIGS = [
`,
},
{
- heading: "Custom name, custom icon",
+ heading: "Custom name + custom icon",
config: `
- type: glance
+ columns: 4
entities:
- entity: device_tracker.demo_paulus
name: ¯\\_(ツ)_/¯
icon: mdi:home-assistant
- - media_player.living_room
- - sun.sun
- - cover.kitchen_window
- - entity: light.kitchen_lights
- icon: mdi:alarm-light
- - lock.kitchen_door
- - light.ceiling_lights
- `,
- },
- {
- heading: "Custom tap action",
- config: `
-- type: glance
- entities:
- - entity: lock.kitchen_door
- tap_action:
- type: toggle
- - entity: light.ceiling_lights
- tap_action:
- action: call-service
- service: light.turn_on
- service_data:
- entity_id: light.ceiling_lights
- - device_tracker.demo_paulus
- - media_player.living_room
- - sun.sun
- - cover.kitchen_window
- - light.kitchen_lights
+ - entity: media_player.living_room
+ name: ¯\\_(ツ)_/¯
+ icon: mdi:home-assistant
`,
},
{
heading: "Selectively hidden name",
config: `
- type: glance
+ columns: 4
entities:
- device_tracker.demo_paulus
- entity: media_player.living_room
@@ -199,45 +185,51 @@ const CONFIGS = [
- entity: cover.kitchen_window
name:
- light.kitchen_lights
+ - entity: lock.kitchen_door
+ name:
+ - light.ceiling_lights
`,
},
{
- heading: "Primary theme",
+ heading: "Custom tap action",
config: `
- type: glance
- theming: primary
+ columns: 4
entities:
- - device_tracker.demo_paulus
- - media_player.living_room
- - sun.sun
- - cover.kitchen_window
- - light.kitchen_lights
- - lock.kitchen_door
- - light.ceiling_lights
+ - entity: lock.kitchen_door
+ name: Custom
+ tap_action:
+ type: toggle
+ - entity: light.ceiling_lights
+ name: Custom
+ tap_action:
+ action: call-service
+ service: light.turn_on
+ service_data:
+ entity_id: light.ceiling_lights
+ - entity: sun.sun
+ name: Regular
+ - entity: light.kitchen_lights
+ name: Regular
`,
},
];
-class DemoPicEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-glance-card")
+class DemoGlanceEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
-customElements.define("demo-hui-glance-card", DemoPicEntity);
+customElements.define("demo-hui-glance-card", DemoGlanceEntity);
diff --git a/gallery/src/demos/demo-hui-iframe-card.ts b/gallery/src/demos/demo-hui-iframe-card.ts
index 596f6d302f11..a2d493476bdb 100644
--- a/gallery/src/demos/demo-hui-iframe-card.ts
+++ b/gallery/src/demos/demo-hui-iframe-card.ts
@@ -1,6 +1,4 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import { customElement, html, LitElement, TemplateResult } from "lit-element";
import "../components/demo-cards";
const CONFIGS = [
@@ -37,18 +35,10 @@ const CONFIGS = [
},
];
-class DemoIframe extends PolymerElement {
- static get template() {
- return html`
`;
- }
-
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+@customElement("demo-hui-iframe-card")
+class DemoIframe extends LitElement {
+ protected render(): TemplateResult {
+ return html`
`;
}
}
diff --git a/gallery/src/demos/demo-hui-light-card.ts b/gallery/src/demos/demo-hui-light-card.ts
index 97808f930a1e..71d12b4af841 100644
--- a/gallery/src/demos/demo-hui-light-card.ts
+++ b/gallery/src/demos/demo-hui-light-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -63,24 +68,19 @@ const CONFIGS = [
},
];
-class DemoLightEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-light-card")
+class DemoLightEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-map-card.ts b/gallery/src/demos/demo-hui-map-card.ts
index 392826fb9356..2cc55f499d16 100644
--- a/gallery/src/demos/demo-hui-map-card.ts
+++ b/gallery/src/demos/demo-hui-map-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -161,24 +166,19 @@ const CONFIGS = [
},
];
-class DemoMap extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-map-card")
+class DemoMap extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-hui-markdown-card.ts b/gallery/src/demos/demo-hui-markdown-card.ts
index 1ae6b5f0f7f1..8321eff7d3e2 100644
--- a/gallery/src/demos/demo-hui-markdown-card.ts
+++ b/gallery/src/demos/demo-hui-markdown-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { mockTemplate } from "../../../demo/src/stubs/template";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -254,23 +259,19 @@ const CONFIGS = [
},
];
-class DemoMarkdown extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-markdown-card")
+class DemoMarkdown extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
+ hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
mockTemplate(hass);
}
}
diff --git a/gallery/src/demos/demo-hui-media-control-card.ts b/gallery/src/demos/demo-hui-media-control-card.ts
index 1f12c851bc3d..55bbc0168c94 100644
--- a/gallery/src/demos/demo-hui-media-control-card.ts
+++ b/gallery/src/demos/demo-hui-media-control-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
import { createMediaPlayerEntities } from "../data/media_players";
@@ -158,26 +163,21 @@ const CONFIGS = [
},
];
-class DemoHuiMediControlCard extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-media-control-card")
+class DemoHuiMediaControlCard extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(createMediaPlayerEntities());
}
}
-customElements.define("demo-hui-media-control-card", DemoHuiMediControlCard);
+customElements.define("demo-hui-media-control-card", DemoHuiMediaControlCard);
diff --git a/gallery/src/demos/demo-hui-media-player-rows.ts b/gallery/src/demos/demo-hui-media-player-rows.ts
index 147f36985ed1..9ffabfee9bbe 100644
--- a/gallery/src/demos/demo-hui-media-player-rows.ts
+++ b/gallery/src/demos/demo-hui-media-player-rows.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
import { createMediaPlayerEntities } from "../data/media_players";
@@ -26,9 +31,9 @@ const CONFIGS = [
- entity: media_player.android_cast
name: Screen casting
- entity: media_player.image_display
- name: Digital Picture Frame
+ name: Digital Picture Frame
- entity: media_player.sonos_idle
- name: Sonos Idle
+ name: Sonos Idle
- entity: media_player.idle_browse_media
name: Idle waiting for Browse Media
- entity: media_player.theater_off
@@ -38,7 +43,7 @@ const CONFIGS = [
- entity: media_player.theater_off_static
name: Player Off (cannot be switched on)
- entity: media_player.theater_on_static
- name: Player On (cannot be switched off)
+ name: Player On (cannot be switched off)
- entity: media_player.idle
name: Player Idle
- entity: media_player.playing
@@ -55,26 +60,21 @@ const CONFIGS = [
},
];
-class DemoHuiMediaPlayerRows extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-media-player-row")
+class DemoHuiMediaPlayerRow extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(createMediaPlayerEntities());
}
}
-customElements.define("demo-hui-media-player-rows", DemoHuiMediaPlayerRows);
+customElements.define("demo-hui-media-player-row", DemoHuiMediaPlayerRow);
diff --git a/gallery/src/demos/demo-hui-picture-elements-card.ts b/gallery/src/demos/demo-hui-picture-elements-card.ts
index 6e0ec3360a1c..6e6ffd86a055 100644
--- a/gallery/src/demos/demo-hui-picture-elements-card.ts
+++ b/gallery/src/demos/demo-hui-picture-elements-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -125,26 +130,21 @@ const CONFIGS = [
},
];
-class DemoPicElements extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-picture-elements-card")
+class DemoPictureElements extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
-customElements.define("demo-hui-picture-elements-card", DemoPicElements);
+customElements.define("demo-hui-picture-elements-card", DemoPictureElements);
diff --git a/gallery/src/demos/demo-hui-picture-entity-card.ts b/gallery/src/demos/demo-hui-picture-entity-card.ts
index d4df8f31f4cc..fd0c5fea94a0 100644
--- a/gallery/src/demos/demo-hui-picture-entity-card.ts
+++ b/gallery/src/demos/demo-hui-picture-entity-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -80,26 +85,21 @@ const CONFIGS = [
},
];
-class DemoPicEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-picture-entity-card")
+class DemoPictureEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
-customElements.define("demo-hui-picture-entity-card", DemoPicEntity);
+customElements.define("demo-hui-picture-entity-card", DemoPictureEntity);
diff --git a/gallery/src/demos/demo-hui-picture-glance-card.ts b/gallery/src/demos/demo-hui-picture-glance-card.ts
index 684aaa2071f6..9ecafb7f5a75 100644
--- a/gallery/src/demos/demo-hui-picture-glance-card.ts
+++ b/gallery/src/demos/demo-hui-picture-glance-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -121,26 +126,21 @@ const CONFIGS = [
},
];
-class DemoPicGlance extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-picture-glance-card")
+class DemoPictureGlance extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
-customElements.define("demo-hui-picture-glance-card", DemoPicGlance);
+customElements.define("demo-hui-picture-glance-card", DemoPictureGlance);
diff --git a/gallery/src/demos/demo-hui-plant-card.ts b/gallery/src/demos/demo-hui-plant-card.ts
new file mode 100644
index 000000000000..a1d49afe5b9c
--- /dev/null
+++ b/gallery/src/demos/demo-hui-plant-card.ts
@@ -0,0 +1,55 @@
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
+import { provideHass } from "../../../src/fake_data/provide_hass";
+import "../components/demo-cards";
+import { createPlantEntities } from "../data/plants";
+
+const CONFIGS = [
+ {
+ heading: "Basic example",
+ config: `
+- type: plant-status
+ entity: plant.lemon_tree
+ `,
+ },
+ {
+ heading: "Problem (too bright) + low battery",
+ config: `
+- type: plant-status
+ entity: plant.apple_tree
+ `,
+ },
+ {
+ heading: "With picture + multiple problems",
+ config: `
+- type: plant-status
+ entity: plant.sunflowers
+ name: Sunflowers Name Overwrite
+ `,
+ },
+];
+
+@customElement("demo-hui-plant-card")
+export class DemoPlantEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
+
+ protected render(): TemplateResult {
+ return html`
`;
+ }
+
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
+ hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
+ hass.addEntities(createPlantEntities());
+ }
+}
+
+customElements.define("demo-hui-plant-card", DemoPlantEntity);
diff --git a/gallery/src/demos/demo-hui-shopping-list-card.ts b/gallery/src/demos/demo-hui-shopping-list-card.ts
index 9abb1afc1e93..a17bd61f1200 100644
--- a/gallery/src/demos/demo-hui-shopping-list-card.ts
+++ b/gallery/src/demos/demo-hui-shopping-list-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -20,24 +25,19 @@ const CONFIGS = [
},
];
-class DemoShoppingListEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-shopping-list-card")
+class DemoShoppingListEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.mockAPI("shopping_list", () => [
{ name: "list", id: 1, complete: false },
diff --git a/gallery/src/demos/demo-hui-stack-card.ts b/gallery/src/demos/demo-hui-stack-card.ts
index 982eab4f2564..26f03c405173 100644
--- a/gallery/src/demos/demo-hui-stack-card.ts
+++ b/gallery/src/demos/demo-hui-stack-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { mockHistory } from "../../../demo/src/stubs/history";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
@@ -132,24 +137,19 @@ const CONFIGS = [
},
];
-class DemoStack extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-stack-card")
+class DemoStack extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
mockHistory(hass);
}
diff --git a/gallery/src/demos/demo-hui-thermostat-card.ts b/gallery/src/demos/demo-hui-thermostat-card.ts
index 81b344e6895e..30e08d3e297f 100644
--- a/gallery/src/demos/demo-hui-thermostat-card.ts
+++ b/gallery/src/demos/demo-hui-thermostat-card.ts
@@ -1,6 +1,11 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-cards";
@@ -74,24 +79,19 @@ const CONFIGS = [
},
];
-class DemoThermostatEntity extends PolymerElement {
- static get template() {
- return html`
`;
- }
+@customElement("demo-hui-thermostat-card")
+class DemoThermostatEntity extends LitElement {
+ @query("#demos") private _demoRoot!: HTMLElement;
- static get properties() {
- return {
- _configs: {
- type: Object,
- value: CONFIGS,
- },
- };
+ protected render(): TemplateResult {
+ return html`
`;
}
- public ready() {
- super.ready();
- const hass = provideHass(this.$.demos);
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
hass.updateTranslations(null, "en");
+ hass.updateTranslations("lovelace", "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-more-info-light.ts b/gallery/src/demos/demo-more-info-light.ts
index 70b77560d933..3a05f1becfde 100644
--- a/gallery/src/demos/demo-more-info-light.ts
+++ b/gallery/src/demos/demo-more-info-light.ts
@@ -1,12 +1,29 @@
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
+import {
+ customElement,
+ html,
+ LitElement,
+ property,
+ PropertyValues,
+ query,
+ TemplateResult,
+} from "lit-element";
import "../../../src/components/ha-card";
-import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
+import {
+ SUPPORT_BRIGHTNESS,
+ SUPPORT_COLOR,
+ SUPPORT_COLOR_TEMP,
+ SUPPORT_EFFECT,
+ SUPPORT_FLASH,
+ SUPPORT_TRANSITION,
+ SUPPORT_WHITE_VALUE,
+} from "../../../src/data/light";
+import "../../../src/dialogs/more-info/more-info-content";
import { getEntity } from "../../../src/fake_data/entity";
-import { provideHass } from "../../../src/fake_data/provide_hass";
+import {
+ MockHomeAssistant,
+ provideHass,
+} from "../../../src/fake_data/provide_hass";
import "../components/demo-more-infos";
-import "../../../src/dialogs/more-info/more-info-content";
const ENTITIES = [
getEntity("light", "bed_light", "on", {
@@ -14,38 +31,52 @@ const ENTITIES = [
}),
getEntity("light", "kitchen_light", "on", {
friendly_name: "Brightness Light",
- brightness: 80,
+ brightness: 200,
supported_features: SUPPORT_BRIGHTNESS,
}),
+ getEntity("light", "color_temperature_light", "on", {
+ friendly_name: "White Color Temperature Light",
+ brightness: 128,
+ color_temp: 75,
+ min_mireds: 30,
+ max_mireds: 150,
+ supported_features: SUPPORT_BRIGHTNESS + SUPPORT_COLOR_TEMP,
+ }),
+ getEntity("light", "color_effectslight", "on", {
+ friendly_name: "Color Effets Light",
+ brightness: 255,
+ hs_color: [30, 100],
+ white_value: 36,
+ supported_features:
+ SUPPORT_BRIGHTNESS +
+ SUPPORT_EFFECT +
+ SUPPORT_FLASH +
+ SUPPORT_COLOR +
+ SUPPORT_TRANSITION +
+ SUPPORT_WHITE_VALUE,
+ effect_list: ["random", "colorloop"],
+ }),
];
-class DemoMoreInfoLight extends PolymerElement {
- static get template() {
+@customElement("demo-more-info-light")
+class DemoMoreInfoLight extends LitElement {
+ @property() public hass!: MockHomeAssistant;
+
+ @query("demo-more-infos") private _demoRoot!: HTMLElement;
+
+ protected render(): TemplateResult {
return html`
ent.entityId)}
>
`;
}
- static get properties() {
- return {
- _entities: {
- type: Array,
- value: ENTITIES.map((ent) => ent.entityId),
- },
- };
- }
-
- public ready() {
- super.ready();
- this._setupDemo();
- }
-
- private async _setupDemo() {
- const hass = provideHass(this);
- await hass.updateTranslations(null, "en");
+ protected firstUpdated(changedProperties: PropertyValues) {
+ super.firstUpdated(changedProperties);
+ const hass = provideHass(this._demoRoot);
+ hass.updateTranslations(null, "en");
hass.addEntities(ENTITIES);
}
}
diff --git a/gallery/src/demos/demo-util-long-press.ts b/gallery/src/demos/demo-util-long-press.ts
index 518af1df39c2..9fa774918f99 100644
--- a/gallery/src/demos/demo-util-long-press.ts
+++ b/gallery/src/demos/demo-util-long-press.ts
@@ -1,9 +1,10 @@
import "@material/mwc-button";
-import { html, LitElement, TemplateResult } from "lit-element";
+import { customElement, html, LitElement, TemplateResult } from "lit-element";
import "../../../src/components/ha-card";
import { ActionHandlerEvent } from "../../../src/data/lovelace";
import { actionHandler } from "../../../src/panels/lovelace/common/directives/action-handler-directive";
+@customElement("demo-util-long-press")
export class DemoUtilLongPress extends LitElement {
protected render(): TemplateResult {
return html`
@@ -20,7 +21,7 @@ export class DemoUtilLongPress extends LitElement {
-
(try pressing and scrolling too!)
+
Try pressing and scrolling too!
`
)}
@@ -62,5 +63,3 @@ export class DemoUtilLongPress extends LitElement {
`;
}
}
-
-customElements.define("demo-util-long-press", DemoUtilLongPress);
diff --git a/gallery/src/ha-gallery.js b/gallery/src/ha-gallery.js
index 779790b632de..c1de40203da8 100644
--- a/gallery/src/ha-gallery.js
+++ b/gallery/src/ha-gallery.js
@@ -14,8 +14,6 @@ import "../../src/styles/polymer-ha-style";
// eslint-disable-next-line import/extensions
import { DEMOS } from "../build/import-demos";
-const fixPath = (path) => path.substr(2, path.length - 5);
-
class HaGallery extends PolymerElement {
static get template() {
return html`
diff --git a/hassio/src/addon-store/hassio-addon-store.ts b/hassio/src/addon-store/hassio-addon-store.ts
index fc15fc38dce8..2e21b19f842d 100644
--- a/hassio/src/addon-store/hassio-addon-store.ts
+++ b/hassio/src/addon-store/hassio-addon-store.ts
@@ -12,6 +12,7 @@ import {
} from "lit-element";
import { html, TemplateResult } from "lit-html";
import { atLeastVersion } from "../../../src/common/config/version";
+import { fireEvent } from "../../../src/common/dom/fire_event";
import "../../../src/common/search/search-input";
import "../../../src/components/ha-button-menu";
import "../../../src/components/ha-svg-icon";
@@ -22,6 +23,7 @@ import {
reloadHassioAddons,
} from "../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
+import { fetchHassioSupervisorInfo } from "../../../src/data/hassio/supervisor";
import "../../../src/layouts/hass-loading-screen";
import "../../../src/layouts/hass-tabs-subpage";
import { HomeAssistant, Route } from "../../../src/types";
@@ -190,7 +192,11 @@ class HassioAddonStore extends LitElement {
private async _loadData() {
try {
- const addonsInfo = await fetchHassioAddonsInfo(this.hass);
+ const [addonsInfo, supervisor] = await Promise.all([
+ fetchHassioAddonsInfo(this.hass),
+ fetchHassioSupervisorInfo(this.hass),
+ ]);
+ fireEvent(this, "supervisor-update", { supervisor });
this._repos = addonsInfo.repositories;
this._repos.sort(sortRepos);
this._addons = addonsInfo.addons;
diff --git a/hassio/src/addon-view/config/hassio-addon-audio.ts b/hassio/src/addon-view/config/hassio-addon-audio.ts
index 71ef1170d5e4..e3349b014483 100644
--- a/hassio/src/addon-view/config/hassio-addon-audio.ts
+++ b/hassio/src/addon-view/config/hassio-addon-audio.ts
@@ -7,13 +7,14 @@ import {
CSSResult,
customElement,
html,
+ internalProperty,
LitElement,
property,
- internalProperty,
PropertyValues,
TemplateResult,
} from "lit-element";
import "web-animations-js/web-animations-next-lite.min";
+import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-card";
import {
HassioAddonDetails,
@@ -28,7 +29,6 @@ import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
import { hassioStyle } from "../../resources/hassio-style";
-import "../../../../src/components/buttons/ha-progress-button";
@customElement("hassio-addon-audio")
class HassioAddonAudio extends LitElement {
diff --git a/hassio/src/addon-view/config/hassio-addon-config-tab.ts b/hassio/src/addon-view/config/hassio-addon-config-tab.ts
index 29e3f1778e46..323d50df73e5 100644
--- a/hassio/src/addon-view/config/hassio-addon-config-tab.ts
+++ b/hassio/src/addon-view/config/hassio-addon-config-tab.ts
@@ -7,11 +7,11 @@ import {
property,
TemplateResult,
} from "lit-element";
+import "../../../../src/components/ha-circular-progress";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
-import "../../../../src/components/ha-circular-progress";
import "./hassio-addon-audio";
import "./hassio-addon-config";
import "./hassio-addon-network";
@@ -26,28 +26,41 @@ class HassioAddonConfigDashboard extends LitElement {
if (!this.addon) {
return html`
`;
}
+ const hasOptions =
+ this.addon.options && Object.keys(this.addon.options).length;
+ const hasSchema =
+ this.addon.schema && Object.keys(this.addon.schema).length;
+
return html`
-
- ${this.addon.network
- ? html`
-
- `
- : ""}
- ${this.addon.audio
+ ${hasOptions || hasSchema || this.addon.network || this.addon.audio
? html`
-
+ ${hasOptions || hasSchema
+ ? html`
+
+ `
+ : ""}
+ ${this.addon.network
+ ? html`
+
+ `
+ : ""}
+ ${this.addon.audio
+ ? html`
+
+ `
+ : ""}
`
- : ""}
+ : "This add-on does not expose configuration for you to mess with.... 👋"}
`;
}
diff --git a/hassio/src/addon-view/hassio-addon-dashboard.ts b/hassio/src/addon-view/hassio-addon-dashboard.ts
index 9876486d5f14..bee5d12166db 100644
--- a/hassio/src/addon-view/hassio-addon-dashboard.ts
+++ b/hassio/src/addon-view/hassio-addon-dashboard.ts
@@ -14,12 +14,12 @@ import {
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
+import "../../../src/components/ha-circular-progress";
import {
fetchHassioAddonInfo,
HassioAddonDetails,
} from "../../../src/data/hassio/addon";
import "../../../src/layouts/hass-tabs-subpage";
-import "../../../src/components/ha-circular-progress";
import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types";
diff --git a/hassio/src/addon-view/info/hassio-addon-info-tab.ts b/hassio/src/addon-view/info/hassio-addon-info-tab.ts
index a2c8fc378bb8..620ea89f5122 100644
--- a/hassio/src/addon-view/info/hassio-addon-info-tab.ts
+++ b/hassio/src/addon-view/info/hassio-addon-info-tab.ts
@@ -7,8 +7,8 @@ import {
property,
TemplateResult,
} from "lit-element";
-import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import "../../../../src/components/ha-circular-progress";
+import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
diff --git a/hassio/src/addon-view/log/hassio-addon-log-tab.ts b/hassio/src/addon-view/log/hassio-addon-log-tab.ts
index 8961e61dd983..54bace246b7d 100644
--- a/hassio/src/addon-view/log/hassio-addon-log-tab.ts
+++ b/hassio/src/addon-view/log/hassio-addon-log-tab.ts
@@ -7,8 +7,8 @@ import {
property,
TemplateResult,
} from "lit-element";
-import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import "../../../../src/components/ha-circular-progress";
+import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
diff --git a/hassio/src/components/supervisor-metric.ts b/hassio/src/components/supervisor-metric.ts
new file mode 100644
index 000000000000..b0af0fd9a20a
--- /dev/null
+++ b/hassio/src/components/supervisor-metric.ts
@@ -0,0 +1,87 @@
+import {
+ css,
+ CSSResult,
+ customElement,
+ html,
+ LitElement,
+ property,
+ TemplateResult,
+} from "lit-element";
+import { classMap } from "lit-html/directives/class-map";
+import "../../../src/components/ha-bar";
+import "../../../src/components/ha-settings-row";
+import { roundWithOneDecimal } from "../../../src/util/calculate";
+
+@customElement("supervisor-metric")
+class SupervisorMetric extends LitElement {
+ @property({ type: Number }) public value!: number;
+
+ @property({ type: String }) public description!: string;
+
+ @property({ type: String }) public tooltip?: string;
+
+ protected render(): TemplateResult {
+ const roundedValue = roundWithOneDecimal(this.value);
+ return html`
+
+ ${this.description}
+
+
+
+ ${roundedValue}%
+
+ 50,
+ "target-critical": roundedValue > 85,
+ })}"
+ .value=${this.value}
+ >
+
+ `;
+ }
+
+ static get styles(): CSSResult {
+ return css`
+ ha-settings-row {
+ padding: 0;
+ height: 54px;
+ width: 100%;
+ }
+ ha-settings-row > div[slot="description"] {
+ white-space: normal;
+ color: var(--secondary-text-color);
+ display: flex;
+ justify-content: space-between;
+ }
+ ha-bar {
+ --ha-bar-primary-color: var(
+ --hassio-bar-ok-color,
+ var(--success-color)
+ );
+ }
+ .target-warning {
+ --ha-bar-primary-color: var(
+ --hassio-bar-warning-color,
+ var(--warning-color)
+ );
+ }
+ .target-critical {
+ --ha-bar-primary-color: var(
+ --hassio-bar-critical-color,
+ var(--error-color)
+ );
+ }
+ .value {
+ width: 42px;
+ padding-right: 4px;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "supervisor-metric": SupervisorMetric;
+ }
+}
diff --git a/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts b/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts
index 6b36d31e5cc4..95177a18f524 100644
--- a/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts
+++ b/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts
@@ -3,9 +3,9 @@ import {
CSSResult,
customElement,
html,
+ internalProperty,
LitElement,
property,
- internalProperty,
TemplateResult,
} from "lit-element";
import { createCloseHeading } from "../../../../src/components/ha-dialog";
diff --git a/hassio/src/entrypoint.ts b/hassio/src/entrypoint.ts
index 00c34787e603..24d3e45359e4 100644
--- a/hassio/src/entrypoint.ts
+++ b/hassio/src/entrypoint.ts
@@ -1,6 +1,7 @@
+// Compat needs to be first import
import "../../src/resources/compatibility";
-import "../../src/resources/safari-14-attachshadow-patch";
import "../../src/resources/roboto";
+import "../../src/resources/safari-14-attachshadow-patch";
import "./hassio-main";
const styleEl = document.createElement("style");
diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts
index 2ee909885e05..81d736e881b7 100644
--- a/hassio/src/hassio-main.ts
+++ b/hassio/src/hassio-main.ts
@@ -1,11 +1,11 @@
-import { html, PropertyValues, customElement, property } from "lit-element";
-import "./hassio-router";
-import { HomeAssistant, Route } from "../../src/types";
-import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
+import { customElement, html, property, PropertyValues } from "lit-element";
+import { atLeastVersion } from "../../src/common/config/version";
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
import { fireEvent } from "../../src/common/dom/fire_event";
+import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
-import { atLeastVersion } from "../../src/common/config/version";
+import { HomeAssistant, Route } from "../../src/types";
+import "./hassio-router";
import { SupervisorBaseElement } from "./supervisor-base-element";
@customElement("hassio-main")
diff --git a/hassio/src/ingress-view/hassio-ingress-view.ts b/hassio/src/ingress-view/hassio-ingress-view.ts
index 14962c6f36c4..531673ac2f32 100644
--- a/hassio/src/ingress-view/hassio-ingress-view.ts
+++ b/hassio/src/ingress-view/hassio-ingress-view.ts
@@ -1,14 +1,17 @@
+import { mdiMenu } from "@mdi/js";
import {
css,
CSSResult,
customElement,
html,
+ internalProperty,
LitElement,
property,
- internalProperty,
PropertyValues,
TemplateResult,
} from "lit-element";
+import { fireEvent } from "../../../src/common/dom/fire_event";
+import { navigate } from "../../../src/common/navigate";
import {
fetchHassioAddonInfo,
HassioAddonDetails,
@@ -17,13 +20,10 @@ import {
createHassioSession,
validateHassioSession,
} from "../../../src/data/hassio/ingress";
+import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
import "../../../src/layouts/hass-loading-screen";
import "../../../src/layouts/hass-subpage";
import { HomeAssistant, Route } from "../../../src/types";
-import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
-import { navigate } from "../../../src/common/navigate";
-import { mdiMenu } from "@mdi/js";
-import { fireEvent } from "../../../src/common/dom/fire_event";
@customElement("hassio-ingress-view")
class HassioIngressView extends LitElement {
diff --git a/hassio/src/snapshots/hassio-snapshots.ts b/hassio/src/snapshots/hassio-snapshots.ts
index d156f567a9ec..4cce8cc0ff2a 100644
--- a/hassio/src/snapshots/hassio-snapshots.ts
+++ b/hassio/src/snapshots/hassio-snapshots.ts
@@ -264,7 +264,7 @@ class HassioSnapshots extends LitElement {
}
protected updated(changedProps: PropertyValues) {
- if (changedProps.has("supervisorInfo")) {
+ if (changedProps.has("supervisor")) {
this._addonList = this.supervisor.supervisor.addons
.map((addon) => ({
slug: addon.slug,
diff --git a/hassio/src/system/hassio-core-info.ts b/hassio/src/system/hassio-core-info.ts
new file mode 100644
index 000000000000..96c3aad65fb8
--- /dev/null
+++ b/hassio/src/system/hassio-core-info.ts
@@ -0,0 +1,246 @@
+import "@material/mwc-button";
+import "@material/mwc-list/mwc-list-item";
+import {
+ css,
+ CSSResult,
+ customElement,
+ html,
+ internalProperty,
+ LitElement,
+ property,
+ TemplateResult,
+} from "lit-element";
+import "../../../src/components/buttons/ha-progress-button";
+import "../../../src/components/ha-button-menu";
+import "../../../src/components/ha-card";
+import "../../../src/components/ha-settings-row";
+import {
+ extractApiErrorMessage,
+ fetchHassioStats,
+ HassioStats,
+} from "../../../src/data/hassio/common";
+import { restartCore, updateCore } from "../../../src/data/supervisor/core";
+import { Supervisor } from "../../../src/data/supervisor/supervisor";
+import {
+ showAlertDialog,
+ showConfirmationDialog,
+} from "../../../src/dialogs/generic/show-dialog-box";
+import { haStyle } from "../../../src/resources/styles";
+import { HomeAssistant } from "../../../src/types";
+import { bytesToString } from "../../../src/util/bytes-to-string";
+import "../components/supervisor-metric";
+import { hassioStyle } from "../resources/hassio-style";
+
+@customElement("hassio-core-info")
+class HassioCoreInfo extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ attribute: false }) public supervisor!: Supervisor;
+
+ @internalProperty() private _metrics?: HassioStats;
+
+ protected render(): TemplateResult | void {
+ const metrics = [
+ {
+ description: "Core CPU Usage",
+ value: this._metrics?.cpu_percent,
+ },
+ {
+ description: "Core RAM Usage",
+ value: this._metrics?.memory_percent,
+ tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
+ this._metrics?.memory_limit
+ )}`,
+ },
+ ];
+
+ return html`
+
+
+
+
+
+ Version
+
+
+ core-${this.supervisor.core.version}
+
+
+
+
+ Newest Version
+
+
+ core-${this.supervisor.core.version_latest}
+
+ ${this.supervisor.core.update_available
+ ? html`
+
+ Update
+
+ `
+ : ""}
+
+
+
+ ${metrics.map(
+ (metric) =>
+ html`
+
+ `
+ )}
+
+
+
+
+ Restart Core
+
+
+
+ `;
+ }
+
+ protected firstUpdated(): void {
+ this._loadData();
+ }
+
+ private async _loadData(): Promise
{
+ this._metrics = await fetchHassioStats(this.hass, "core");
+ }
+
+ private async _coreRestart(ev: CustomEvent): Promise {
+ const button = ev.currentTarget as any;
+ button.progress = true;
+
+ const confirmed = await showConfirmationDialog(this, {
+ title: "Restart Home Assistant Core",
+ text: "Are you sure you want to restart Home Assistant Core",
+ confirmText: "restart",
+ dismissText: "cancel",
+ });
+
+ if (!confirmed) {
+ button.progress = false;
+ return;
+ }
+
+ try {
+ await restartCore(this.hass);
+ } catch (err) {
+ showAlertDialog(this, {
+ title: "Failed to restart Home Assistant Core",
+ text: extractApiErrorMessage(err),
+ });
+ } finally {
+ button.progress = false;
+ }
+ }
+
+ private async _coreUpdate(ev: CustomEvent): Promise {
+ const button = ev.currentTarget as any;
+ button.progress = true;
+
+ const confirmed = await showConfirmationDialog(this, {
+ title: "Update Home Assistant Core",
+ text: `Are you sure you want to update Home Assistant Core to version ${this.supervisor.core.version_latest}?`,
+ confirmText: "update",
+ dismissText: "cancel",
+ });
+
+ if (!confirmed) {
+ button.progress = false;
+ return;
+ }
+
+ try {
+ await updateCore(this.hass);
+ } catch (err) {
+ showAlertDialog(this, {
+ title: "Failed to update Home Assistant Core",
+ text: extractApiErrorMessage(err),
+ });
+ } finally {
+ button.progress = false;
+ }
+ }
+
+ static get styles(): CSSResult[] {
+ return [
+ haStyle,
+ hassioStyle,
+ css`
+ ha-card {
+ height: 100%;
+ justify-content: space-between;
+ flex-direction: column;
+ display: flex;
+ }
+ .card-actions {
+ height: 48px;
+ border-top: none;
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ }
+ .card-content {
+ display: flex;
+ flex-direction: column;
+ height: calc(100% - 124px);
+ justify-content: space-between;
+ }
+ ha-settings-row {
+ padding: 0;
+ height: 54px;
+ width: 100%;
+ }
+ ha-settings-row[three-line] {
+ height: 74px;
+ }
+ ha-settings-row > span[slot="description"] {
+ white-space: normal;
+ color: var(--secondary-text-color);
+ }
+
+ .warning {
+ --mdc-theme-primary: var(--error-color);
+ }
+
+ ha-button-menu {
+ color: var(--secondary-text-color);
+ --mdc-menu-min-width: 200px;
+ }
+ @media (min-width: 563px) {
+ paper-listbox {
+ max-height: 150px;
+ overflow: auto;
+ }
+ }
+ paper-item {
+ cursor: pointer;
+ min-height: 35px;
+ }
+ mwc-list-item ha-svg-icon {
+ color: var(--secondary-text-color);
+ }
+ `,
+ ];
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "hassio-core-info": HassioCoreInfo;
+ }
+}
diff --git a/hassio/src/system/hassio-host-info.ts b/hassio/src/system/hassio-host-info.ts
index 42b066c2145a..773fcc8bab87 100644
--- a/hassio/src/system/hassio-host-info.ts
+++ b/hassio/src/system/hassio-host-info.ts
@@ -43,6 +43,11 @@ import {
} from "../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types";
+import {
+ getValueInPercentage,
+ roundWithOneDecimal,
+} from "../../../src/util/calculate";
+import "../components/supervisor-metric";
import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio-markdown";
import { showNetworkDialog } from "../dialogs/network/show-dialog-network";
import { hassioStyle } from "../resources/hassio-style";
@@ -57,80 +62,105 @@ class HassioHostInfo extends LitElement {
const primaryIpAddress = this.supervisor.host.features.includes("network")
? this._primaryIpAddress(this.supervisor.network!)
: "";
+
+ const metrics = [
+ {
+ description: "Used Space",
+ value: this._getUsedSpace(
+ this.supervisor.host.disk_used,
+ this.supervisor.host.disk_total
+ ),
+ tooltip: `${this.supervisor.host.disk_used} GB/${this.supervisor.host.disk_total} GB`,
+ },
+ ];
return html`
-
+
- ${this.supervisor.host.features.includes("hostname")
- ? html`
-
- Hostname
-
-
- ${this.supervisor.host.hostname}
-
-
-
- `
- : ""}
- ${this.supervisor.host.features.includes("network")
- ? html`
-
- IP Address
-
-
- ${primaryIpAddress}
-
-
-
- `
- : ""}
-
-
-
- Operating System
-
-
- ${this.supervisor.host.operating_system}
-
- ${this.supervisor.os.update_available
- ? html`
-
+ ${this.supervisor.host.features.includes("hostname")
+ ? html`
+
+ Hostname
+
+
+ ${this.supervisor.host.hostname}
+
+
- Update
-
- `
+
+ `
: ""}
-
- ${!this.supervisor.host.features.includes("hassos")
- ? html`
-
- Docker version
-
-
- ${this.supervisor.info.docker}
-
- `
- : ""}
- ${this.supervisor.host.deployment
- ? html`
-
- Deployment
-
-
- ${this.supervisor.host.deployment}
-
- `
- : ""}
+ ${this.supervisor.host.features.includes("network")
+ ? html`
+
+ IP Address
+
+
+ ${primaryIpAddress}
+
+
+
+ `
+ : ""}
+
+
+
+ Operating System
+
+
+ ${this.supervisor.host.operating_system}
+
+ ${this.supervisor.os.update_available
+ ? html`
+
+ Update
+
+ `
+ : ""}
+
+ ${!this.supervisor.host.features.includes("hassos")
+ ? html`
+
+ Docker version
+
+
+ ${this.supervisor.info.docker}
+
+ `
+ : ""}
+ ${this.supervisor.host.deployment
+ ? html`
+
+ Deployment
+
+
+ ${this.supervisor.host.deployment}
+
+ `
+ : ""}
+
+
+ ${metrics.map(
+ (metric) =>
+ html`
+
+ `
+ )}
+