Skip to content

Commit

Permalink
fix: fix unavailable view
Browse files Browse the repository at this point in the history
  • Loading branch information
Lebe1ge committed Dec 30, 2024
1 parent 3085681 commit 2c03084
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 28 deletions.
24 changes: 12 additions & 12 deletions src/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ class Helper {
* @return {string} The template string.
* @static
*/
static getCountTemplate(domain: string, operator: string, value: string | string[], area_slug?: string | string[]): string {
static getCountTemplate(domain: string, operator: string, value: string | string[], area_slug?: string | string[], allowUnavailable?: boolean): string {
const states: string[] = [];

if (!this.isInitialized()) {
Expand Down Expand Up @@ -519,7 +519,7 @@ class Helper {

const formatedValue = Array.isArray(value) ? JSON.stringify(value).replaceAll('"', "'") : `'${value}'`;

return `{% set entities = [${states}] %}{{ entities | selectattr('state','${operator}',${formatedValue}) | list | count }}`;
return `{% set entities = [${states}] %}{{ entities ${allowUnavailable ? "" : "| selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable')"}| selectattr('state','${operator}',${formatedValue}) | list | count }}`;
}

/**
Expand Down Expand Up @@ -552,7 +552,7 @@ class Helper {
}

const formattedValue = Array.isArray(value) ? JSON.stringify(value).replace(/"/g, "'") : `'${value}'`;
return `{% set entities = [${states}] %}{{ entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | selectattr('state','${operator}',${formattedValue}) | list | count }}`;
return `{% set entities = [${states}] %}{{ entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | selectattr('state','${operator}',${formattedValue}) | list | count }}`;
}

/**
Expand Down Expand Up @@ -591,7 +591,7 @@ class Helper {
if (newStates) states.push(...newStates);
}

return `{% set entities = [${states}] %}{{ (entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length) | round(1) }} {{ ${states[0]}.attributes.unit_of_measurement }}`;
return `{% set entities = [${states}] %}{{ (entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length) | round(1) }} {% if ${states[0]}.attributes.unit_of_measurement is defined %} {{ ${states[0]}.attributes.unit_of_measurement }}{% endif %}`;
}

/**
Expand Down Expand Up @@ -757,7 +757,7 @@ class Helper {
return entity.disabled_by === null && entity.hidden_by === null
}

static getFromDomainState({ domain, operator, value, ifReturn, elseReturn, area_slug }: { domain: string, operator?: string, value?: string | string[], ifReturn?: string, elseReturn?: string, area_slug?: string | string[] }): string {
static getFromDomainState({ domain, operator, value, ifReturn, elseReturn, area_slug, allowUnavailable }: { domain: string, operator?: string, value?: string | string[], ifReturn?: string, elseReturn?: string, area_slug?: string | string[], allowUnavailable?: boolean }): string {
const states: string[] = [];

if (!this.isInitialized()) {
Expand Down Expand Up @@ -810,7 +810,7 @@ class Helper {

const formatedValue = Array.isArray(value) ? JSON.stringify(value).replaceAll('"', "'") : `'${value ?? 'on'}'`;

return `{% set entities = [${states}] %}{{ '${ifReturn ?? 'white'}' if entities | selectattr('state','${operator ?? 'eq'}', ${formatedValue}) | list | count > 0 else '${elseReturn ?? 'grey'}' }}`;
return `{% set entities = [${states}] %}{{ '${ifReturn ?? 'white'}' if entities ${allowUnavailable ? "" : "| selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable')"}| selectattr('state','${operator ?? 'eq'}', ${formatedValue}) | list | count > 0 else '${elseReturn ?? 'grey'}' }}`;
}

static getBinarySensorColorFromState(device_class: string, operator: string, value: string, ifReturn: string, elseReturn: string, area_slug: string | string[] = "global"): string {
Expand All @@ -832,7 +832,7 @@ class Helper {

return `
{% set entities = [${states}] %}
{{ '${ifReturn}' if entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | selectattr('state','${operator}','${value}') | list | count else '${elseReturn}' }}`;
{{ '${ifReturn}' if entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | selectattr('state','${operator}','${value}') | list | count else '${elseReturn}' }}`;
}

static getSensorColorFromState(device_class: string, area_slug: string | string[] = "global"): string | undefined {
Expand All @@ -855,7 +855,7 @@ class Helper {
if (device_class === "battery") {
return `
{% set entities = [${states}] %}
{% set bl = entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% set bl = entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% if bl < 20 %}
red
{% elif bl < 30 %}
Expand All @@ -871,7 +871,7 @@ class Helper {
if (device_class === "temperature") {
return `
{% set entities = [${states}] %}
{% set bl = entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% set bl = entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% if bl < 20 %}
blue
{% elif bl < 30 %}
Expand All @@ -887,7 +887,7 @@ class Helper {
if (device_class === "humidity") {
return `
{% set entities = [${states}] %}
{% set humidity = entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% set humidity = entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% if humidity < 30 %}
blue
{% elif humidity >= 30 and humidity <= 60 %}
Expand Down Expand Up @@ -920,7 +920,7 @@ class Helper {
if (device_class === "battery") {
return `
{% set entities = [${states}] %}
{% set bl = entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% set bl = entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% if bl == 'unknown' or bl == 'unavailable' %}
{% elif bl < 10 %} mdi:battery-outline
{% elif bl < 20 %} mdi:battery-10
Expand All @@ -940,7 +940,7 @@ class Helper {
if (device_class === "temperature") {
return `
{% set entities = [${states}] %}
{% set bl = entities | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% set bl = entities | selectattr('state', 'ne', 'unknown') | selectattr('state', 'ne', 'unavailable') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', '${device_class}') | map(attribute='state') | map('float') | sum / entities | length %}
{% if bl < 20 %}
mdi:thermometer-low
{% elif bl < 30 %}
Expand Down
8 changes: 5 additions & 3 deletions src/chips/UnavailableChip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ class UnavailableChip extends AbstractChip {
constructor(options: chips.ChipOptions = {}) {
super();

this.#defaultConfig.content = Helper.getCountTemplate("all", "eq", UNAVAILABLE, options?.area_slug);
this.#defaultConfig.content = Helper.getCountTemplate("all", "eq", UNAVAILABLE, options?.area_slug, true);

this.#defaultConfig.icon = Helper.getFromDomainState({
domain: "all",
operator: "eq",
value: UNAVAILABLE,
ifReturn: this.#defaultConfig.icon,
elseReturn: "mdi:alert-circle-check-outline",
area_slug: options?.area_slug
area_slug: options?.area_slug,
allowUnavailable: true
});


Expand All @@ -53,7 +54,8 @@ class UnavailableChip extends AbstractChip {
value: UNAVAILABLE,
ifReturn: this.#defaultConfig.icon_color,
elseReturn: "green",
area_slug: options?.area_slug
area_slug: options?.area_slug,
allowUnavailable: true
});

this.#defaultConfig.tap_action = navigateTo("unavailable")
Expand Down
6 changes: 2 additions & 4 deletions src/views/HomeView.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Helper } from "../Helper";
import { AbstractView } from "./AbstractView";
import { views } from "../types/strategy/views";
import { LovelaceChipConfig } from "../types/lovelace-mushroom/utils/lovelace/chip/types";
import { ChipsCardConfig } from "../types/lovelace-mushroom/cards/chips-card";
Expand All @@ -9,12 +8,11 @@ import { ActionConfig, LovelaceSectionConfig, LovelaceViewConfig } from "../type
import { PersonCardConfig } from "../types/lovelace-mushroom/cards/person-card-config";
import { SettingsChip } from "../chips/SettingsChip";
import { SettingsPopup } from "../popups/SettingsPopup";
import { HOME_EXPOSED_CHIPS, UNAVAILABLE, UNDISCLOSED } from "../variables";
import { createChipsFromList, getFloorName, getMAEntity, navigateTo, slugify } from "../utils";
import { HOME_EXPOSED_CHIPS, UNDISCLOSED } from "../variables";
import { createChipsFromList, getFloorName, navigateTo, slugify } from "../utils";
import { WeatherChip } from "../chips/WeatherChip";
import { AggregateChip } from "../chips/AggregateChip";
import { PersonCard } from "../cards/PersonCard";
import { ConditionalChip } from "../chips/ConditionalChip";
import { UnavailableChip } from "../chips/UnavailableChip";


Expand Down
37 changes: 28 additions & 9 deletions src/views/UnavailableView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { Helper } from "../Helper";
import { LovelaceGridCardConfig } from "../types/homeassistant/lovelace/cards/types";
import { LovelaceCardConfig, LovelaceSectionConfig, LovelaceViewConfig } from "../types/homeassistant/data/lovelace";
import { HassServiceTarget } from "home-assistant-js-websocket";
import { getEntityDomain, getFloorName, slugify } from '../utils';
import { getAreaName, getEntityDomain, getFloorName, slugify } from '../utils';
import { views } from '../types/strategy/views';
import { GroupedCard } from '../cards/GroupedCard';
import { ControllerCard } from '../cards/ControllerCard';

/**
* Abstract View Class.
Expand Down Expand Up @@ -60,8 +61,9 @@ class UnavailableView {
if (floor.areas_slug.length === 0) continue;

const floorCards = [];
const floors = Array.from(floor.areas_slug.map(area_slug => Helper.areas[area_slug]).values());

for (const area of floor.areas_slug.map(area_slug => Helper.areas[area_slug]).values()) {
for (const area of floors) {
const entities = Helper.areas[area.slug].entities;
const unavailableEntities = entities?.filter(entity_id => AREA_CARDS_DOMAINS.includes(getEntityDomain(entity_id)) && Helper.getEntityState(entity_id)?.state === UNAVAILABLE).map(entity_id => Helper.entities[entity_id]);
const cardModule = await import(`../cards/MiscellaneousCard`);
Expand All @@ -80,22 +82,39 @@ class UnavailableView {
.map(entity => new cardModule.MiscellaneousCard(entity).getCard());

if (entityCards.length) {
floorCards.push(new GroupedCard(entityCards).getCard())
const titleCardOptions = {
subtitle: getAreaName(area),
subtitleIcon: area.area_id === UNDISCLOSED ? "mdi:help-circle" : area.icon ?? "mdi:floor-plan",
subtitleNavigate: area.slug,
showControls: false
} as any;

const areaControllerCard = new ControllerCard(titleCardOptions, "", area.slug).createCard();

floorCards.push(...areaControllerCard, new GroupedCard(entityCards).getCard())
}
}

if (floorCards.length) {
const titleSectionOptions: any = {
title: getFloorName(floor),
titleIcon: floor.icon ?? "mdi:floor-plan",
titleNavigate: slugify(floor.name)
titleNavigate: slugify(floor.name),
showControls: false
};
viewSections.push({ type: "grid", cards: floorCards });
}
}

if (viewSections.length) {
viewSections.unshift({ type: "grid", cards: this.viewControllerCard });
const floorControllerCard = new ControllerCard(
titleSectionOptions,
"",
floor.floor_id
).createCard();

const section = { type: "grid", cards: [] } as LovelaceGridCardConfig;

section.cards.push(...floorControllerCard);
section.cards.push(...floorCards);
viewSections.push(section);
}
}

return viewSections;
Expand Down

0 comments on commit 2c03084

Please sign in to comment.