Skip to content

Commit

Permalink
climate icon coloring and icon ability
Browse files Browse the repository at this point in the history
  • Loading branch information
warmfire540 committed Jan 26, 2025
1 parent b67cf0d commit 613efae
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 44 deletions.
37 changes: 27 additions & 10 deletions src/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
getEntity,
getState,
} from './helpers';
import { createStateStyles, styles } from './styles';
import { createStateStyles, getClimateStyles, styles } from './styles';
import type {
Config,
EntityConfig,
Expand Down Expand Up @@ -48,6 +48,7 @@ export class RoomSummaryCard extends LitElement {
const roomEntity = {
config: {
entity_id: roomEntityId,
icon: getArea(this._hass, this._config.area).icon,
tap_action: {
action: 'navigate',
navigation_path: this._config.area.replace('_', '-'),
Expand All @@ -56,8 +57,6 @@ export class RoomSummaryCard extends LitElement {
state: getState(this._hass, roomEntityId),
} as EntityInformation;

const icon = getArea(this._hass, this._config.area).icon;

const { cardStyle, textStyle } = createStateStyles(roomEntity.state);

return html`
Expand All @@ -73,7 +72,7 @@ export class RoomSummaryCard extends LitElement {
${this._getLabel()} <br />
<span class="stats">${this._getAreaStatistics()}</span>
</div>
${createStateIcon(this, this._hass, roomEntity, ['room'], icon)}
${createStateIcon(this, this._hass, roomEntity, ['room'])}
${this._states.map((s, i) => {
return createStateIcon(this, this._hass, s, [
'entity',
Expand Down Expand Up @@ -107,17 +106,35 @@ export class RoomSummaryCard extends LitElement {
this._hass = hass;

const baseEntities = [
`light.${this._config.area}_light`,
`switch.${this._config.area}_fan`,
];
{ entity_id: `light.${this._config.area}_light` },
{ entity_id: `switch.${this._config.area}_fan` },
] as EntityConfig[];

const entities = this._config.remove_fan
? this._config.entities
: baseEntities.concat(this._config.entities);

const states = entities.map((entity) => {
const state = getState(hass, entity.entity_id);
const useClimateColors =
!this._config.skip_climate_colors && state.getDomain() === 'climate';

const { climateStyles, climateIcons } = getClimateStyles();

const states = baseEntities.map((entity) => {
return {
config: {
entity_id: entity,
tap_action: { action: 'toggle' },
...entity,
} as EntityConfig,
state: getState(hass, entity),
state: {
...state,
state: useClimateColors ? 'on' : state.state,
attributes: {
icon: useClimateColors ? climateIcons[state.state] : undefined,
on_color: useClimateColors ? climateStyles[state.state] : undefined,
...state.attributes,
},
},
} as EntityInformation;
});

Expand Down
8 changes: 4 additions & 4 deletions src/events.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { HomeAssistant } from './types';
import type { HomeAssistant, State } from './types';

export const doToggle = (hass: HomeAssistant, entity_id: string) => {
hass.callService(entity_id.substr(0, entity_id.indexOf('.')), 'toggle', {
entity_id: entity_id,
export const doToggle = (hass: HomeAssistant, entity: State) => {
hass.callService(entity.getDomain(), 'toggle', {
entity_id: entity.entity_id,
});
};

Expand Down
14 changes: 7 additions & 7 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,16 @@ export const createStateIcon = (
hass: HomeAssistant,
entity: EntityInformation,
classes: String[],
icon: string | undefined = undefined,
): TemplateResult => {
const { state } = entity;
const { iconStyle, iconDivStyle } = createStateStyles(state);
const { iconStyle, iconContainerStyle } = createStateStyles(state);

return html`<div
class="${['icon', ...classes].join(' ')}"
style=${iconDivStyle}
style=${iconContainerStyle}
>
<ha-state-icon
.hass=${hass}
.icon="${icon}"
.stateObj=${state}
style=${iconStyle}
@action=${{
Expand All @@ -44,7 +42,7 @@ export const createStateIcon = (
break;
case 'toggle':
default:
doToggle(hass, state.entity_id);
doToggle(hass, state);
break;
}
break;
Expand All @@ -67,8 +65,10 @@ export const createStateIcon = (
</div>`;
};

export const getState = (hass: HomeAssistant, entityId: string): State =>
(hass.states as { [key: string]: any })[entityId];
export const getState = (hass: HomeAssistant, entityId: string): State => {
const state = (hass.states as { [key: string]: any })[entityId];
return { ...state, getDomain: () => state.entity_id.split('.')[0] };
};

export const getEntity = (hass: HomeAssistant, entityId: string): Entity =>
(hass.entities as { [key: string]: any })[entityId];
Expand Down
6 changes: 0 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { RoomSummaryCard } from './card';

declare global {
interface Window {
customCards: Array<Object>;
}
}

// Register our custom card
customElements.define('room-summary-card', RoomSummaryCard);

Expand Down
64 changes: 47 additions & 17 deletions src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,64 @@ import {

import type { State } from './types';

export const getClimateStyles = (): {
climateStyles: Record<string, string>;
climateIcons: Record<string, string>;
} => {
return {
climateStyles: {
auto: 'green',
cool: 'blue',
heat: 'red',
dry: 'yellow',
heat_cool: 'purple',
fan_only: 'green',
off: 'grey',
},
climateIcons: {
auto: 'mdi:autorenew',
cool: 'mdi:snowflake',
heat: 'mdi:fire',
dry: 'mdi:water',
heat_cool: 'mdi:sun-snowflake',
fan_only: 'mdi:fan',
off: 'mdi:snowflake-off',
},
};
};

export const createStateStyles = (
state: State,
): {
cardStyle: DirectiveResult<typeof StyleMapDirective>;
iconStyle: DirectiveResult<typeof StyleMapDirective>;
iconDivStyle: DirectiveResult<typeof StyleMapDirective>;
iconContainerStyle: DirectiveResult<typeof StyleMapDirective>;
textStyle: DirectiveResult<typeof StyleMapDirective>;
} => {
const isActive = state.state === 'on';
const color = state.attributes.on_color || 'yellow';

return {
cardStyle: styleMap({
'background-color': isActive
? `rgba(var(--color-background-${color}),var(--opacity-bg))`
: undefined,
}),
iconStyle: styleMap({
color: isActive ? `rgba(var(--color-${color}),1)` : undefined,
}),
iconDivStyle: styleMap({
'background-color': isActive
? `rgba(var(--color-${color}),0.2)`
: undefined,
}),
textStyle: styleMap({
color: isActive ? `rgba(var(--color-${color}-text),1)` : undefined,
}),
cardStyle:
isActive &&
styleMap({
'background-color': `rgba(var(--color-background-${color}),var(--opacity-bg))`,
}),
iconStyle:
isActive &&
styleMap({
color: `rgba(var(--color-${color}),1)`,
}),
iconContainerStyle:
isActive &&
styleMap({
'background-color': `rgba(var(--color-${color}),0.2)`,
}),
textStyle:
isActive &&
styleMap({
color: `rgba(var(--color-${color}-text),1)`,
}),
};
};

Expand Down
11 changes: 11 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export interface Config {
area: string;
entity: EntityConfig;
entities: EntityConfig[];
remove_fan: boolean;
skip_climate_colors: boolean;
}

export interface EntityConfig {
Expand Down Expand Up @@ -67,6 +69,7 @@ export interface Device {
area_id: string;
}

// this.substring(0, this.indexOf('.'));?
/**
* Represents the current state and attributes of a Home Assistant entity.
* Used to track an entity's status and properties at a given moment.
Expand All @@ -90,6 +93,8 @@ export type State = {
* Keys are strings, values can be any type
*/
attributes: Record<string, any>;

getDomain: () => string;
};

/**
Expand Down Expand Up @@ -122,3 +127,9 @@ export type ActionHandlerEvent = HASSDomEvent<ActionHandlerDetail>;
export interface HASSDomEvent<T> extends Event {
detail: T;
}

declare global {
interface Window {
customCards: Array<Object>;
}
}

0 comments on commit 613efae

Please sign in to comment.