mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 00:06:35 +00:00
Add event entity (#17332)
This commit is contained in:
parent
3189ef0701
commit
0eebc9095c
@ -135,6 +135,14 @@ const ENTITIES = [
|
|||||||
getEntity("text", "unavailable", "unavailable", {
|
getEntity("text", "unavailable", "unavailable", {
|
||||||
friendly_name: "Message",
|
friendly_name: "Message",
|
||||||
}),
|
}),
|
||||||
|
getEntity("event", "unavailable", "unavailable", {
|
||||||
|
friendly_name: "Empty remote",
|
||||||
|
}),
|
||||||
|
getEntity("event", "doorbell", "2023-07-17T21:26:11.615+00:00", {
|
||||||
|
friendly_name: "Doorbell",
|
||||||
|
device_class: "doorbell",
|
||||||
|
event_type: "Ding-Dong",
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@ -154,6 +162,7 @@ const CONFIGS = [
|
|||||||
- input_number.number
|
- input_number.number
|
||||||
- sensor.humidity
|
- sensor.humidity
|
||||||
- text.message
|
- text.message
|
||||||
|
- event.doorbell
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -246,6 +255,7 @@ const CONFIGS = [
|
|||||||
- input_number.unavailable
|
- input_number.unavailable
|
||||||
- input_select.unavailable
|
- input_select.unavailable
|
||||||
- text.unavailable
|
- text.unavailable
|
||||||
|
- event.unavailable
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
mdiBookmark,
|
mdiBookmark,
|
||||||
mdiBrightness5,
|
mdiBrightness5,
|
||||||
mdiBullhorn,
|
mdiBullhorn,
|
||||||
|
mdiButtonPointer,
|
||||||
mdiCalendar,
|
mdiCalendar,
|
||||||
mdiCalendarClock,
|
mdiCalendarClock,
|
||||||
mdiCarCoolantLevel,
|
mdiCarCoolantLevel,
|
||||||
@ -28,7 +29,6 @@ import {
|
|||||||
mdiFormatListBulleted,
|
mdiFormatListBulleted,
|
||||||
mdiFormTextbox,
|
mdiFormTextbox,
|
||||||
mdiGauge,
|
mdiGauge,
|
||||||
mdiGestureTapButton,
|
|
||||||
mdiGoogleAssistant,
|
mdiGoogleAssistant,
|
||||||
mdiGoogleCirclesCommunities,
|
mdiGoogleCirclesCommunities,
|
||||||
mdiHomeAssistant,
|
mdiHomeAssistant,
|
||||||
@ -93,7 +93,7 @@ export const FIXED_DOMAIN_ICONS = {
|
|||||||
homekit: mdiHomeAutomation,
|
homekit: mdiHomeAutomation,
|
||||||
image: mdiImage,
|
image: mdiImage,
|
||||||
image_processing: mdiImageFilterFrames,
|
image_processing: mdiImageFilterFrames,
|
||||||
input_button: mdiGestureTapButton,
|
input_button: mdiButtonPointer,
|
||||||
input_datetime: mdiCalendarClock,
|
input_datetime: mdiCalendarClock,
|
||||||
input_number: mdiRayVertex,
|
input_number: mdiRayVertex,
|
||||||
input_select: mdiFormatListBulleted,
|
input_select: mdiFormatListBulleted,
|
||||||
@ -178,6 +178,7 @@ export const DOMAINS_WITH_CARD = [
|
|||||||
"climate",
|
"climate",
|
||||||
"cover",
|
"cover",
|
||||||
"configurator",
|
"configurator",
|
||||||
|
"event",
|
||||||
"input_button",
|
"input_button",
|
||||||
"input_select",
|
"input_select",
|
||||||
"input_number",
|
"input_number",
|
||||||
|
@ -185,9 +185,15 @@ export const computeStateDisplayFromEntityAttributes = (
|
|||||||
|
|
||||||
// state is a timestamp
|
// state is a timestamp
|
||||||
if (
|
if (
|
||||||
["button", "image", "input_button", "scene", "stt", "tts"].includes(
|
[
|
||||||
domain
|
"button",
|
||||||
) ||
|
"event",
|
||||||
|
"image",
|
||||||
|
"input_button",
|
||||||
|
"scene",
|
||||||
|
"stt",
|
||||||
|
"tts",
|
||||||
|
].includes(domain) ||
|
||||||
(domain === "sensor" && attributes.device_class === "timestamp")
|
(domain === "sensor" && attributes.device_class === "timestamp")
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
mdiAudioVideoOff,
|
mdiAudioVideoOff,
|
||||||
mdiBluetooth,
|
mdiBluetooth,
|
||||||
mdiBluetoothConnect,
|
mdiBluetoothConnect,
|
||||||
|
mdiButtonPointer,
|
||||||
mdiCalendar,
|
mdiCalendar,
|
||||||
mdiCast,
|
mdiCast,
|
||||||
mdiCastConnected,
|
mdiCastConnected,
|
||||||
@ -16,8 +17,10 @@ import {
|
|||||||
mdiClock,
|
mdiClock,
|
||||||
mdiCloseCircleOutline,
|
mdiCloseCircleOutline,
|
||||||
mdiCrosshairsQuestion,
|
mdiCrosshairsQuestion,
|
||||||
|
mdiDoorbell,
|
||||||
mdiFan,
|
mdiFan,
|
||||||
mdiFanOff,
|
mdiFanOff,
|
||||||
|
mdiGestureTap,
|
||||||
mdiGestureTapButton,
|
mdiGestureTapButton,
|
||||||
mdiLanConnect,
|
mdiLanConnect,
|
||||||
mdiLanDisconnect,
|
mdiLanDisconnect,
|
||||||
@ -25,6 +28,7 @@ import {
|
|||||||
mdiLockAlert,
|
mdiLockAlert,
|
||||||
mdiLockClock,
|
mdiLockClock,
|
||||||
mdiLockOpen,
|
mdiLockOpen,
|
||||||
|
mdiMotionSensor,
|
||||||
mdiPackage,
|
mdiPackage,
|
||||||
mdiPackageDown,
|
mdiPackageDown,
|
||||||
mdiPackageUp,
|
mdiPackageUp,
|
||||||
@ -111,7 +115,7 @@ export const domainIconWithoutDefault = (
|
|||||||
case "update":
|
case "update":
|
||||||
return mdiPackageUp;
|
return mdiPackageUp;
|
||||||
default:
|
default:
|
||||||
return mdiGestureTapButton;
|
return mdiButtonPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "camera":
|
case "camera":
|
||||||
@ -131,6 +135,18 @@ export const domainIconWithoutDefault = (
|
|||||||
}
|
}
|
||||||
return compareState === "not_home" ? mdiAccountArrowRight : mdiAccount;
|
return compareState === "not_home" ? mdiAccountArrowRight : mdiAccount;
|
||||||
|
|
||||||
|
case "event":
|
||||||
|
switch (stateObj?.attributes.device_class) {
|
||||||
|
case "doorbell":
|
||||||
|
return mdiDoorbell;
|
||||||
|
case "button":
|
||||||
|
return mdiGestureTapButton;
|
||||||
|
case "motion":
|
||||||
|
return mdiMotionSensor;
|
||||||
|
default:
|
||||||
|
return mdiGestureTap;
|
||||||
|
}
|
||||||
|
|
||||||
case "fan":
|
case "fan":
|
||||||
return compareState === "off" ? mdiFanOff : mdiFan;
|
return compareState === "off" ? mdiFanOff : mdiFan;
|
||||||
|
|
||||||
|
@ -250,6 +250,11 @@ export const getStates = (
|
|||||||
result.push("home", "not_home");
|
result.push("home", "not_home");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "event":
|
||||||
|
if (attribute === "event_type") {
|
||||||
|
result.push(...state.attributes.event_types);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "fan":
|
case "fan":
|
||||||
if (attribute === "preset_mode") {
|
if (attribute === "preset_mode") {
|
||||||
result.push(...state.attributes.preset_modes);
|
result.push(...state.attributes.preset_modes);
|
||||||
|
@ -6,7 +6,7 @@ export function stateActive(stateObj: HassEntity, state?: string): boolean {
|
|||||||
const domain = computeDomain(stateObj.entity_id);
|
const domain = computeDomain(stateObj.entity_id);
|
||||||
const compareState = state !== undefined ? state : stateObj?.state;
|
const compareState = state !== undefined ? state : stateObj?.state;
|
||||||
|
|
||||||
if (["button", "input_button", "scene"].includes(domain)) {
|
if (["button", "event", "input_button", "scene"].includes(domain)) {
|
||||||
return compareState !== UNAVAILABLE;
|
return compareState !== UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ export const STATE_ATTRIBUTES = [
|
|||||||
"emulated_hue_name",
|
"emulated_hue_name",
|
||||||
"emulated_hue",
|
"emulated_hue",
|
||||||
"entity_picture",
|
"entity_picture",
|
||||||
|
"event_types",
|
||||||
"friendly_name",
|
"friendly_name",
|
||||||
"haaska_hidden",
|
"haaska_hidden",
|
||||||
"haaska_name",
|
"haaska_name",
|
||||||
|
@ -12,6 +12,7 @@ import { LocalizeFunc } from "../common/translations/localize";
|
|||||||
import { HaEntityPickerEntityFilterFunc } from "../components/entity/ha-entity-picker";
|
import { HaEntityPickerEntityFilterFunc } from "../components/entity/ha-entity-picker";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { UNAVAILABLE, UNKNOWN } from "./entity";
|
import { UNAVAILABLE, UNKNOWN } from "./entity";
|
||||||
|
import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
|
||||||
|
|
||||||
const LOGBOOK_LOCALIZE_PATH = "ui.components.logbook.messages";
|
const LOGBOOK_LOCALIZE_PATH = "ui.components.logbook.messages";
|
||||||
export const CONTINUOUS_DOMAINS = ["counter", "proximity", "sensor", "zone"];
|
export const CONTINUOUS_DOMAINS = ["counter", "proximity", "sensor", "zone"];
|
||||||
@ -156,6 +157,7 @@ export const createHistoricState = (
|
|||||||
attributes: {
|
attributes: {
|
||||||
// Rebuild the historical state by copying static attributes only
|
// Rebuild the historical state by copying static attributes only
|
||||||
device_class: currentStateObj?.attributes.device_class,
|
device_class: currentStateObj?.attributes.device_class,
|
||||||
|
event_type: currentStateObj?.attributes.event_type,
|
||||||
source_type: currentStateObj?.attributes.source_type,
|
source_type: currentStateObj?.attributes.source_type,
|
||||||
has_date: currentStateObj?.attributes.has_date,
|
has_date: currentStateObj?.attributes.has_date,
|
||||||
has_time: currentStateObj?.attributes.has_time,
|
has_time: currentStateObj?.attributes.has_time,
|
||||||
@ -343,6 +345,23 @@ export const localizeStateMessage = (
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "event": {
|
||||||
|
const event_type =
|
||||||
|
computeAttributeValueDisplay(
|
||||||
|
hass!.localize,
|
||||||
|
stateObj,
|
||||||
|
hass.locale,
|
||||||
|
hass.config,
|
||||||
|
hass.entities,
|
||||||
|
"event_type"
|
||||||
|
)?.toString() ||
|
||||||
|
localize(`${LOGBOOK_LOCALIZE_PATH}.detected_unknown_event`);
|
||||||
|
|
||||||
|
return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_event`, {
|
||||||
|
event_type: autoCaseNoun(event_type, hass.language),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
case "lock":
|
case "lock":
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case "unlocked":
|
case "unlocked":
|
||||||
|
@ -10,6 +10,7 @@ export const SCENE_IGNORED_DOMAINS = [
|
|||||||
"button",
|
"button",
|
||||||
"configuration",
|
"configuration",
|
||||||
"device_tracker",
|
"device_tracker",
|
||||||
|
"event",
|
||||||
"image_processing",
|
"image_processing",
|
||||||
"input_button",
|
"input_button",
|
||||||
"persistent_notification",
|
"persistent_notification",
|
||||||
|
@ -72,6 +72,7 @@ export const DOMAINS_HIDE_DEFAULT_MORE_INFO = [
|
|||||||
"select",
|
"select",
|
||||||
"text",
|
"text",
|
||||||
"update",
|
"update",
|
||||||
|
"event",
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Domains that should have the history hidden in the more info dialog. */
|
/** Domains that should have the history hidden in the more info dialog. */
|
||||||
|
@ -52,6 +52,8 @@ export default class HaNumericStateCondition extends LitElement {
|
|||||||
"effect_list",
|
"effect_list",
|
||||||
"effect",
|
"effect",
|
||||||
"entity_picture",
|
"entity_picture",
|
||||||
|
"event_type",
|
||||||
|
"event_types",
|
||||||
"fan_mode",
|
"fan_mode",
|
||||||
"fan_modes",
|
"fan_modes",
|
||||||
"fan_speed_list",
|
"fan_speed_list",
|
||||||
|
@ -42,6 +42,7 @@ const SCHEMA = [
|
|||||||
"editable",
|
"editable",
|
||||||
"effect_list",
|
"effect_list",
|
||||||
"entity_picture",
|
"entity_picture",
|
||||||
|
"event_types",
|
||||||
"fan_modes",
|
"fan_modes",
|
||||||
"fan_speed_list",
|
"fan_speed_list",
|
||||||
"forecast",
|
"forecast",
|
||||||
|
@ -51,6 +51,8 @@ export class HaNumericStateTrigger extends LitElement {
|
|||||||
"effect",
|
"effect",
|
||||||
"entity_id",
|
"entity_id",
|
||||||
"entity_picture",
|
"entity_picture",
|
||||||
|
"event_type",
|
||||||
|
"event_types",
|
||||||
"fan_mode",
|
"fan_mode",
|
||||||
"fan_modes",
|
"fan_modes",
|
||||||
"fan_speed_list",
|
"fan_speed_list",
|
||||||
|
@ -76,6 +76,7 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
"effect_list",
|
"effect_list",
|
||||||
"entity_id",
|
"entity_id",
|
||||||
"entity_picture",
|
"entity_picture",
|
||||||
|
"event_types",
|
||||||
"fan_modes",
|
"fan_modes",
|
||||||
"fan_speed_list",
|
"fan_speed_list",
|
||||||
"friendly_name",
|
"friendly_name",
|
||||||
|
@ -207,16 +207,25 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
const result = groupBy(entities, (entry) =>
|
const result = groupBy(entities, (entry) =>
|
||||||
entry.entity_category
|
entry.entity_category
|
||||||
? entry.entity_category
|
? entry.entity_category
|
||||||
|
: computeDomain(entry.entity_id) === "event"
|
||||||
|
? "event"
|
||||||
: SENSOR_ENTITIES.includes(computeDomain(entry.entity_id))
|
: SENSOR_ENTITIES.includes(computeDomain(entry.entity_id))
|
||||||
? "sensor"
|
? "sensor"
|
||||||
: "control"
|
: "control"
|
||||||
) as Record<
|
) as Record<
|
||||||
| "control"
|
| "control"
|
||||||
|
| "event"
|
||||||
| "sensor"
|
| "sensor"
|
||||||
| NonNullable<EntityRegistryEntry["entity_category"]>,
|
| NonNullable<EntityRegistryEntry["entity_category"]>,
|
||||||
EntityRegistryStateEntry[]
|
EntityRegistryStateEntry[]
|
||||||
>;
|
>;
|
||||||
for (const key of ["control", "sensor", "diagnostic", "config"]) {
|
for (const key of [
|
||||||
|
"config",
|
||||||
|
"control",
|
||||||
|
"diagnostic",
|
||||||
|
"event",
|
||||||
|
"sensor",
|
||||||
|
]) {
|
||||||
if (!(key in result)) {
|
if (!(key in result)) {
|
||||||
result[key] = [];
|
result[key] = [];
|
||||||
}
|
}
|
||||||
@ -877,24 +886,25 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
${!this.narrow ? [automationCard, sceneCard, scriptCard] : ""}
|
${!this.narrow ? [automationCard, sceneCard, scriptCard] : ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
${(["control", "sensor", "config", "diagnostic"] as const).map(
|
${(
|
||||||
(category) =>
|
["control", "sensor", "event", "config", "diagnostic"] as const
|
||||||
// Make sure we render controls if no other cards will be rendered
|
).map((category) =>
|
||||||
entitiesByCategory[category].length > 0 ||
|
// Make sure we render controls if no other cards will be rendered
|
||||||
(entities.length === 0 && category === "control")
|
entitiesByCategory[category].length > 0 ||
|
||||||
? html`
|
(entities.length === 0 && category === "control")
|
||||||
<ha-device-entities-card
|
? html`
|
||||||
.hass=${this.hass}
|
<ha-device-entities-card
|
||||||
.header=${this.hass.localize(
|
.hass=${this.hass}
|
||||||
`ui.panel.config.devices.entities.${category}`
|
.header=${this.hass.localize(
|
||||||
)}
|
`ui.panel.config.devices.entities.${category}`
|
||||||
.deviceName=${deviceName}
|
)}
|
||||||
.entities=${entitiesByCategory[category]}
|
.deviceName=${deviceName}
|
||||||
.showHidden=${device.disabled_by !== null}
|
.entities=${entitiesByCategory[category]}
|
||||||
>
|
.showHidden=${device.disabled_by !== null}
|
||||||
</ha-device-entities-card>
|
>
|
||||||
`
|
</ha-device-entities-card>
|
||||||
: ""
|
`
|
||||||
|
: ""
|
||||||
)}
|
)}
|
||||||
<ha-device-via-devices-card
|
<ha-device-via-devices-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import "../entity-rows/hui-event-entity-row";
|
||||||
import "../entity-rows/hui-media-player-entity-row";
|
import "../entity-rows/hui-media-player-entity-row";
|
||||||
import "../entity-rows/hui-scene-entity-row";
|
import "../entity-rows/hui-scene-entity-row";
|
||||||
import "../entity-rows/hui-script-entity-row";
|
import "../entity-rows/hui-script-entity-row";
|
||||||
@ -29,6 +30,7 @@ const LAZY_LOAD_TYPES = {
|
|||||||
"cover-entity": () => import("../entity-rows/hui-cover-entity-row"),
|
"cover-entity": () => import("../entity-rows/hui-cover-entity-row"),
|
||||||
"date-entity": () => import("../entity-rows/hui-date-entity-row"),
|
"date-entity": () => import("../entity-rows/hui-date-entity-row"),
|
||||||
"datetime-entity": () => import("../entity-rows/hui-datetime-entity-row"),
|
"datetime-entity": () => import("../entity-rows/hui-datetime-entity-row"),
|
||||||
|
"event-entity": () => import("../entity-rows/hui-event-entity-row"),
|
||||||
"group-entity": () => import("../entity-rows/hui-group-entity-row"),
|
"group-entity": () => import("../entity-rows/hui-group-entity-row"),
|
||||||
"input-button-entity": () =>
|
"input-button-entity": () =>
|
||||||
import("../entity-rows/hui-input-button-entity-row"),
|
import("../entity-rows/hui-input-button-entity-row"),
|
||||||
@ -65,6 +67,7 @@ const DOMAIN_TO_ELEMENT_TYPE = {
|
|||||||
cover: "cover",
|
cover: "cover",
|
||||||
date: "date",
|
date: "date",
|
||||||
datetime: "datetime",
|
datetime: "datetime",
|
||||||
|
event: "event",
|
||||||
fan: "toggle",
|
fan: "toggle",
|
||||||
group: "group",
|
group: "group",
|
||||||
humidifier: "humidifier",
|
humidifier: "humidifier",
|
||||||
|
129
src/panels/lovelace/entity-rows/hui-event-entity-row.ts
Normal file
129
src/panels/lovelace/entity-rows/hui-event-entity-row.ts
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||||
|
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
|
||||||
|
import { isUnavailableState } from "../../../data/entity";
|
||||||
|
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { EntitiesCardEntityConfig } from "../cards/types";
|
||||||
|
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||||
|
import { handleAction } from "../common/handle-action";
|
||||||
|
import { hasAction } from "../common/has-action";
|
||||||
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
|
import "../components/hui-generic-entity-row";
|
||||||
|
import "../components/hui-timestamp-display";
|
||||||
|
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||||
|
import { TimestampRenderingFormat } from "../components/types";
|
||||||
|
import { LovelaceRow } from "./types";
|
||||||
|
|
||||||
|
interface EventEntityConfig extends EntitiesCardEntityConfig {
|
||||||
|
format?: TimestampRenderingFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement("hui-event-entity-row")
|
||||||
|
class HuiEventEntityRow extends LitElement implements LovelaceRow {
|
||||||
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _config?: EventEntityConfig;
|
||||||
|
|
||||||
|
public setConfig(config: EventEntityConfig): void {
|
||||||
|
if (!config) {
|
||||||
|
throw new Error("Invalid configuration");
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||||
|
return hasConfigOrEntityChanged(this, changedProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._config || !this.hass) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stateObj = this.hass.states[this._config.entity];
|
||||||
|
|
||||||
|
if (!stateObj) {
|
||||||
|
return html`
|
||||||
|
<hui-warning>
|
||||||
|
${createEntityNotFoundWarning(this.hass, this._config.entity)}
|
||||||
|
</hui-warning>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
||||||
|
<div
|
||||||
|
@action=${this._handleAction}
|
||||||
|
.actionHandler=${actionHandler({
|
||||||
|
hasHold: hasAction(this._config.hold_action),
|
||||||
|
hasDoubleClick: hasAction(this._config.double_tap_action),
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div class="what">
|
||||||
|
${isUnavailableState(stateObj.state)
|
||||||
|
? computeStateDisplay(
|
||||||
|
this.hass!.localize,
|
||||||
|
stateObj,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.config,
|
||||||
|
this.hass.entities
|
||||||
|
)
|
||||||
|
: computeAttributeValueDisplay(
|
||||||
|
this.hass!.localize,
|
||||||
|
stateObj,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.config,
|
||||||
|
this.hass.entities,
|
||||||
|
"event_type"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="when">
|
||||||
|
${isUnavailableState(stateObj.state)
|
||||||
|
? ``
|
||||||
|
: html`
|
||||||
|
<hui-timestamp-display
|
||||||
|
.hass=${this.hass}
|
||||||
|
.ts=${new Date(stateObj.state)}
|
||||||
|
.format=${this._config.format}
|
||||||
|
capitalize
|
||||||
|
></hui-timestamp-display>
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleAction(ev: ActionHandlerEvent) {
|
||||||
|
handleAction(this, this.hass!, this._config!, ev.detail.action);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return css`
|
||||||
|
div {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.when {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
.what {
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-event-entity-row": HuiEventEntityRow;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import "./state-card-humidifier";
|
|||||||
import "./state-card-configurator";
|
import "./state-card-configurator";
|
||||||
import "./state-card-cover";
|
import "./state-card-cover";
|
||||||
import "./state-card-display";
|
import "./state-card-display";
|
||||||
|
import "./state-card-event";
|
||||||
import "./state-card-input_button";
|
import "./state-card-input_button";
|
||||||
import "./state-card-input_number";
|
import "./state-card-input_number";
|
||||||
import "./state-card-input_select";
|
import "./state-card-input_select";
|
||||||
|
59
src/state-summary/state-card-event.ts
Normal file
59
src/state-summary/state-card-event.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { CSSResultGroup, html, LitElement } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import "../components/entity/ha-entity-toggle";
|
||||||
|
import "../components/entity/state-info";
|
||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
import { isUnavailableState } from "../data/entity";
|
||||||
|
import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
|
||||||
|
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||||
|
import { haStyle } from "../resources/styles";
|
||||||
|
|
||||||
|
@customElement("state-card-event")
|
||||||
|
export class StateCardEvent extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public stateObj!: HassEntity;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public inDialog = false;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
<div class="horizontal justified layout">
|
||||||
|
<state-info
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
.inDialog=${this.inDialog}
|
||||||
|
></state-info>
|
||||||
|
<div class="event_type">
|
||||||
|
${isUnavailableState(this.stateObj.state)
|
||||||
|
? computeStateDisplay(
|
||||||
|
this.hass!.localize,
|
||||||
|
this.stateObj,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.config,
|
||||||
|
this.hass.entities
|
||||||
|
)
|
||||||
|
: computeAttributeValueDisplay(
|
||||||
|
this.hass!.localize,
|
||||||
|
this.stateObj,
|
||||||
|
this.hass.locale,
|
||||||
|
this.hass.config,
|
||||||
|
this.hass.entities,
|
||||||
|
"event_type"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return haStyle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"state-card-event": StateCardEvent;
|
||||||
|
}
|
||||||
|
}
|
@ -357,7 +357,9 @@
|
|||||||
"became_unavailable": "became unavailable",
|
"became_unavailable": "became unavailable",
|
||||||
"became_unknown": "became unknown",
|
"became_unknown": "became unknown",
|
||||||
"detected_tampering": "detected tampering",
|
"detected_tampering": "detected tampering",
|
||||||
"cleared_tampering": "cleared tampering"
|
"cleared_tampering": "cleared tampering",
|
||||||
|
"detected_event": "{event_type} event detected",
|
||||||
|
"detected_unknown_event": "detected an unknown event"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
@ -2322,7 +2324,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"event": {
|
"event": {
|
||||||
"label": "Event",
|
"label": "Manual event",
|
||||||
"event_type": "Event type",
|
"event_type": "Event type",
|
||||||
"event_data": "Event data",
|
"event_data": "Event data",
|
||||||
"context_users": "Limit to events triggered by",
|
"context_users": "Limit to events triggered by",
|
||||||
@ -2640,11 +2642,11 @@
|
|||||||
"label": "Condition"
|
"label": "Condition"
|
||||||
},
|
},
|
||||||
"event": {
|
"event": {
|
||||||
"label": "Event",
|
"label": "Manual event",
|
||||||
"event": "[%key:ui::panel::config::automation::editor::triggers::type::event::label%]",
|
"event": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_type%]",
|
||||||
"event_data": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_data%]",
|
"event_data": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_data%]",
|
||||||
"description": {
|
"description": {
|
||||||
"full": "Fire event {name}",
|
"full": "Manually fire event {name}",
|
||||||
"template": "based on a template"
|
"template": "based on a template"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3212,6 +3214,7 @@
|
|||||||
"entities": {
|
"entities": {
|
||||||
"entities": "Entities",
|
"entities": "Entities",
|
||||||
"control": "Controls",
|
"control": "Controls",
|
||||||
|
"event": "Events",
|
||||||
"sensor": "Sensors",
|
"sensor": "Sensors",
|
||||||
"diagnostic": "Diagnostic",
|
"diagnostic": "Diagnostic",
|
||||||
"config": "Configuration",
|
"config": "Configuration",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user