mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-15 05:16:34 +00:00
parent
f9e97c0577
commit
b261e779e5
@ -7,6 +7,32 @@
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
<meta name="theme-color" content="#2157BC" />
|
||||
<meta property="fb:app_id" content="338291289691179" />
|
||||
<meta property="og:title" content="Home Assistant Demo" />
|
||||
<meta property="og:site_name" content="Home Assistant" />
|
||||
<meta property="og:url" content="https://demo.home-assistant.io/" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Open source home automation that puts local control and privacy first."
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://www.home-assistant.io/images/default-social.png"
|
||||
/>
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@home_assistant" />
|
||||
|
||||
<meta name="twitter:title" content="Home Assistant" />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="Open source home automation that puts local control and privacy first."
|
||||
/>
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://www.home-assistant.io/images/default-social.png"
|
||||
/>
|
||||
<title>Home Assistant Demo</title>
|
||||
<script src="./custom-elements-es5-adapter.js"></script>
|
||||
<script src="./compatibility.js"></script>
|
||||
|
@ -18,9 +18,12 @@ export const setDemoConfig = async (
|
||||
lovelace: Lovelace,
|
||||
index: number
|
||||
) => {
|
||||
const confProm = demoConfigs[index]();
|
||||
const config = await confProm;
|
||||
|
||||
selectedDemoConfigIndex = index;
|
||||
selectedDemoConfig = demoConfigs[index]();
|
||||
const config = await selectedDemoConfig;
|
||||
selectedDemoConfig = confProm;
|
||||
|
||||
hass.addEntities(config.entities(), true);
|
||||
lovelace.saveConfig(config.lovelace());
|
||||
hass.mockTheme(config.theme());
|
||||
|
@ -352,9 +352,18 @@ export const demoLovelaceKernehed: () => LovelaceConfig = () => ({
|
||||
},
|
||||
{
|
||||
entities: [
|
||||
"sensor.pi_hole_dns_queries_today",
|
||||
"sensor.pi_hole_ads_blocked_today",
|
||||
"sensor.pi_hole_dns_unique_clients",
|
||||
{
|
||||
entity: "sensor.pi_hole_dns_queries_today",
|
||||
name: "DNS Queries Today",
|
||||
},
|
||||
{
|
||||
entity: "sensor.pi_hole_ads_blocked_today",
|
||||
name: "Ads Blocked Today",
|
||||
},
|
||||
{
|
||||
entity: "sensor.pi_hole_dns_unique_clients",
|
||||
name: "DNS Unique Clients",
|
||||
},
|
||||
],
|
||||
show_header_toggle: false,
|
||||
type: "entities",
|
||||
@ -369,16 +378,16 @@ export const demoLovelaceKernehed: () => LovelaceConfig = () => ({
|
||||
"binary_sensor.windows_server",
|
||||
"binary_sensor.teamspeak",
|
||||
"binary_sensor.harmony_hub",
|
||||
{
|
||||
style: {
|
||||
height: "1px",
|
||||
width: "85%",
|
||||
"margin-left": "auto",
|
||||
background: "#62717b",
|
||||
"margin-right": "auto",
|
||||
},
|
||||
type: "divider",
|
||||
},
|
||||
// {
|
||||
// style: {
|
||||
// height: "1px",
|
||||
// width: "85%",
|
||||
// "margin-left": "auto",
|
||||
// background: "#62717b",
|
||||
// "margin-right": "auto",
|
||||
// },
|
||||
// type: "divider",
|
||||
// },
|
||||
// {
|
||||
// items: ["sensor.uptime_router", "sensor.installerad_routeros"],
|
||||
// head: {
|
||||
|
@ -231,62 +231,62 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
|
||||
cards: [
|
||||
{
|
||||
cards: [
|
||||
{
|
||||
entities: [
|
||||
{
|
||||
name: "Front door lock",
|
||||
entity: "sensor.front_door_lock",
|
||||
},
|
||||
{
|
||||
name: "Yard door lock",
|
||||
entity: "sensor.yard_door_lock",
|
||||
},
|
||||
"sensor.front_door",
|
||||
"sensor.back_door",
|
||||
"sensor.backyard_door",
|
||||
"sensor.balcony_door",
|
||||
"sensor.yard_door",
|
||||
{
|
||||
name: "Dining area",
|
||||
entity: "sensor.dining_area_window",
|
||||
},
|
||||
{
|
||||
name: "Bedroom",
|
||||
entity: "sensor.bedroom_window",
|
||||
},
|
||||
{
|
||||
name: "Ring motion",
|
||||
entity: "sensor.front_door_outdoor_movement",
|
||||
},
|
||||
"sensor.hallway_movement",
|
||||
"sensor.passage_movement",
|
||||
"sensor.upstairs_hallway_movement",
|
||||
"sensor.living_room_movement",
|
||||
"sensor.back_door_camera_movement",
|
||||
{
|
||||
name: "Storage door",
|
||||
entity: "sensor.yard_storage_door",
|
||||
},
|
||||
"sensor.water_heater",
|
||||
"sensor.kitchen_sink",
|
||||
"binary_sensor.smoke_sensor_158d0001d37bdd",
|
||||
"binary_sensor.smoke_sensor_158d0001d37be5",
|
||||
"binary_sensor.smoke_sensor_158d0001d37c82",
|
||||
],
|
||||
show_empty: false,
|
||||
type: "entity-filter",
|
||||
card: {
|
||||
type: "glance",
|
||||
show_state: false,
|
||||
},
|
||||
state_filter: [
|
||||
"Open",
|
||||
"Movement detected",
|
||||
"Leaking",
|
||||
"Unlocked",
|
||||
"on",
|
||||
],
|
||||
},
|
||||
// {
|
||||
// entities: [
|
||||
// {
|
||||
// name: "Front door lock",
|
||||
// entity: "sensor.front_door_lock",
|
||||
// },
|
||||
// {
|
||||
// name: "Yard door lock",
|
||||
// entity: "sensor.yard_door_lock",
|
||||
// },
|
||||
// "sensor.front_door",
|
||||
// "sensor.back_door",
|
||||
// "sensor.backyard_door",
|
||||
// "sensor.balcony_door",
|
||||
// "sensor.yard_door",
|
||||
// {
|
||||
// name: "Dining area",
|
||||
// entity: "sensor.dining_area_window",
|
||||
// },
|
||||
// {
|
||||
// name: "Bedroom",
|
||||
// entity: "sensor.bedroom_window",
|
||||
// },
|
||||
// {
|
||||
// name: "Ring motion",
|
||||
// entity: "sensor.front_door_outdoor_movement",
|
||||
// },
|
||||
// "sensor.hallway_movement",
|
||||
// "sensor.passage_movement",
|
||||
// "sensor.upstairs_hallway_movement",
|
||||
// "sensor.living_room_movement",
|
||||
// "sensor.back_door_camera_movement",
|
||||
// {
|
||||
// name: "Storage door",
|
||||
// entity: "sensor.yard_storage_door",
|
||||
// },
|
||||
// "sensor.water_heater",
|
||||
// "sensor.kitchen_sink",
|
||||
// "binary_sensor.smoke_sensor_158d0001d37bdd",
|
||||
// "binary_sensor.smoke_sensor_158d0001d37be5",
|
||||
// "binary_sensor.smoke_sensor_158d0001d37c82",
|
||||
// ],
|
||||
// show_empty: false,
|
||||
// type: "entity-filter",
|
||||
// card: {
|
||||
// type: "glance",
|
||||
// show_state: false,
|
||||
// },
|
||||
// state_filter: [
|
||||
// "Open",
|
||||
// "Movement detected",
|
||||
// "Leaking",
|
||||
// "Unlocked",
|
||||
// "on",
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
entities: [
|
||||
"light.outdoor_lights",
|
||||
@ -676,6 +676,7 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
|
||||
},
|
||||
],
|
||||
title: "Home info",
|
||||
path: "home_info",
|
||||
icon: "mdi:home-heart",
|
||||
},
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ export const demoThemeTeachingbirds = () => ({
|
||||
"paper-item-icon-color": "#d3d3d3",
|
||||
"divider-color": "rgba(255, 255, 255, 0.12)",
|
||||
"primary-color": "#389638",
|
||||
"light-primary-color": "#6f956f",
|
||||
"label-badge-red": "var(--primary-color)",
|
||||
"paper-slider-secondary-color": "var(--light-primary-color)",
|
||||
"paper-slider-knob-color": "var(--primary-color)",
|
||||
|
@ -1,6 +1,14 @@
|
||||
import { LitElement, html, CSSResult, css } from "lit-element";
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
CSSResult,
|
||||
css,
|
||||
PropertyDeclarations,
|
||||
} from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import "@polymer/paper-icon-button";
|
||||
import "@polymer/paper-button";
|
||||
import "@polymer/paper-spinner/paper-spinner-lite";
|
||||
import "../../../src/components/ha-card";
|
||||
import { LovelaceCard, Lovelace } from "../../../src/panels/lovelace/types";
|
||||
import { LovelaceCardConfig } from "../../../src/data/lovelace";
|
||||
@ -15,6 +23,15 @@ import {
|
||||
export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
public lovelace?: Lovelace;
|
||||
public hass?: MockHomeAssistant;
|
||||
private _switching?: boolean;
|
||||
|
||||
static get properties(): PropertyDeclarations {
|
||||
return {
|
||||
lovelace: {},
|
||||
hass: {},
|
||||
_switching: {},
|
||||
};
|
||||
}
|
||||
|
||||
public getCardSize() {
|
||||
return 2;
|
||||
@ -28,16 +45,21 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-card header="Home Assistant Demo Switcher">
|
||||
<ha-card>
|
||||
<div class="picker">
|
||||
<paper-icon-button
|
||||
@click=${this._prevConfig}
|
||||
icon="hass:chevron-right"
|
||||
style="transform: rotate(180deg)"
|
||||
.disabled=${this._switching}
|
||||
></paper-icon-button>
|
||||
<div>
|
||||
${
|
||||
until(
|
||||
this._switching
|
||||
? html`
|
||||
<paper-spinner-lite active></paper-spinner-lite>
|
||||
`
|
||||
: until(
|
||||
selectedDemoConfig.then(
|
||||
(conf) => html`
|
||||
${conf.name}
|
||||
@ -56,8 +78,18 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
<paper-icon-button
|
||||
@click=${this._nextConfig}
|
||||
icon="hass:chevron-right"
|
||||
.disabled=${this._switching}
|
||||
></paper-icon-button>
|
||||
</div>
|
||||
<div class="content">
|
||||
Welcome home! You've reached the Home Assistant demo where we showcase
|
||||
the best UIs created by our community.
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a href="https://www.home-assistant.io" target="_blank">
|
||||
<paper-button>Learn more about Home Assistant</paper-button>
|
||||
</a>
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
@ -78,39 +110,28 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
);
|
||||
}
|
||||
|
||||
private _updateConfig(index: number) {
|
||||
setDemoConfig(this.hass!, this.lovelace!, index);
|
||||
private async _updateConfig(index: number) {
|
||||
this._switching = true;
|
||||
try {
|
||||
await setDemoConfig(this.hass!, this.lovelace!, index);
|
||||
} catch (err) {
|
||||
alert("Failed to switch config :-(");
|
||||
} finally {
|
||||
this._switching = false;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
css`
|
||||
.content {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 16px 16px 16px 38px;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
li:first-child {
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
||||
li:last-child {
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.picker {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -125,6 +146,15 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
.picker small {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.actions {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.actions paper-button {
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ class HaDemo extends HomeAssistant {
|
||||
protected async _handleConnProm() {
|
||||
const initial: Partial<HomeAssistant> = {
|
||||
panelUrl: (this as any).panelUrl,
|
||||
// Override updateHass so that the correct hass lifecycle methods are called
|
||||
updateHass: (hassUpdate) =>
|
||||
// @ts-ignore
|
||||
this._updateHass(hassUpdate),
|
||||
};
|
||||
|
||||
const hass = provideHass(this, initial);
|
||||
|
@ -45,15 +45,8 @@ export const provideHass = (
|
||||
} = {};
|
||||
const entities = {};
|
||||
|
||||
function updateHass(obj: Partial<MockHomeAssistant>) {
|
||||
const newHass = { ...hass(), ...obj };
|
||||
elements.forEach((el) => {
|
||||
el.hass = newHass;
|
||||
});
|
||||
}
|
||||
|
||||
function updateStates(newStates: HassEntities) {
|
||||
updateHass({
|
||||
hass().updateHass({
|
||||
states: { ...hass().states, ...newStates },
|
||||
});
|
||||
}
|
||||
@ -66,7 +59,7 @@ export const provideHass = (
|
||||
states[ent.entityId] = ent.toState();
|
||||
});
|
||||
if (replace) {
|
||||
updateHass({
|
||||
hass().updateHass({
|
||||
states,
|
||||
});
|
||||
} else {
|
||||
@ -93,7 +86,7 @@ export const provideHass = (
|
||||
);
|
||||
});
|
||||
|
||||
updateHass({
|
||||
const hassObj: MockHomeAssistant = {
|
||||
// Home Assistant properties
|
||||
auth: {} as any,
|
||||
connection: {
|
||||
@ -141,11 +134,11 @@ export const provideHass = (
|
||||
panelUrl: "lovelace",
|
||||
|
||||
language: getActiveTranslation(),
|
||||
resources: null,
|
||||
resources: null as any,
|
||||
|
||||
translationMetadata,
|
||||
translationMetadata: translationMetadata as any,
|
||||
dockedSidebar: false,
|
||||
moreInfoEntityId: null,
|
||||
moreInfoEntityId: null as any,
|
||||
async callService(domain, service, data) {
|
||||
fireEvent(elements[0], "hass-notification", {
|
||||
message: `Called service ${domain}/${service}`,
|
||||
@ -197,7 +190,12 @@ export const provideHass = (
|
||||
|
||||
// Mock stuff
|
||||
mockEntities: entities,
|
||||
updateHass,
|
||||
updateHass(obj: Partial<MockHomeAssistant>) {
|
||||
const newHass = { ...hass(), ...obj };
|
||||
elements.forEach((el) => {
|
||||
el.hass = newHass;
|
||||
});
|
||||
},
|
||||
updateStates,
|
||||
addEntities,
|
||||
mockWS(type, callback) {
|
||||
@ -208,7 +206,7 @@ export const provideHass = (
|
||||
(eventListeners[event] || []).forEach((fn) => fn(event));
|
||||
},
|
||||
mockTheme(theme) {
|
||||
updateHass({
|
||||
hass().updateHass({
|
||||
selectedTheme: theme ? "mock" : "default",
|
||||
themes: {
|
||||
...hass().themes,
|
||||
@ -217,15 +215,22 @@ export const provideHass = (
|
||||
},
|
||||
},
|
||||
});
|
||||
const hassObj = hass();
|
||||
elements.forEach((el) => {
|
||||
applyThemesOnElement(el, hassObj.themes, hassObj.selectedTheme, true);
|
||||
});
|
||||
const { themes, selectedTheme } = hass();
|
||||
applyThemesOnElement(
|
||||
document.documentElement,
|
||||
themes,
|
||||
selectedTheme,
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
...overrideData,
|
||||
} as MockHomeAssistant);
|
||||
};
|
||||
|
||||
// Update the elements. Note, we call it on hassObj so that if it was
|
||||
// overridden (like in the demo), it will still work.
|
||||
hassObj.updateHass(hassObj);
|
||||
|
||||
// @ts-ignore
|
||||
return hass();
|
||||
return hassObj;
|
||||
};
|
||||
|
@ -47,14 +47,14 @@ export class HomeAssistant extends ext(PolymerElement, [
|
||||
use-hash-as-path="[[_useHashAsPath]]"
|
||||
></app-location>
|
||||
<app-route
|
||||
route="{{route}}"
|
||||
route="[[route]]"
|
||||
pattern="/:panel"
|
||||
data="{{routeData}}"
|
||||
></app-route>
|
||||
<template is="dom-if" if="[[showMain]]" restamp>
|
||||
<home-assistant-main
|
||||
hass="[[hass]]"
|
||||
route="{{route}}"
|
||||
route="[[route]]"
|
||||
></home-assistant-main>
|
||||
</template>
|
||||
|
||||
|
@ -117,7 +117,7 @@ class PartialPanelResolver extends NavigateMixin(PolymerElement) {
|
||||
}
|
||||
</style>
|
||||
<app-route
|
||||
route="{{route}}"
|
||||
route="[[route]]"
|
||||
pattern="/:panel"
|
||||
data="{{routeData}}"
|
||||
tail="{{routeTail}}"
|
||||
|
@ -86,7 +86,7 @@ export interface HomeAssistant {
|
||||
services: HassServices;
|
||||
config: HassConfig;
|
||||
themes: Themes;
|
||||
selectedTheme: string | null;
|
||||
selectedTheme?: string | null;
|
||||
panels: Panels;
|
||||
panelUrl: string;
|
||||
language: string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user