forked from DigiLive/mushroom-strategy
Add localization
Fixed dashboard strings are replaced with a string in the language as defined by the user. Currently, languages `en` and `nl` are supported. If the user-defined language isn't supported, the language will fall back to english. Untranslated strings will fall back to the translation keyword. Resolves #166
This commit is contained in:
@ -1,10 +1,11 @@
|
||||
import {configurationDefaults} from "./configurationDefaults";
|
||||
import {getConfigurationDefaults} from "./configurationDefaults";
|
||||
import {HassEntities, HassEntity} from "home-assistant-js-websocket";
|
||||
import deepmerge from "deepmerge";
|
||||
import {EntityRegistryEntry} from "./types/homeassistant/data/entity_registry";
|
||||
import {DeviceRegistryEntry} from "./types/homeassistant/data/device_registry";
|
||||
import {AreaRegistryEntry} from "./types/homeassistant/data/area_registry";
|
||||
import {generic} from "./types/strategy/generic";
|
||||
import setupCustomLocalize from "./localize";
|
||||
import StrategyArea = generic.StrategyArea;
|
||||
|
||||
/**
|
||||
@ -68,6 +69,7 @@ class Helper {
|
||||
* @private
|
||||
*/
|
||||
static #debug: boolean;
|
||||
static customLocalize: Function;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
@ -140,8 +142,12 @@ class Helper {
|
||||
*/
|
||||
static async initialize(info: generic.DashBoardInfo): Promise<void> {
|
||||
// Initialize properties.
|
||||
this.#hassStates = info.hass.states;
|
||||
this.customLocalize = setupCustomLocalize(info.hass);
|
||||
|
||||
const configurationDefaults = getConfigurationDefaults(this.customLocalize)
|
||||
this.#strategyOptions = deepmerge(configurationDefaults, info.config?.strategy?.options ?? {});
|
||||
|
||||
this.#hassStates = info.hass.states;
|
||||
this.#debug = this.#strategyOptions.debug;
|
||||
|
||||
try {
|
||||
|
@ -4,151 +4,153 @@ import StrategyDefaults = generic.StrategyDefaults;
|
||||
/**
|
||||
* Default configuration for the mushroom strategy.
|
||||
*/
|
||||
export const configurationDefaults: StrategyDefaults = {
|
||||
areas: {
|
||||
undisclosed: {
|
||||
area_id: "undisclosed",
|
||||
floor_id: null,
|
||||
name: "Undisclosed",
|
||||
picture: null,
|
||||
icon: "mdi:floor-plan",
|
||||
labels: [],
|
||||
aliases: [],
|
||||
hidden: false,
|
||||
export const getConfigurationDefaults = (localize: Function): StrategyDefaults => {
|
||||
return {
|
||||
areas: {
|
||||
undisclosed: {
|
||||
area_id: "undisclosed",
|
||||
floor_id: null,
|
||||
name: "Undisclosed",
|
||||
picture: null,
|
||||
icon: "mdi:floor-plan",
|
||||
labels: [],
|
||||
aliases: [],
|
||||
hidden: false,
|
||||
}
|
||||
},
|
||||
debug: false,
|
||||
domains: {
|
||||
_: {
|
||||
hide_config_entities: false,
|
||||
},
|
||||
default: {
|
||||
title: localize("generic.miscellaneous"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
light: {
|
||||
title: localize("light.lights"),
|
||||
showControls: true,
|
||||
iconOn: "mdi:lightbulb",
|
||||
iconOff: "mdi:lightbulb-off",
|
||||
onService: "light.turn_on",
|
||||
offService: "light.turn_off",
|
||||
hidden: false,
|
||||
},
|
||||
fan: {
|
||||
title: localize("fan.fans"),
|
||||
showControls: true,
|
||||
iconOn: "mdi:fan",
|
||||
iconOff: "mdi:fan-off",
|
||||
onService: "fan.turn_on",
|
||||
offService: "fan.turn_off",
|
||||
hidden: false,
|
||||
},
|
||||
cover: {
|
||||
title: localize("cover.covers"),
|
||||
showControls: true,
|
||||
iconOn: "mdi:arrow-up",
|
||||
iconOff: "mdi:arrow-down",
|
||||
onService: "cover.open_cover",
|
||||
offService: "cover.close_cover",
|
||||
hidden: false,
|
||||
},
|
||||
switch: {
|
||||
title: localize("switch.switches"),
|
||||
showControls: true,
|
||||
iconOn: "mdi:power-plug",
|
||||
iconOff: "mdi:power-plug-off",
|
||||
onService: "switch.turn_on",
|
||||
offService: "switch.turn_off",
|
||||
hidden: false,
|
||||
},
|
||||
camera: {
|
||||
title: localize("camera.cameras"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
lock: {
|
||||
title: localize("lock.locks"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
climate: {
|
||||
title: localize("climate.climates"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
media_player: {
|
||||
title: localize("media_player.media_players"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
sensor: {
|
||||
title: localize("sensor.sensors"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
binary_sensor: {
|
||||
title: `${localize("sensor.binary")} ` + localize("sensor.sensors"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
number: {
|
||||
title: localize("generic.numbers"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
vacuum: {
|
||||
title: localize("vacuum.vacuums"),
|
||||
showControls: true,
|
||||
hidden: false,
|
||||
},
|
||||
select: {
|
||||
title: localize("select.selects"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
input_select: {
|
||||
title: localize("input_select.input_selects"),
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
},
|
||||
home_view: {
|
||||
hidden: [],
|
||||
},
|
||||
views: {
|
||||
home: {
|
||||
order: 1,
|
||||
hidden: false,
|
||||
},
|
||||
light: {
|
||||
order: 2,
|
||||
hidden: false,
|
||||
},
|
||||
fan: {
|
||||
order: 3,
|
||||
hidden: false,
|
||||
},
|
||||
cover: {
|
||||
order: 4,
|
||||
hidden: false,
|
||||
},
|
||||
switch: {
|
||||
order: 5,
|
||||
hidden: false,
|
||||
},
|
||||
climate: {
|
||||
order: 6,
|
||||
hidden: false,
|
||||
},
|
||||
camera: {
|
||||
order: 7,
|
||||
hidden: false,
|
||||
},
|
||||
vacuum: {
|
||||
order: 8,
|
||||
hidden: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
debug: false,
|
||||
domains: {
|
||||
_: {
|
||||
hide_config_entities: false,
|
||||
},
|
||||
default: {
|
||||
title: "Miscellaneous",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
light: {
|
||||
title: "Lights",
|
||||
showControls: true,
|
||||
iconOn: "mdi:lightbulb",
|
||||
iconOff: "mdi:lightbulb-off",
|
||||
onService: "light.turn_on",
|
||||
offService: "light.turn_off",
|
||||
hidden: false,
|
||||
},
|
||||
fan: {
|
||||
title: "Fans",
|
||||
showControls: true,
|
||||
iconOn: "mdi:fan",
|
||||
iconOff: "mdi:fan-off",
|
||||
onService: "fan.turn_on",
|
||||
offService: "fan.turn_off",
|
||||
hidden: false,
|
||||
},
|
||||
cover: {
|
||||
title: "Covers",
|
||||
showControls: true,
|
||||
iconOn: "mdi:arrow-up",
|
||||
iconOff: "mdi:arrow-down",
|
||||
onService: "cover.open_cover",
|
||||
offService: "cover.close_cover",
|
||||
hidden: false,
|
||||
},
|
||||
switch: {
|
||||
title: "Switches",
|
||||
showControls: true,
|
||||
iconOn: "mdi:power-plug",
|
||||
iconOff: "mdi:power-plug-off",
|
||||
onService: "switch.turn_on",
|
||||
offService: "switch.turn_off",
|
||||
hidden: false,
|
||||
},
|
||||
camera: {
|
||||
title: "Cameras",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
lock: {
|
||||
title: "Locks",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
climate: {
|
||||
title: "Climates",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
media_player: {
|
||||
title: "Media Players",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
sensor: {
|
||||
title: "Sensors",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
binary_sensor: {
|
||||
title: "Binary Sensors",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
number: {
|
||||
title: "Numbers",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
vacuum: {
|
||||
title: "Vacuums",
|
||||
showControls: true,
|
||||
hidden: false,
|
||||
},
|
||||
select: {
|
||||
title: "Selects",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
input_select: {
|
||||
title: "Input Selects",
|
||||
showControls: false,
|
||||
hidden: false,
|
||||
},
|
||||
},
|
||||
home_view: {
|
||||
hidden: [],
|
||||
},
|
||||
views: {
|
||||
home: {
|
||||
order: 1,
|
||||
hidden: false,
|
||||
},
|
||||
light: {
|
||||
order: 2,
|
||||
hidden: false,
|
||||
},
|
||||
fan: {
|
||||
order: 3,
|
||||
hidden: false,
|
||||
},
|
||||
cover: {
|
||||
order: 4,
|
||||
hidden: false,
|
||||
},
|
||||
switch: {
|
||||
order: 5,
|
||||
hidden: false,
|
||||
},
|
||||
climate: {
|
||||
order: 6,
|
||||
hidden: false,
|
||||
},
|
||||
camera: {
|
||||
order: 7,
|
||||
hidden: false,
|
||||
},
|
||||
vacuum: {
|
||||
order: 8,
|
||||
hidden: false,
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
56
src/localize.ts
Normal file
56
src/localize.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import {HomeAssistant} from "./types/homeassistant/types";
|
||||
import * as en from "./translations/en.json";
|
||||
import * as nl from "./translations/nl.json";
|
||||
|
||||
/* Registry of currently supported languages */
|
||||
const languages: Record<string, unknown> = {
|
||||
en,
|
||||
nl,
|
||||
};
|
||||
|
||||
/* The fallback language if the user-defined language isn't defined */
|
||||
const DEFAULT_LANG = "en";
|
||||
|
||||
/**
|
||||
* Get a string by keyword and language.
|
||||
*
|
||||
* @param {string} key The keyword to look for in object notation (E.g. generic.home).
|
||||
* @param {string} lang The language to get the string from (E.g. en).
|
||||
*
|
||||
* @return {string | undefined} The requested string or undefined if the keyword doesn't exist/on error.
|
||||
*/
|
||||
function getTranslatedString(key: string, lang: string): string | undefined {
|
||||
try {
|
||||
return key
|
||||
.split(".")
|
||||
.reduce(
|
||||
(o, i) => (o as Record<string, unknown>)[i],
|
||||
languages[lang]
|
||||
) as string;
|
||||
} catch (_) {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the localization.
|
||||
*
|
||||
* It reads the user-defined language with a fall-back to english and returns a function to get strings from
|
||||
* language-files by keyword.
|
||||
*
|
||||
* If the keyword is undefined, or on error, the keyword itself is returned.
|
||||
*
|
||||
* @param {HomeAssistant} hass The Home Assistant object.
|
||||
* @return {(key: string) => string} The function to call for translating strings.
|
||||
*/
|
||||
export default function setupCustomLocalize(hass?: HomeAssistant): (key: string) => string {
|
||||
return function (key: string) {
|
||||
const lang = hass?.locale.language ?? DEFAULT_LANG;
|
||||
|
||||
let translated = getTranslatedString(key, lang);
|
||||
if (!translated) translated = getTranslatedString(key, DEFAULT_LANG);
|
||||
|
||||
return translated ?? key;
|
||||
};
|
||||
}
|
61
src/translations/en.json
Normal file
61
src/translations/en.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"camera": {
|
||||
"all_cameras": "All Cameras",
|
||||
"cameras": "Cameras"
|
||||
},
|
||||
"climate": {
|
||||
"all_climates": "All Climates",
|
||||
"climates": "Climates"
|
||||
},
|
||||
"covers": {
|
||||
"all_covers": "All Covers",
|
||||
"covers": "Covers"
|
||||
},
|
||||
"fan": {
|
||||
"all_fans": "All Fans",
|
||||
"fans": "Fans"
|
||||
},
|
||||
"generic": {
|
||||
"all": "All",
|
||||
"areas": "Areas",
|
||||
"busy": "Busy",
|
||||
"good_afternoon": "Good afternoon",
|
||||
"good_evening": "Good evening",
|
||||
"good_morning": "Good morning",
|
||||
"hello": "Hello",
|
||||
"home": "Home",
|
||||
"miscellaneous": "Miscellaneous",
|
||||
"numbers": "Numbers",
|
||||
"off": "Off",
|
||||
"on": "On",
|
||||
"open": "Open"
|
||||
},
|
||||
"input_select": {
|
||||
"input_selects": "Input Selects"
|
||||
},
|
||||
"light": {
|
||||
"all_lights": "All Lights",
|
||||
"lights": "Lights"
|
||||
},
|
||||
"lock": {
|
||||
"locks": "Locks"
|
||||
},
|
||||
"media_player": {
|
||||
"media_players": "Mediaplayers"
|
||||
},
|
||||
"select": {
|
||||
"selects": "Selects"
|
||||
},
|
||||
"sensor": {
|
||||
"binary": "Binary",
|
||||
"sensors": "Sensors"
|
||||
},
|
||||
"switch": {
|
||||
"all_switches": "All Switches",
|
||||
"switches": "Switches"
|
||||
},
|
||||
"vacuum": {
|
||||
"all_vacuums": "All Vacuums",
|
||||
"vacuums": "Vacuums"
|
||||
}
|
||||
}
|
61
src/translations/nl.json
Normal file
61
src/translations/nl.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"camera": {
|
||||
"all_cameras": "Alle Cameras",
|
||||
"cameras": "Cameras"
|
||||
},
|
||||
"climate": {
|
||||
"all_climates": "Alle Klimaatregelingen",
|
||||
"climates": "Klimaatregelingen"
|
||||
},
|
||||
"covers": {
|
||||
"all_covers": "Alle Bedekkingen",
|
||||
"covers": "Bedekkingen"
|
||||
},
|
||||
"fan": {
|
||||
"all_fans": "Alle Ventilatoren",
|
||||
"fans": "Ventilatoren"
|
||||
},
|
||||
"generic": {
|
||||
"all": "Alle",
|
||||
"areas": "Ruimtes",
|
||||
"busy": "Bezig",
|
||||
"good_afternoon": "Goede middag",
|
||||
"good_evening": "Goede avond",
|
||||
"good_morning": "Goede morgen",
|
||||
"hello": "Hallo",
|
||||
"home": "Start",
|
||||
"miscellaneous": "Overige",
|
||||
"numbers": "Nummers",
|
||||
"off": "Uit",
|
||||
"on": "Aan",
|
||||
"open": "Open"
|
||||
},
|
||||
"input_select": {
|
||||
"input_selects": "Lijsten"
|
||||
},
|
||||
"light": {
|
||||
"all_lights": "Alle Lampen",
|
||||
"lights": "Lampen"
|
||||
},
|
||||
"lock": {
|
||||
"locks": "Sloten"
|
||||
},
|
||||
"media_player": {
|
||||
"media_players": "Mediaspelers"
|
||||
},
|
||||
"select": {
|
||||
"selects": "Statuslijsten"
|
||||
},
|
||||
"sensor": {
|
||||
"binary": "Binaire",
|
||||
"sensors": "Sensoren"
|
||||
},
|
||||
"switch": {
|
||||
"all_switches": "Alle Schakelaars",
|
||||
"switches": "Schakelaars"
|
||||
},
|
||||
"vacuum": {
|
||||
"all_vacuums": "Alle Afzuiging",
|
||||
"vacuums": "Afzuiging"
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ class CameraView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Cameras",
|
||||
title: Helper.customLocalize("camera.cameras"),
|
||||
path: "cameras",
|
||||
icon: "mdi:cctv",
|
||||
subview: false,
|
||||
@ -46,8 +46,10 @@ class CameraView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Cameras",
|
||||
subtitle: Helper.getCountTemplate(CameraView.#domain, "ne", "off") + " cameras on",
|
||||
title: Helper.customLocalize("camera.all_cameras"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(CameraView.#domain, "ne", "off")} ${Helper.customLocalize("camera.cameras")} `
|
||||
+ Helper.customLocalize("generic.busy"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class ClimateView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Climates",
|
||||
title: Helper.customLocalize("climate.climates"),
|
||||
path: "climates",
|
||||
icon: "mdi:thermostat",
|
||||
subview: false,
|
||||
@ -46,8 +46,10 @@ class ClimateView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Climates",
|
||||
subtitle: Helper.getCountTemplate(ClimateView.#domain, "ne", "off") + " climates on",
|
||||
title: Helper.customLocalize("climate.all_climates"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(ClimateView.#domain, "ne", "off")} ${Helper.customLocalize("climate.climates")} `
|
||||
+ Helper.customLocalize("generic.busy"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class CoverView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Covers",
|
||||
title: Helper.customLocalize("cover.covers"),
|
||||
path: "covers",
|
||||
icon: "mdi:window-open",
|
||||
subview: false,
|
||||
@ -49,8 +49,10 @@ class CoverView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Covers",
|
||||
subtitle: Helper.getCountTemplate(CoverView.#domain, "eq", "open") + " covers open",
|
||||
title: Helper.customLocalize("cover.all_covers"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(CoverView.#domain, "eq", "open")} ${Helper.customLocalize("cover.covers")} `
|
||||
+ Helper.customLocalize("generic.open"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class FanView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Fans",
|
||||
title: Helper.customLocalize("fan.fans"),
|
||||
path: "fans",
|
||||
icon: "mdi:fan",
|
||||
subview: false,
|
||||
@ -49,8 +49,10 @@ class FanView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Fans",
|
||||
subtitle: Helper.getCountTemplate(FanView.#domain, "eq", "on") + " fans on",
|
||||
title: Helper.customLocalize("fan.all_fans"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(FanView.#domain, "eq", "on")} ${Helper.customLocalize("fan.fans")} `
|
||||
+ Helper.customLocalize("generic.on"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@ class HomeView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Home",
|
||||
title: Helper.customLocalize("generic.home"),
|
||||
icon: "mdi:home-assistant",
|
||||
path: "home",
|
||||
subview: false,
|
||||
@ -77,24 +77,28 @@ class HomeView extends AbstractView {
|
||||
}
|
||||
|
||||
if (!Helper.strategyOptions.home_view.hidden.includes("greeting")) {
|
||||
homeViewCards.push({
|
||||
type: "custom:mushroom-template-card",
|
||||
primary: "{% set time = now().hour %} {% if (time >= 18) %} Good Evening, {{user}}! {% elif (time >= 12) %} Good Afternoon, {{user}}! {% elif (time >= 5) %} Good Morning, {{user}}! {% else %} Hello, {{user}}! {% endif %}",
|
||||
icon: "mdi:hand-wave",
|
||||
icon_color: "orange",
|
||||
tap_action: {
|
||||
action: "none",
|
||||
} as ActionConfig,
|
||||
double_tap_action: {
|
||||
action: "none",
|
||||
} as ActionConfig,
|
||||
hold_action: {
|
||||
action: "none",
|
||||
} as ActionConfig,
|
||||
} as TemplateCardConfig);
|
||||
const greeting =
|
||||
homeViewCards.push({
|
||||
type: "custom:mushroom-template-card",
|
||||
primary:
|
||||
`{% set time = now().hour %} {% if (time >= 18) %} ${Helper.customLocalize("generic.good_evening")},{{user}}!
|
||||
{% elif (time >= 12) %} ${Helper.customLocalize("generic.good_afternoon")}, {{user}}!
|
||||
{% elif (time >= 5) %} ${Helper.customLocalize("generic.good_morning")}, {{user}}!
|
||||
{% else %} ${Helper.customLocalize("generic.hello")}, {{user}}! {% endif %}`,
|
||||
icon: "mdi:hand-wave",
|
||||
icon_color: "orange",
|
||||
tap_action: {
|
||||
action: "none",
|
||||
} as ActionConfig,
|
||||
double_tap_action: {
|
||||
action: "none",
|
||||
} as ActionConfig,
|
||||
hold_action: {
|
||||
action: "none",
|
||||
} as ActionConfig,
|
||||
} as TemplateCardConfig);
|
||||
}
|
||||
|
||||
|
||||
// Add quick access cards.
|
||||
if (options.quick_access_cards) {
|
||||
homeViewCards.push(...options.quick_access_cards);
|
||||
@ -225,7 +229,7 @@ class HomeView extends AbstractView {
|
||||
if (!Helper.strategyOptions.home_view.hidden.includes("areasTitle")) {
|
||||
groupedCards.push({
|
||||
type: "custom:mushroom-title-card",
|
||||
title: "Areas",
|
||||
title: Helper.customLocalize("generic.areas"),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class LightView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Lights",
|
||||
title: Helper.customLocalize("light.lights"),
|
||||
path: "lights",
|
||||
icon: "mdi:lightbulb-group",
|
||||
subview: false,
|
||||
@ -49,8 +49,10 @@ class LightView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Lights",
|
||||
subtitle: Helper.getCountTemplate(LightView.#domain, "eq", "on") + " lights on",
|
||||
title: Helper.customLocalize("light.all_lights"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(LightView.#domain, "eq", "on")} ${Helper.customLocalize("light.lights")} `
|
||||
+ Helper.customLocalize("generic.on"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class SwitchView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Switches",
|
||||
title: Helper.customLocalize("switch.switches"),
|
||||
path: "switches",
|
||||
icon: "mdi:dip-switch",
|
||||
subview: false,
|
||||
@ -49,8 +49,10 @@ class SwitchView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Switches",
|
||||
subtitle: Helper.getCountTemplate(SwitchView.#domain, "eq", "on") + " switches on",
|
||||
title: Helper.customLocalize("switch.all_switches"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(SwitchView.#domain, "eq", "on")} ${Helper.customLocalize("switch.switches")} `
|
||||
+ Helper.customLocalize("generic.on"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class VacuumView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: views.ViewConfig = {
|
||||
title: "Vacuums",
|
||||
title: Helper.customLocalize("vacuum.vacuums"),
|
||||
path: "vacuums",
|
||||
icon: "mdi:robot-vacuum",
|
||||
subview: false,
|
||||
@ -49,8 +49,10 @@ class VacuumView extends AbstractView {
|
||||
* @private
|
||||
*/
|
||||
#viewControllerCardConfig: cards.ControllerCardOptions = {
|
||||
title: "All Vacuums",
|
||||
subtitle: Helper.getCountTemplate(VacuumView.#domain, "ne", "off") + " vacuums on",
|
||||
title: Helper.customLocalize("vacuum.all_vacuums"),
|
||||
subtitle:
|
||||
`${Helper.getCountTemplate(VacuumView.#domain, "ne", "off")} ${Helper.customLocalize("vacuum.vacuums")} `
|
||||
+ Helper.customLocalize("generic.busy"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,9 @@
|
||||
"strictNullChecks": true,
|
||||
|
||||
/* Completeness */
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
|
||||
"resolveJsonModule": true,
|
||||
},
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
|
Reference in New Issue
Block a user