mirror of
https://github.com/DigiLive/mushroom-strategy.git
synced 2025-08-04 12:04:28 +02:00
Optimize Cards
- Make use of the debug module. - Make use of the Registry module. - Align code across the chip modules. - Make configurations immutable. - Make use of the refactored types.
This commit is contained in:
@@ -1,59 +1,59 @@
|
||||
import {Helper} from "../Helper";
|
||||
import {EntityCardConfig} from "../types/lovelace-mushroom/cards/entity-card-config";
|
||||
import {cards} from "../types/strategy/cards";
|
||||
import {generic} from "../types/strategy/generic";
|
||||
import { Registry } from '../Registry';
|
||||
import { EntityCardConfig } from '../types/lovelace-mushroom/cards/entity-card-config';
|
||||
import { AbstractCardConfig } from '../types/strategy/strategy-cards';
|
||||
import { RegistryEntry } from '../types/strategy/strategy-generics';
|
||||
import { logMessage, lvlFatal } from '../utilities/debug';
|
||||
|
||||
/**
|
||||
* Abstract Card Class
|
||||
*
|
||||
* To create a new card, extend the new class with this one.
|
||||
* To create a card configuration, this class should be extended by a child class.
|
||||
* Child classes should override the default configuration so the card correctly reflects the entity.
|
||||
*
|
||||
* @class
|
||||
* @abstract
|
||||
* @remarks
|
||||
* Before using this class, the Registry module must be initialized by calling {@link Registry.initialize}.
|
||||
*/
|
||||
abstract class AbstractCard {
|
||||
/**
|
||||
* Entity to create the card for.
|
||||
*
|
||||
* @type {generic.RegistryEntry}
|
||||
*/
|
||||
entity: generic.RegistryEntry;
|
||||
/** The registry entry this card represents. */
|
||||
readonly entity: RegistryEntry;
|
||||
|
||||
/**
|
||||
* Configuration of the card.
|
||||
* The card configuration for this entity.
|
||||
*
|
||||
* @type {EntityCardConfig}
|
||||
* Child classes should override this property to reflect their own card type and options.
|
||||
*/
|
||||
config: EntityCardConfig = {
|
||||
type: "custom:mushroom-entity-card",
|
||||
icon: "mdi:help-circle",
|
||||
configuration: EntityCardConfig = {
|
||||
type: 'custom:mushroom-entity-card',
|
||||
icon: 'mdi:help-circle',
|
||||
};
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param {generic.RegistryEntry} entity The hass entity to create a card for.
|
||||
* @throws {Error} If the Helper module isn't initialized.
|
||||
* @param {RegistryEntry} entity The registry entry to create a card configuration for.
|
||||
*
|
||||
* @remarks
|
||||
* Before this class can be used, the Registry module must be initialized by calling {@link Registry.initialize}.
|
||||
*/
|
||||
protected constructor(entity: generic.RegistryEntry) {
|
||||
if (!Helper.isInitialized()) {
|
||||
throw new Error("The Helper module must be initialized before using this one.");
|
||||
protected constructor(entity: RegistryEntry) {
|
||||
if (!Registry.initialized) {
|
||||
logMessage(lvlFatal, 'Registry not initialized!');
|
||||
}
|
||||
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a card.
|
||||
* Get a card configuration.
|
||||
*
|
||||
* @returns {cards.AbstractCardConfig} A card object.
|
||||
* The configuration should be set by any of the child classes so the card correctly reflects an entity.
|
||||
*/
|
||||
getCard(): cards.AbstractCardConfig {
|
||||
getCard(): AbstractCardConfig {
|
||||
return {
|
||||
...this.config,
|
||||
entity: "entity_id" in this.entity ? this.entity.entity_id : undefined,
|
||||
...this.configuration,
|
||||
entity: 'entity_id' in this.entity ? this.entity.entity_id : undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {AbstractCard};
|
||||
export default AbstractCard;
|
||||
|
@@ -1,44 +1,37 @@
|
||||
import {AbstractCard} from "./AbstractCard";
|
||||
import {cards} from "../types/strategy/cards";
|
||||
import {EntityRegistryEntry} from "../types/homeassistant/data/entity_registry";
|
||||
import {PictureEntityCardConfig} from "../types/homeassistant/panels/lovelace/cards/types";
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols Class is dynamically imported.
|
||||
|
||||
import { EntityRegistryEntry } from '../types/homeassistant/data/entity_registry';
|
||||
import { PictureEntityCardConfig } from '../types/homeassistant/panels/lovelace/cards/types';
|
||||
import AbstractCard from './AbstractCard';
|
||||
|
||||
/**
|
||||
* Camera Card Class
|
||||
*
|
||||
* Used to create a card for controlling an entity of the camera domain.
|
||||
*
|
||||
* @class
|
||||
* @extends AbstractCard
|
||||
* Used to create a card configuration to control an entity of the camera domain.
|
||||
*/
|
||||
class CameraCard extends AbstractCard {
|
||||
/**
|
||||
* Default configuration of the card.
|
||||
*
|
||||
* @type {PictureEntityCardConfig}
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: PictureEntityCardConfig = {
|
||||
entity: "",
|
||||
type: "picture-entity",
|
||||
show_name: false,
|
||||
show_state: false,
|
||||
camera_view: "live",
|
||||
};
|
||||
/** Returns the default configuration object for the card. */
|
||||
static getDefaultConfig(): PictureEntityCardConfig {
|
||||
return {
|
||||
entity: '',
|
||||
type: 'picture-entity',
|
||||
show_name: false,
|
||||
show_state: false,
|
||||
camera_view: 'live',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param {EntityRegistryEntry} entity The hass entity to create a card for.
|
||||
* @param {cards.PictureEntityCardOptions} [options={}] Options for the card.
|
||||
* @throws {Error} If the Helper module isn't initialized.
|
||||
* @param {EntityRegistryEntry} entity The HASS entity to create a card configuration for.
|
||||
* @param {PictureEntityCardConfig} [customConfiguration] Custom card configuration.
|
||||
*/
|
||||
constructor(entity: EntityRegistryEntry, options: cards.PictureEntityCardOptions = {}) {
|
||||
constructor(entity: EntityRegistryEntry, customConfiguration?: PictureEntityCardConfig) {
|
||||
super(entity);
|
||||
|
||||
this.config = Object.assign(this.config, this.#defaultConfig, options);
|
||||
this.configuration = { ...this.configuration, ...CameraCard.getDefaultConfig(), ...customConfiguration };
|
||||
}
|
||||
}
|
||||
|
||||
export {CameraCard};
|
||||
export default CameraCard;
|
||||
|
@@ -1,49 +1,45 @@
|
||||
import {AbstractCard} from "./AbstractCard";
|
||||
import {cards} from "../types/strategy/cards";
|
||||
import {AreaRegistryEntry} from "../types/homeassistant/data/area_registry";
|
||||
import {AreaCardConfig} from "../types/homeassistant/panels/lovelace/cards/types";
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols Class is dynamically imported.
|
||||
|
||||
import { AreaRegistryEntry } from '../types/homeassistant/data/area_registry';
|
||||
import { AreaCardConfig } from '../types/homeassistant/panels/lovelace/cards/types';
|
||||
import AbstractCard from './AbstractCard';
|
||||
|
||||
/**
|
||||
* HA Area Card Class
|
||||
*
|
||||
* Used to create a card for an entity of the area domain using the built-in type 'area'.
|
||||
*
|
||||
* @class
|
||||
* @extends AbstractCard
|
||||
* Used to create card configuration for an entry of the HASS area registry.
|
||||
*/
|
||||
class AreaCard extends AbstractCard {
|
||||
/**
|
||||
* Default configuration of the card.
|
||||
*
|
||||
* @type {AreaCardConfig}
|
||||
* @private
|
||||
*/
|
||||
#defaultConfig: AreaCardConfig = {
|
||||
type: "area",
|
||||
area: "",
|
||||
};
|
||||
/** Returns the default configuration object for the card. */
|
||||
static getDefaultConfig(): AreaCardConfig {
|
||||
return {
|
||||
type: 'area',
|
||||
area: '',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param {AreaRegistryEntry} area The area entity to create a card for.
|
||||
* @param {cards.AreaCardOptions} [options={}] Options for the card.
|
||||
* @throws {Error} If the Helper module isn't initialized.
|
||||
* @param {AreaRegistryEntry} area The HASS entity to create a card configuration for.
|
||||
* @param {AreaCardConfig} [customConfiguration] Custom card configuration.
|
||||
*/
|
||||
|
||||
constructor(area: AreaRegistryEntry, options: cards.AreaCardOptions = {}) {
|
||||
constructor(area: AreaRegistryEntry, customConfiguration?: AreaCardConfig) {
|
||||
super(area);
|
||||
|
||||
// Initialize the default configuration.
|
||||
this.#defaultConfig.area = area.area_id;
|
||||
this.#defaultConfig.navigation_path = this.#defaultConfig.area;
|
||||
const configuration = AreaCard.getDefaultConfig();
|
||||
|
||||
// Enforce the card type.
|
||||
delete options.type;
|
||||
configuration.area = area.area_id;
|
||||
configuration.navigation_path = configuration.area;
|
||||
|
||||
this.config = Object.assign(this.config, this.#defaultConfig, options);
|
||||
this.configuration = {
|
||||
...this.configuration,
|
||||
...configuration,
|
||||
...customConfiguration,
|
||||
type: configuration.type, // Enforce the card type.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {AreaCard};
|
||||
export default AreaCard;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
import { EntityRegistryEntry } from '../types/homeassistant/data/entity_registry';
|
||||
import { LightCardConfig } from '../types/lovelace-mushroom/cards/light-card-config';
|
||||
import { isCallServiceActionConfig } from '../types/strategy/strategy-generics';
|
||||
import { isCallServiceActionConfig, isCallServiceActionTarget } from '../types/strategy/strategy-generics';
|
||||
import AbstractCard from './AbstractCard';
|
||||
|
||||
/**
|
||||
@@ -44,8 +44,11 @@ class LightCard extends AbstractCard {
|
||||
|
||||
const configuration = LightCard.getDefaultConfig();
|
||||
|
||||
if (isCallServiceActionConfig(configuration.double_tap_action)) {
|
||||
configuration.double_tap_action.target = { entity_id: entity.entity_id };
|
||||
if (
|
||||
isCallServiceActionConfig(configuration.double_tap_action) &&
|
||||
isCallServiceActionTarget(configuration.double_tap_action.target)
|
||||
) {
|
||||
configuration.double_tap_action.target.entity_id = entity.entity_id;
|
||||
}
|
||||
|
||||
this.configuration = { ...this.configuration, ...configuration, ...customConfiguration };
|
||||
|
@@ -3,27 +3,27 @@
|
||||
import { Registry } from '../Registry';
|
||||
import { EntityRegistryEntry } from '../types/homeassistant/data/entity_registry';
|
||||
import { EntityCardConfig } from '../types/lovelace-mushroom/cards/entity-card-config';
|
||||
import { isCallServiceActionConfig, isCallServiceActionTarget } from '../types/strategy/strategy-generics';
|
||||
import AbstractCard from './AbstractCard';
|
||||
import SwitchCard from './SwitchCard';
|
||||
import { isCallServiceActionConfig } from '../types/strategy/strategy-generics';
|
||||
|
||||
/**
|
||||
* Scene Card Class
|
||||
*
|
||||
* Used to create a card configuration to control an entity of the scene domain.
|
||||
*
|
||||
* Supports Stateful scenes from https://github.com/hugobloem/stateful_scenes.
|
||||
* If the stateful scene entity is available, it will be used instead of the original scene entity.
|
||||
*/
|
||||
class SceneCard extends AbstractCard {
|
||||
/** Returns the default configuration object for the card. */
|
||||
static getDefaultConfig(): EntityCardConfig {
|
||||
return {
|
||||
type: 'custom:mushroom-entity-card',
|
||||
icon: 'mdi:palette',
|
||||
icon_color: 'blue',
|
||||
tap_action: {
|
||||
action: 'perform-action',
|
||||
action: 'call-service',
|
||||
perform_action: 'scene.turn_on',
|
||||
target: {},
|
||||
target: {
|
||||
entity_id: undefined,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -35,25 +35,16 @@ class SceneCard extends AbstractCard {
|
||||
* @param {EntityCardConfig} [customConfiguration] Custom card configuration.
|
||||
*/
|
||||
constructor(entity: EntityRegistryEntry, customConfiguration?: EntityCardConfig) {
|
||||
const sceneName = entity.entity_id.split('.').pop();
|
||||
const statefulScene = Registry.entities.find((entity) => entity.entity_id === `switch.${sceneName}_stateful_scene`);
|
||||
super(entity);
|
||||
|
||||
super(statefulScene ?? entity);
|
||||
|
||||
// Stateful scene support.
|
||||
if (statefulScene) {
|
||||
this.configuration = new SwitchCard(statefulScene).getCard();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the default configuration.
|
||||
const configuration = SceneCard.getDefaultConfig();
|
||||
|
||||
if (isCallServiceActionConfig(configuration.tap_action)) {
|
||||
configuration.tap_action.target = { entity_id: entity.entity_id };
|
||||
if (
|
||||
isCallServiceActionConfig(configuration.tap_action) &&
|
||||
isCallServiceActionTarget(configuration.tap_action.target)
|
||||
) {
|
||||
configuration.tap_action.target.entity_id = entity.entity_id;
|
||||
}
|
||||
|
||||
configuration.icon = Registry.hassStates[entity.entity_id]?.attributes.icon ?? configuration.icon;
|
||||
|
||||
this.configuration = { ...this.configuration, ...configuration, ...customConfiguration };
|
||||
|
Reference in New Issue
Block a user