More demo stubs (#2529)

* More demo stubs

* History stub actually generates mocks

* More tweaks

* Add more entities
pull/2530/head
Paulus Schoutsen 2019-01-21 21:18:01 -08:00 committed by GitHub
parent 547f829f5b
commit 24b0eb8ce4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 534 additions and 414 deletions

View File

@ -19,6 +19,7 @@ export const demoThemeJimpower = () => ({
"paper-grey-200": "#414A59", "paper-grey-200": "#414A59",
"label-badge-background-color": "#2E333A", "label-badge-background-color": "#2E333A",
"paper-card-header-color": "var(--accent-color)", "paper-card-header-color": "var(--accent-color)",
"sidebar-icon-color": "var(--paper-item-icon-color)",
"paper-listbox-background-color": "#2E333A", "paper-listbox-background-color": "#2E333A",
"table-row-background-color": "#353840", "table-row-background-color": "#353840",
"paper-grey-50": "var(--primary-text-color)", "paper-grey-50": "var(--primary-text-color)",

View File

@ -93,7 +93,7 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
type: "icon", type: "icon",
tap_action: { tap_action: {
action: "navigate", action: "navigate",
navigation_path: "/lovelace/traffic", navigation_path: "/lovelace/home_info",
}, },
icon: "mdi:car", icon: "mdi:car",
}, },
@ -192,6 +192,12 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
], ],
type: "horizontal-stack", type: "horizontal-stack",
}, },
],
type: "vertical-stack",
},
{
type: "vertical-stack",
cards: [
{ {
cards: [ cards: [
{ {
@ -225,248 +231,180 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
type: "horizontal-stack", type: "horizontal-stack",
}, },
], ],
type: "vertical-stack", },
{
entities: [
"light.outdoor_lights",
{
name: "Yard net",
entity: "light.outdoor_yard_light_net",
},
"light.bedroom_ceiling_light",
"light.bedside_lamp",
"light.dining_area_ceiling_light_level",
"light.kitchen_ceiling_spotlights_level",
"light.floorlamp_reading_light",
"light.floorlamp_uplight",
"light.hallway_window_light",
"light.isa_ceiling_light",
"light.living_room_ceiling_light_level",
"light.living_room_spotlights_level",
"light.passage_ceiling_spotlights_level",
"light.stairs_lights_lights",
"light.walk_in_closet_lights",
"light.upstairs_hallway_ceiling_light_level",
"light.gateway_light_34ce008bfc4b",
],
show_empty: false,
type: "entity-filter",
card: {
type: "glance",
show_state: false,
},
state_filter: ["on"],
},
{
type: "shopping-list",
},
{
entities: [
{
entity: "switch.livingroom_tv",
name: "Tv",
icon: "mdi:television-classic",
},
// {
// hide_power: true,
// group: true,
// icon: "mdi:television-classic",
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.livingroom_tv",
// },
{
entity: "switch.livingroom_movie_system",
name: "Movie system",
icon: "mdi:movie",
},
// {
// hide_power: true,
// group: true,
// name: "Movie system",
// icon: "mdi:movie",
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.livingroom_movie_system",
// },
// {
// hide_power: true,
// type: "custom:mini-media-player",
// entity: "media_player.shield",
// group: true,
// icon: "mdi:cast",
// },
// {
// group: true,
// icon: "mdi:speaker-wireless",
// power_color: true,
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.sonos",
// },
// {
// group: true,
// name: "Chromecast Bedroom",
// icon: "mdi:cast",
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.sovrum",
// },
],
type: "entities",
},
{
image: "/assets/teachingbirds/plants.png",
elements: [
{
style: {
top: "7%",
"--ha-label-badge-font-size": "1em",
left: "2%",
transform: "none",
},
type: "state-badge",
entity: "sensor.small_chili_moisture",
},
{
style: {
top: "7%",
"--ha-label-badge-font-size": "1em",
left: "17%",
transform: "none",
},
type: "state-badge",
entity: "sensor.big_chili_moisture",
},
{
style: {
top: "7%",
"--ha-label-badge-font-size": "1em",
left: "32%",
transform: "none",
},
type: "state-badge",
entity: "sensor.herbs_moisture",
},
{
style: {
top: "12%",
"--ha-label-badge-font-size": "1em",
left: "92%",
},
type: "state-label",
entity: "sensor.greenhouse_temperature",
},
],
type: "picture-elements",
},
{
// show_name: false,
// entity: "camera.stockholm_meteogram",
// type: "picture-entity",
// show_state: false,
type: "picture",
image: "/assets/teachingbirds/meteogram.png",
}, },
{ {
cards: [ cards: [
{ {
cards: [ type: "gauge",
// { severity: {
// entities: [ green: 0,
// { yellow: 2,
// name: "Front door lock", red: 3,
// entity: "sensor.front_door_lock", },
// }, min: 0,
// { max: 6,
// name: "Yard door lock", title: "Downstairs",
// entity: "sensor.yard_door_lock", measurement: "visits",
// }, entity: "counter.litterbox_downstairs_visits",
// "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",
{
name: "Yard net",
entity: "light.outdoor_yard_light_net",
},
"light.bedroom_ceiling_light",
"light.bedside_lamp",
"light.dining_area_ceiling_light_level",
"light.kitchen_ceiling_spotlights_level",
"light.floorlamp_reading_light",
"light.floorlamp_uplight",
"light.hallway_window_light",
"light.isa_ceiling_light",
"light.living_room_ceiling_light_level",
"light.living_room_spotlights_level",
"light.passage_ceiling_spotlights_level",
"light.stairs_lights_lights",
"light.walk_in_closet_lights",
"light.upstairs_hallway_ceiling_light_level",
"light.gateway_light_34ce008bfc4b",
],
show_empty: false,
type: "entity-filter",
card: {
type: "glance",
show_state: false,
},
state_filter: ["on"],
},
],
type: "vertical-stack",
}, },
{ {
type: "shopping-list", type: "gauge",
}, severity: {
{ green: 0,
entities: [ yellow: 2,
{ red: 3,
entity: "switch.livingroom_tv", },
name: "Tv", min: 0,
icon: "mdi:television-classic", max: 6,
}, title: "Upstairs",
// { measurement: "visits",
// hide_power: true, entity: "counter.litterbox_upstairs_visits",
// group: true,
// icon: "mdi:television-classic",
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.livingroom_tv",
// },
{
entity: "switch.livingroom_movie_system",
name: "Movie system",
icon: "mdi:movie",
},
// {
// hide_power: true,
// group: true,
// name: "Movie system",
// icon: "mdi:movie",
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.livingroom_movie_system",
// },
// {
// hide_power: true,
// type: "custom:mini-media-player",
// entity: "media_player.shield",
// group: true,
// icon: "mdi:cast",
// },
// {
// group: true,
// icon: "mdi:speaker-wireless",
// power_color: true,
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.sonos",
// },
// {
// group: true,
// name: "Chromecast Bedroom",
// icon: "mdi:cast",
// artwork_border: true,
// type: "custom:mini-media-player",
// entity: "media_player.sovrum",
// },
],
type: "entities",
}, },
], ],
type: "vertical-stack", type: "horizontal-stack",
},
{
cards: [
{
image: "/assets/teachingbirds/plants.png",
elements: [
{
style: {
top: "30%",
"--ha-label-badge-font-size": "1em",
left: "10%",
},
type: "state-badge",
entity: "sensor.small_chili_moisture",
},
{
style: {
top: "30%",
"--ha-label-badge-font-size": "1em",
left: "25%",
},
type: "state-badge",
entity: "sensor.big_chili_moisture",
},
{
style: {
top: "30%",
"--ha-label-badge-font-size": "1em",
left: "40%",
},
type: "state-badge",
entity: "sensor.herbs_moisture",
},
{
style: {
top: "12%",
"--ha-label-badge-font-size": "1em",
left: "92%",
},
type: "state-label",
entity: "sensor.greenhouse_temperature",
},
],
type: "picture-elements",
},
{
// show_name: false,
// entity: "camera.stockholm_meteogram",
// type: "picture-entity",
// show_state: false,
type: "picture",
image: "/assets/teachingbirds/meteogram.png",
},
{
cards: [
{
type: "gauge",
severity: {
green: 0,
yellow: 2,
red: 3,
},
min: 0,
max: 6,
title: "Downstairs",
measurement: "visits",
entity: "counter.litterbox_downstairs_visits",
},
{
type: "gauge",
severity: {
green: 0,
yellow: 2,
red: 3,
},
min: 0,
max: 6,
title: "Upstairs",
measurement: "visits",
entity: "counter.litterbox_upstairs_visits",
},
],
type: "horizontal-stack",
},
],
type: "vertical-stack",
}, },
], ],
path: "home", path: "home",
@ -478,75 +416,75 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
{ {
cards: [ cards: [
{ {
cards: [ entity: "script.air_cleaner_quiet",
{ type: "entity-button",
entity: "script.air_cleaner_quiet", name: "AC bed",
type: "entity-button", tap_action: {
name: "AC bed", action: "call-service",
tap_action: { service_data: {
action: "call-service", entity_id: "script.air_cleaner_quiet",
service_data: {
entity_id: "script.air_cleaner_quiet",
},
service: "script.turn_on",
},
icon: "mdi:fan-off",
}, },
{ service: "script.turn_on",
entity: "script.air_cleaner_auto", },
type: "entity-button", icon: "mdi:fan-off",
name: "AC bed",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.air_cleaner_auto",
},
service: "script.turn_on",
},
icon: "mdi:fan",
},
{
entity: "script.air_cleaner_turbo",
type: "entity-button",
name: "AC bed",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.air_cleaner_turbo",
},
service: "script.turn_on",
},
icon: "mdi:run-fast",
},
{
entity: "script.ac_off",
type: "entity-button",
name: "AC",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.ac_off",
},
service: "script.turn_on",
},
icon: "mdi:fan-off",
},
{
entity: "script.ac_on",
type: "entity-button",
name: "AC",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.ac_on",
},
service: "script.turn_on",
},
icon: "mdi:fan",
},
],
type: "horizontal-stack",
}, },
{
entity: "script.air_cleaner_auto",
type: "entity-button",
name: "AC bed",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.air_cleaner_auto",
},
service: "script.turn_on",
},
icon: "mdi:fan",
},
{
entity: "script.air_cleaner_turbo",
type: "entity-button",
name: "AC bed",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.air_cleaner_turbo",
},
service: "script.turn_on",
},
icon: "mdi:run-fast",
},
{
entity: "script.ac_off",
type: "entity-button",
name: "AC",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.ac_off",
},
service: "script.turn_on",
},
icon: "mdi:fan-off",
},
{
entity: "script.ac_on",
type: "entity-button",
name: "AC",
tap_action: {
action: "call-service",
service_data: {
entity_id: "script.ac_on",
},
service: "script.turn_on",
},
icon: "mdi:fan",
},
],
type: "horizontal-stack",
},
{
cards: [
{ {
cards: [ cards: [
{ {
@ -595,91 +533,100 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
], ],
type: "horizontal-stack", type: "horizontal-stack",
}, },
{
entities: [
{
name: "Vacation",
entity: "input_boolean.vacation_mode",
},
"input_boolean.cleaning_day",
"input_boolean.guest_mode",
{
name: "Isa Mode",
tap_action: {
action: "toggle",
},
entity: "input_boolean.isa_mode",
},
],
show_header_toggle: false,
type: "glance",
},
{
entities: [
"sensor.pollen_bjork",
"sensor.pollen_gras",
"sensor.pollen_grabo",
],
type: "glance",
},
], ],
type: "vertical-stack", type: "vertical-stack",
}, },
{ {
cards: [ entities: [
{ {
states: ["arm_home", "arm_away", "arm_night"], name: "Vacation",
type: "alarm-panel", entity: "input_boolean.vacation_mode",
entity: "alarm_control_panel.house", tap_action: {
action: "toggle",
},
}, },
{ {
entities: [ entity: "input_boolean.cleaning_day",
{ tap_action: {
entity: "sensor.front_door", action: "toggle",
secondary_info: "last-changed", },
}, },
{ {
entity: "sensor.back_door", entity: "input_boolean.guest_mode",
secondary_info: "last-changed", tap_action: {
}, action: "toggle",
{ },
entity: "sensor.yard_door", },
secondary_info: "last-changed", {
}, name: "Isa Mode",
{ tap_action: {
entity: "sensor.balcony_door", action: "toggle",
secondary_info: "last-changed", },
}, entity: "input_boolean.isa_mode",
{
entity: "sensor.dining_area_window",
secondary_info: "last-changed",
},
{
entity: "sensor.bedroom_window",
secondary_info: "last-changed",
},
{
entity: "sensor.passage_movement",
secondary_info: "last-changed",
},
{
entity: "sensor.upstairs_hallway_movement",
secondary_info: "last-changed",
},
{
entity: "binary_sensor.stefans_room_motion",
secondary_info: "last-changed",
},
{
entity: "sensor.ring_front_door_last_motion",
secondary_info: "last-changed",
},
],
type: "entities",
}, },
], ],
type: "vertical-stack", show_header_toggle: false,
type: "glance",
}, },
{
entities: [
"sensor.pollen_bjork",
"sensor.pollen_gras",
"sensor.pollen_grabo",
],
type: "glance",
},
{
states: ["arm_home", "arm_away", "arm_night"],
type: "alarm-panel",
entity: "alarm_control_panel.house",
},
{
entities: [
{
entity: "sensor.front_door",
secondary_info: "last-changed",
},
{
entity: "sensor.back_door",
secondary_info: "last-changed",
},
{
entity: "sensor.yard_door",
secondary_info: "last-changed",
},
{
entity: "sensor.balcony_door",
secondary_info: "last-changed",
},
{
entity: "sensor.dining_area_window",
secondary_info: "last-changed",
},
{
entity: "sensor.bedroom_window",
secondary_info: "last-changed",
},
{
entity: "sensor.passage_movement",
secondary_info: "last-changed",
},
{
entity: "sensor.upstairs_hallway_movement",
secondary_info: "last-changed",
},
{
entity: "binary_sensor.stefans_room_motion",
secondary_info: "last-changed",
},
{
entity: "sensor.ring_front_door_last_motion",
secondary_info: "last-changed",
},
],
type: "entities",
},
{ {
cards: [ cards: [
{ {
@ -729,19 +676,16 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
cards: [ cards: [
{ {
entity: "scene.morning_lights", entity: "scene.morning_lights",
hold_action: { tap_action: {
action: "call-service", action: "call-service",
service: "script.goodnight", service: "script.goodnight",
}, },
type: "entity-button", type: "entity-button",
tap_action: {
action: "none",
},
icon: "mdi:weather-night", icon: "mdi:weather-night",
}, },
{ {
entity: "scene.morning_lights", entity: "scene.morning_lights",
hold_action: { tap_action: {
action: "call-service", action: "call-service",
service_data: { service_data: {
entity_id: "scene.morning_lights", entity_id: "scene.morning_lights",
@ -749,14 +693,11 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
service: "scene.turn_on", service: "scene.turn_on",
}, },
type: "entity-button", type: "entity-button",
tap_action: {
action: "none",
},
icon: "mdi:coffee-outline", icon: "mdi:coffee-outline",
}, },
{ {
entity: "scene.movie_time", entity: "scene.movie_time",
hold_action: { tap_action: {
action: "call-service", action: "call-service",
service_data: { service_data: {
entity_id: "scene.movie_time", entity_id: "scene.movie_time",
@ -764,9 +705,6 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
service: "scene.turn_on", service: "scene.turn_on",
}, },
type: "entity-button", type: "entity-button",
tap_action: {
action: "none",
},
icon: "mdi:television-classic", icon: "mdi:television-classic",
}, },
], ],
@ -820,32 +758,26 @@ export const demoLovelaceTeachingbirds: () => LovelaceConfig = () => ({
cards: [ cards: [
{ {
entity: "light.downstairs_lights", entity: "light.downstairs_lights",
hold_action: { tap_action: {
action: "call-service", action: "call-service",
service_data: { service_data: {
entity_id: "light.downstairs_lights", entity_id: "light.downstairs_lights",
}, },
service: "light.turn_off", service: "light.toggle",
}, },
type: "entity-button", type: "entity-button",
tap_action: {
action: "none",
},
icon: "mdi:page-layout-footer", icon: "mdi:page-layout-footer",
}, },
{ {
entity: "light.upstairs_lights", entity: "light.upstairs_lights",
hold_action: { tap_action: {
action: "call-service", action: "call-service",
service_data: { service_data: {
entity_id: "light.upstairs_lights", entity_id: "light.upstairs_lights",
}, },
service: "light.turn_off", service: "light.toggle",
}, },
type: "entity-button", type: "entity-button",
tap_action: {
action: "none",
},
icon: "mdi:page-layout-header", icon: "mdi:page-layout-header",
}, },
], ],

View File

@ -7,6 +7,9 @@ import { selectedDemoConfig } from "./configs/demo-configs";
import { mockTranslations } from "./stubs/translations"; import { mockTranslations } from "./stubs/translations";
import { mockHistory } from "./stubs/history"; import { mockHistory } from "./stubs/history";
import { mockShoppingList } from "./stubs/shopping_list"; import { mockShoppingList } from "./stubs/shopping_list";
import { mockSystemLog } from "./stubs/system_log";
import { mockTemplate } from "./stubs/template";
import { mockEvents } from "./stubs/events";
class HaDemo extends HomeAssistant { class HaDemo extends HomeAssistant {
protected async _handleConnProm() { protected async _handleConnProm() {
@ -24,6 +27,9 @@ class HaDemo extends HomeAssistant {
mockTranslations(hass); mockTranslations(hass);
mockHistory(hass); mockHistory(hass);
mockShoppingList(hass); mockShoppingList(hass);
mockSystemLog(hass);
mockTemplate(hass);
mockEvents(hass);
selectedDemoConfig.then((conf) => { selectedDemoConfig.then((conf) => {
hass.addEntities(conf.entities()); hass.addEntities(conf.entities());
if (conf.theme) { if (conf.theme) {

5
demo/src/stubs/events.ts Normal file
View File

@ -0,0 +1,5 @@
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
export const mockEvents = (hass: MockHomeAssistant) => {
hass.mockAPI("events", () => []);
};

View File

@ -1,5 +1,138 @@
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
import { HassEntity } from "home-assistant-js-websocket";
export const mockHistory = (hass: MockHomeAssistant) => { interface HistoryQueryParams {
hass.mockAPI(new RegExp("history/period/.+"), () => []); filter_entity_id: string;
end_time: string;
}
const parseQuery = <T>(queryString: string) => {
const query: any = {};
const items = queryString.split("&");
for (const item of items) {
const parts = item.split("=");
const key = decodeURIComponent(parts[0]);
const value = parts.length > 1 ? decodeURIComponent(parts[1]) : undefined;
query[key] = value;
}
return query as T;
};
const getTime = (minutesAgo) => {
const ts = new Date(Date.now() - minutesAgo * 60 * 1000);
return ts.toISOString();
};
const randomTimeAdjustment = (diff) => Math.random() * diff - diff / 2;
const maxTime = 1440;
const generateHistory = (state, deltas) => {
const changes =
typeof deltas[0] === "object"
? deltas
: deltas.map((st) => ({ state: st }));
const timeDiff = 900 / changes.length;
return changes.map((change, index) => {
let attributes;
if (!change.attributes && !state.attributes) {
attributes = {};
} else if (!change.attributes) {
attributes = state.attributes;
} else if (!state.attributes) {
attributes = change.attributes;
} else {
attributes = { ...state.attributes, ...change.attributes };
}
const time =
index === 0
? getTime(maxTime)
: getTime(maxTime - index * timeDiff + randomTimeAdjustment(timeDiff));
return {
attributes,
entity_id: state.entity_id,
state: change.state || state.state,
last_changed: time,
last_updated: time,
};
});
};
const incrementalUnits = ["clients", "queries", "ads"];
export const mockHistory = (mockHass: MockHomeAssistant) => {
mockHass.mockAPI(new RegExp("history/period/.+"), (
hass,
// @ts-ignore
method,
path,
// @ts-ignore
parameters
) => {
const params = parseQuery<HistoryQueryParams>(path.split("?")[1]);
const entities = params.filter_entity_id.split(",");
const results: HassEntity[][] = [];
for (const entityId of entities) {
const state = hass.states[entityId];
if (!state) {
continue;
}
if (!state.attributes.unit_of_measurement) {
results.push(generateHistory(state, [state.state]));
continue;
}
const numberState = Number(state.state);
if (isNaN(numberState)) {
// tslint:disable-next-line
console.log(
"Ignoring state with unparsable state but with a unit",
entityId,
state
);
continue;
}
const statesToGenerate = 15;
let genFunc;
if (incrementalUnits.includes(state.attributes.unit_of_measurement)) {
let initial = Math.floor(
numberState * 0.4 + numberState * Math.random() * 0.2
);
const diff = Math.max(
1,
Math.floor((numberState - initial) / statesToGenerate)
);
genFunc = () => {
initial += diff;
return Math.min(numberState, initial);
};
} else {
const diff = Math.floor(numberState * (numberState > 80 ? 0.05 : 0.5));
genFunc = () =>
numberState - diff + Math.floor(Math.random() * 2 * diff);
}
results.push(
generateHistory(
{
entity_id: state.entity_id,
attributes: state.attributes,
},
Array.from({ length: statesToGenerate }, genFunc)
)
);
}
return results;
});
}; };

View File

@ -0,0 +1,5 @@
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
export const mockSystemLog = (hass: MockHomeAssistant) => {
hass.mockAPI("error/all", () => []);
};

View File

@ -0,0 +1,9 @@
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
export const mockTemplate = (hass: MockHomeAssistant) => {
hass.mockAPI("template", () =>
Promise.reject({
body: { message: "Template dev tool does not work in the demo." },
})
);
};

View File

@ -11,7 +11,7 @@ export const demoConfig: HassConfig = {
temperature: "°C", temperature: "°C",
volume: "L", volume: "L",
}, },
components: ["conversation"], components: ["conversation", "notify.html5", "history"],
time_zone: "America/Los_Angeles", time_zone: "America/Los_Angeles",
config_dir: "/config", config_dir: "/config",
version: "DEMO", version: "DEMO",

View File

@ -66,7 +66,7 @@ export class Entity {
} }
} }
export class LightEntity extends Entity { class LightEntity extends Entity {
public async handleService(domain, service, data) { public async handleService(domain, service, data) {
if (!["homeassistant", this.domain].includes(domain)) { if (!["homeassistant", this.domain].includes(domain)) {
return; return;
@ -89,7 +89,7 @@ export class LightEntity extends Entity {
} }
} }
export class SwitchEntity extends Entity { class ToggleEntity extends Entity {
public async handleService(domain, service, data) { public async handleService(domain, service, data) {
if (!["homeassistant", this.domain].includes(domain)) { if (!["homeassistant", this.domain].includes(domain)) {
return; return;
@ -109,7 +109,7 @@ export class SwitchEntity extends Entity {
} }
} }
export class LockEntity extends Entity { class LockEntity extends Entity {
public async handleService( public async handleService(
domain, domain,
service, service,
@ -128,7 +128,31 @@ export class LockEntity extends Entity {
} }
} }
export class CoverEntity extends Entity { class AlarmControlPanelEntity extends Entity {
public async handleService(
domain,
service,
// @ts-ignore
data
) {
if (domain !== this.domain) {
return;
}
const serviceStateMap = {
alarm_arm_night: "armed_night",
alarm_arm_home: "armed_home",
alarm_arm_away: "armed_away",
alarm_disarm: "disarmed",
};
if (serviceStateMap[service]) {
this.update(serviceStateMap[service], this.baseAttributes);
}
}
}
class CoverEntity extends Entity {
public async handleService( public async handleService(
domain, domain,
service, service,
@ -147,7 +171,7 @@ export class CoverEntity extends Entity {
} }
} }
export class ClimateEntity extends Entity { class ClimateEntity extends Entity {
public async handleService(domain, service, data) { public async handleService(domain, service, data) {
if (domain !== this.domain) { if (domain !== this.domain) {
return; return;
@ -162,7 +186,7 @@ export class ClimateEntity extends Entity {
} }
} }
export class GroupEntity extends Entity { class GroupEntity extends Entity {
public async handleService(domain, service, data) { public async handleService(domain, service, data) {
if (!["homeassistant", this.domain].includes(domain)) { if (!["homeassistant", this.domain].includes(domain)) {
return; return;
@ -180,12 +204,14 @@ export class GroupEntity extends Entity {
} }
const TYPES = { const TYPES = {
alarm_control_panel: AlarmControlPanelEntity,
climate: ClimateEntity, climate: ClimateEntity,
cover: CoverEntity, cover: CoverEntity,
group: GroupEntity, group: GroupEntity,
input_boolean: ToggleEntity,
light: LightEntity, light: LightEntity,
lock: LockEntity, lock: LockEntity,
switch: SwitchEntity, switch: ToggleEntity,
}; };
export const getEntity = ( export const getEntity = (

View File

@ -13,7 +13,8 @@ import { translationMetadata } from "../resources/translations-metadata";
const ensureArray = <T>(val: T | T[]): T[] => const ensureArray = <T>(val: T | T[]): T[] =>
Array.isArray(val) ? val : [val]; Array.isArray(val) ? val : [val];
type RestCallback = ( type MockRestCallback = (
hass: MockHomeAssistant,
method: string, method: string,
path: string, path: string,
parameters: { [key: string]: any } | undefined parameters: { [key: string]: any } | undefined
@ -25,7 +26,7 @@ export interface MockHomeAssistant extends HomeAssistant {
updateStates(newStates: HassEntities); updateStates(newStates: HassEntities);
addEntities(entites: Entity | Entity[], replace?: boolean); addEntities(entites: Entity | Entity[], replace?: boolean);
mockWS(type: string, callback: (msg: any) => any); mockWS(type: string, callback: (msg: any) => any);
mockAPI(path: string | RegExp, callback: RestCallback); mockAPI(path: string | RegExp, callback: MockRestCallback);
mockEvent(event); mockEvent(event);
mockTheme(theme: { [key: string]: string } | null); mockTheme(theme: { [key: string]: string } | null);
} }
@ -39,7 +40,7 @@ export const provideHass = (
const hass = (): MockHomeAssistant => elements[0].hass; const hass = (): MockHomeAssistant => elements[0].hass;
const wsCommands = {}; const wsCommands = {};
const restResponses: Array<[string | RegExp, RestCallback]> = []; const restResponses: Array<[string | RegExp, MockRestCallback]> = [];
const eventListeners: { const eventListeners: {
[event: string]: Array<(event) => void>; [event: string]: Array<(event) => void>;
} = {}; } = {};
@ -160,7 +161,7 @@ export const provideHass = (
); );
return response return response
? response[1](method, path, parameters) ? response[1](hass(), method, path, parameters)
: Promise.reject(`API Mock for ${path} is not implemented`); : Promise.reject(`API Mock for ${path} is not implemented`);
}, },
fetchWithAuth: () => Promise.reject("Not implemented"), fetchWithAuth: () => Promise.reject("Not implemented"),

View File

@ -210,7 +210,9 @@ For loop example:
this.rendering = false; this.rendering = false;
}.bind(this), }.bind(this),
function(error) { function(error) {
this.processed = error.body.message; this.processed =
(error && error.body && error.body.message) ||
"Unknown error rendering template";
this.error = true; this.error = true;
this.rendering = false; this.rendering = false;
}.bind(this) }.bind(this)