diff --git a/README.md b/README.md index 1658ac9..667a4b6 100644 --- a/README.md +++ b/README.md @@ -120,16 +120,17 @@ weather entity for the weather chip. The options available are: -| Name | Type | Default | Description | -|:---------------------|:--------------------------|:--------------------------------------------------------|:---------------------------------------------------------------| -| `areas` | object (optional) | unset | One or more areas in a list, see [areas object](#area-object). | -| `card_options` | object (optional) | unset | Card options for cards, see [Card Options](#card-options). | -| `views` | object (optional) | All default views | See available [Pre-built views](#pre-built-views). | -| `chips` | object | All count chips enabled with auto selected weather card | See [chips](#chips). | -| `quick_access_cards` | array of cards (optional) | unset | List of cards to show between welcome card and rooms cards. | -| `extra_cards` | array of cards (optional | unset | List of cards to show below room cards. | -| `extra_views` | array of views (optional) | unset | List of views to add to the dashboard. | -| `domains` | object (optional) | All supported domains | See [Supported domains](#supported-domains). | +| Name | Type | Default | Description | +|:---------------------|:--------------------------|:--------------------------------------------------------|:-----------------------------------------------------------------------| +| `areas` | object (optional) | unset | One or more areas in a list, see [areas object](#area-object). | +| `card_options` | object (optional) | unset | Card options for cards, see [Card Options](#card-options). | +| `views` | object (optional) | All default views | See available [Pre-built views](#pre-built-views). | +| `chips` | object | All count chips enabled with auto selected weather card | See [chips](#chips). | +| `quick_access_cards` | array of cards (optional) | unset | List of cards to show between welcome card and rooms cards. | +| `extra_cards` | array of cards (optional | unset | List of cards to show below room cards. | +| `extra_views` | array of views (optional) | unset | List of views to add to the dashboard. | +| `domains` | object (optional) | All supported domains | See [Supported domains](#supported-domains). | +| `homeView` | object (optional) | unset | Options for the home view, see [Home View Options](#home-view-options) | #### Example @@ -343,6 +344,36 @@ strategy: views: [] ``` +### Home View Options + +Home View options will let you configure the Home View. + +| Option | type | Description | +|:---------|:------|:----------------------------------------------| +| `hidden` | array | Array of elements to hide from the home view. | + +#### hidden + +The following elements are supported: +* Chips +* Persons +* Greeting +* AreaTitle +* Areas + +#### Example + +```YAML +strategy: + type: custom:mushroom-strategy + options: + homeView: + hidden: + - Greeting + - AreaTitle +views: [] +``` + ### Chips ![Chips](./docs/chips.png) @@ -402,6 +433,10 @@ strategy: switches: hidden: true icon: mdi:toggle-switch + homeView: + hidden: + - Greeting + - AreaTitle chips: weather_entity: weather.forecast_home climate_count: false @@ -518,6 +553,7 @@ views: [] ## Contributors * [DigiLive](https://github.com/DigiLive) +* [Johan Frick](https://github.com/johanfrick) diff --git a/src/typedefs.js b/src/typedefs.js index 04408a7..e5c35e5 100644 --- a/src/typedefs.js +++ b/src/typedefs.js @@ -119,6 +119,7 @@ * @property {Object[]} [quick_access_cards] List of cards to show between welcome card and rooms cards. * @property {Object[]} [extra_cards] List of cards to show below room cards. * @property {Object[]} [extra_views] List of views to add to the dashboard. + * @property {Object.} [homeView] Options for the home view. * @memberOf typedefs.generic */ @@ -134,6 +135,12 @@ * @memberOf typedefs.generic */ +/** + * @typedef {Object} homeViewOptions Options for the home view. + * @property {string[]} [hidden] Elements to hide from the home view. + * @memberOf typedefs.generic + */ + /** * @typedef {Object} cardOptions Custom card-configuration for an entity. * @property {string} type Type of card for the entity @@ -182,7 +189,7 @@ * @property {string} object_id Object ID of entity. * Example: `kitchen`. * @property {string} name Name of the entity. - * Based on `friendly_name` attribute with fall back to object ID. + * Based on `friendly_name` attribute with fall-back to object ID. * Example: `Kitchen Ceiling`. * @property {string} last_updated Time the state was written to the state machine in UTC time. * Note that writing the exact same state including attributes will not result in this @@ -228,7 +235,7 @@ * @typedef {Object} stateContext State context. * @property {string} context_id Unique identifier for the context. * @property {string} user_id Unique identifier of the user that started the change. - * Will be None if action was not started by a user (i.e. started by an automation) + * Will be None if action was not started by a user (i.e., started by an automation) * @property {string} parent_id Unique identifier of the parent context that started the change, if available. * For example, if an automation is triggered, the context of the trigger will be set as * parent. diff --git a/src/views/HomeView.js b/src/views/HomeView.js index c24c178..5edd199 100644 --- a/src/views/HomeView.js +++ b/src/views/HomeView.js @@ -30,8 +30,8 @@ class HomeView extends AbstractView { constructor(options = {}) { super(); this.mergeOptions( - this.#defaultOptions, - options, + this.#defaultOptions, + options, ); } @@ -47,20 +47,37 @@ class HomeView extends AbstractView { this.#createPersonCards(), this.#createAreaCards(), ]).then(([chips, personCards, areaCards]) => { - const options = Helper.strategyOptions; - const homeViewCards = [ - { + const options = Helper.strategyOptions; + const homeViewCards = []; + + // Add chips to the view. + if (chips.length) { + homeViewCards.push({ type: "custom:mushroom-chips-card", alignment: "center", chips: chips, - }, - { + }); + } + + // Add persons to the view + if (personCards.length) { + homeViewCards.push({ type: "horizontal-stack", cards: personCards, - }, - { + }); + } + + // Add greeting to the view if not hidden. + if (!Helper.strategyOptions.homeView?.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 %}", + 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: { @@ -72,8 +89,8 @@ class HomeView extends AbstractView { hold_action: { action: "none", }, - }, - ]; + }); + } // Add quick access cards. if (options.quick_access_cards) { @@ -101,24 +118,29 @@ class HomeView extends AbstractView { * @return {Object[]} A chip object array. */ async #createChips() { - const chips = []; + if (Helper.strategyOptions.homeView?.hidden?.includes("chips")) { + // Chips section is hidden; Return 0 chips. + return []; + } + + const chips = []; const chipOptions = Helper.strategyOptions.chips; // TODO: Get domains from config. const exposed_chips = ["light", "fan", "cover", "switch", "climate"]; // Create a list of area-ids, used for switching all devices via chips - const areaIds = Helper.areas.map(area => area.area_id); + const areaIds = Helper.areas.map(area => area.area_id); let chipModule; // Weather chip. const weatherEntityId = chipOptions?.weather_entity ?? Helper.entities.find( - entity => entity.entity_id.startsWith("weather.") && entity.disabled_by == null && entity.hidden_by == null, + entity => entity.entity_id.startsWith("weather.") && entity.disabled_by == null && entity.hidden_by == null, )?.entity_id; if (weatherEntityId) { try { - chipModule = await import("../chips/WeatherChip"); + chipModule = await import("../chips/WeatherChip"); const weatherChip = new chipModule.WeatherChip(weatherEntityId); chips.push(weatherChip.getChip()); } catch (e) { @@ -154,13 +176,18 @@ class HomeView extends AbstractView { * @return {Object[]} A card object array. */ #createPersonCards() { + if (Helper.strategyOptions.homeView?.hidden?.includes("persons")) { + // Person section is hidden; Return 0 cards. + return []; + } + const cards = []; import("../cards/PersonCard").then(personModule => { for (const person of Helper.entities.filter(entity => { return entity.entity_id.startsWith("person.") - && entity.hidden_by == null - && entity.disabled_by == null; + && entity.hidden_by == null + && entity.disabled_by == null; })) { cards.push(new personModule.PersonCard(person).getCard()); } @@ -177,6 +204,11 @@ class HomeView extends AbstractView { * @return {Object[]} A card object array. */ async #createAreaCards() { + if (Helper.strategyOptions.homeView?.hidden?.includes("areas")) { + // Area section is hidden; Return 0 cards. + return []; + } + /** * Cards to be stacked vertically. * @@ -184,20 +216,25 @@ class HomeView extends AbstractView { * * @type {[{}]} */ - const groupedCards = [ - { + const groupedCards = []; + + let areaCards = []; + + // Add title to the area section. + if (!Helper.strategyOptions.homeView?.hidden?.includes("areasTitle")) { + groupedCards.push({ type: "custom:mushroom-title-card", title: "Areas", - }, - ]; - let areaCards = []; + }); + } + // Add cards to the area section. for (const [i, area] of Helper.areas.entries()) { let module; let moduleName = - Helper.strategyOptions.areas[area.area_id ?? "undisclosed"]?.type ?? - Helper.strategyOptions.areas["_"]?.type ?? - "default"; + Helper.strategyOptions.areas[area.area_id ?? "undisclosed"]?.type ?? + Helper.strategyOptions.areas["_"]?.type ?? + "default"; // Load module by type in strategy options. try {