Skip to content

Commit

Permalink
add support for notify entities
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsfaber committed Oct 23, 2024
1 parent 4da6534 commit 69c971d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 32 deletions.
46 changes: 33 additions & 13 deletions custom_components/alarmo/frontend/src/data/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,22 +137,28 @@ export const computeAreaDisplay = (
}
};

export const computeServiceDisplay = (hass: HomeAssistant, ...services: (string | undefined)[]) => {
const output = services
.map(service => {
if (!service) return null;
const domain = computeDomain(service);
const domainService = computeEntity(service);
export const computeServiceDisplay = (hass: HomeAssistant, ...actions: { service?: string, entity_id?: string }[]) => {
const output = actions
.map(action => {

if (action.entity_id) {
let data = computeEntityDisplay([action.entity_id], hass).pop();
return data;
}

if (!action || !action.service) return null;
const domain = computeDomain(action.service);
const domainService = computeEntity(action.service);

let data = {
value: service,
value: action.service,
name: domainService
.replace(/_/g, ' ')
.split(' ')
.map(e => e.substring(0, 1).toUpperCase() + e.substring(1))
.join(' '),
icon: 'hass:home',
description: service,
description: action.service,
};

switch (domain) {
Expand All @@ -170,7 +176,6 @@ export const computeServiceDisplay = (hass: HomeAssistant, ...services: (string
data = { ...data, icon: 'hass:microphone' };
break;
}

return data;
})
.filter(isDefined);
Expand Down Expand Up @@ -220,18 +225,33 @@ export const computeEntityDisplay = (entity_id: string[], hass: HomeAssistant) =
return data;
};

export const getNotifyServices = (hass: HomeAssistant) => {
let res: string[] = [];
export const getNotifyServices = (hass: HomeAssistant): { service: string, entity_id?: string }[] => {
let res: { service: string, entity_id?: string }[] = [];
if ('notify' in hass.services)
res = [...res, ...Object.keys(hass.services.notify).map(service => `notify.${service}`)];
res = [
...res,
...Object.keys(hass.services.notify)
.filter(e => e != 'send_message')
.map(service => Object({ service: `notify.${service}` }))
];

if ('tts' in hass.services)
res = [
...res,
...Object.keys(hass.services.tts)
.filter(e => e != 'clear_cache')
.map(service => `tts.${service}`),
.map(service => Object({ service: `tts.${service}` }))
];

Object.keys(hass.states).filter(e => computeDomain(e) == 'notify')
.map(entityId => {
res = [...res,
{
service: 'notify.send_message',
entity_id: entityId
}
]
});
return res;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class NotificationEditorCard extends LitElement {
this.alarmoConfig = await fetchConfig(this.hass);

if (this.item) {
let actions = this.item.actions.map(e => omit(e, 'entity_id'));
let actions = [...this.item.actions];
this.config = { ...this.item, actions: [actions[0], ...actions.slice(1)] };
if (this.config.triggers.length > 1) this.config = { ...this.config, triggers: [this.config.triggers[0]] };

Expand Down Expand Up @@ -200,7 +200,7 @@ export class NotificationEditorCard extends LitElement {
?disabled=${!getNotifyServices(this.hass).length}
label=${localize('panels.actions.cards.new_notification.fields.target.heading', this.hass.language)}
icons=${true}
.value=${this.config.actions[0].service}
.value=${getNotifyServices(this.hass).find(e => e.entity_id == this.config.actions[0].entity_id && e.service == this.config.actions[0].service)?.entity_id || getNotifyServices(this.hass).find(e => e.service == this.config.actions[0].service)?.service || undefined}
@value-changed=${this._setService}
?invalid=${this.errors.service}
allow-custom-value
Expand Down Expand Up @@ -499,14 +499,11 @@ export class NotificationEditorCard extends LitElement {
private _setService(ev: CustomEvent) {
ev.stopPropagation();
const value = String(ev.detail.value);
let config = getNotifyServices(this.hass).find(e => e.entity_id == value || e.service == value);
let actionConfig = this.config.actions;
Object.assign(actionConfig, { [0]: { ...actionConfig[0], service: value, ...omit(actionConfig[0], 'service') } });
if ((actionConfig[0].data || {}).entity_id && computeDomain(value) == 'notify')
Object.assign(actionConfig, {
[0]: { ...actionConfig[0], data: omit(actionConfig[0].data || {}, 'entity_id') },
});
Object.assign(actionConfig, { [0]: { ...config, ...omit(actionConfig[0], 'service', 'entity_id') } });
this.config = { ...this.config, actions: actionConfig };
if (Object.keys(this.errors).includes('service')) this._validateConfig();
if (Object.keys(this.errors).includes('service') || Object.keys(this.errors).includes('entity')) this._validateConfig();
}

private _setTitle(ev: Event) {
Expand Down Expand Up @@ -603,9 +600,10 @@ export class NotificationEditorCard extends LitElement {
this.errors = { ...this.errors, modes: true };

const actionConfig = data.actions[0];

if (
!actionConfig.service ||
(!getNotifyServices(this.hass).includes(actionConfig.service) && computeDomain(actionConfig.service) != 'script')
(!getNotifyServices(this.hass).find(e => e.service == actionConfig.service && e.entity_id == actionConfig.entity_id) && computeDomain(actionConfig.service) != 'script')
)
this.errors = { ...this.errors, service: true };
else if (
Expand Down Expand Up @@ -640,7 +638,7 @@ export class NotificationEditorCard extends LitElement {
return (
actionConfig.service &&
(computeDomain(actionConfig.service) == 'script' ||
getNotifyServices(this.hass).includes(actionConfig.service)) &&
getNotifyServices(this.hass).find(e => e.service == actionConfig.service && e.entity_id == actionConfig.entity_id)) &&
isValidString(actionConfig.data?.message)
);
}
Expand Down Expand Up @@ -670,7 +668,7 @@ export class NotificationEditorCard extends LitElement {

if (!serviceData.message) serviceData = { ...serviceData, message: '' };

if (getNotifyServices(this.hass).includes(actionConfig.service!)) {
if (getNotifyServices(this.hass).find(e => e.service == actionConfig.service && e.entity_id == actionConfig.entity_id)) {
if (computeDomain(actionConfig.service!) == 'notify' && !serviceData.title)
serviceData = { ...serviceData, title: '' };
if (computeDomain(actionConfig.service!) == 'tts' && !serviceData.entity_id)
Expand All @@ -696,7 +694,7 @@ export class NotificationEditorCard extends LitElement {
const domain = this.config.actions[0].service ? computeDomain(this.config.actions[0].service) : null;
if (!event) return '';
if (domain == 'notify') {
const target = computeServiceDisplay(this.hass, this.config.actions[0].service);
const target = computeServiceDisplay(this.hass, this.config.actions[0]);
if (!target.length) return '';

return localize(
Expand Down Expand Up @@ -819,8 +817,7 @@ export class NotificationEditorCard extends LitElement {

private async _testClick(ev: Event) {
const data = this._parseAutomation();
const action = data.actions[0];
const [domain, service] = action.service!.split('.');
let action = { ...data.actions[0] };

let message = action.data!.message;
message = message.replace('{{open_sensors|format=short}}', 'Some Example Sensor');
Expand All @@ -830,11 +827,9 @@ export class NotificationEditorCard extends LitElement {
message = message.replace('{{changed_by}}', 'Some Example User');
message = message.replace('{{delay}}', '30');

let sequence = {
action: action.service,
data: action.data,
entity_id: action.entity_id
};
action = { ...action, data: { ...action.data, message: message } };

let sequence = { ...omit(action, 'service'), action: action.service };

this.hass.callWS({
type: "execute_script",
Expand Down

0 comments on commit 69c971d

Please sign in to comment.