diff --git a/public/manifest.json b/public/manifest.json index 6f6dfd7..2acfd42 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -24,6 +24,7 @@ "Icon": "images/actionImage", "Name": "Entity (custom icons)", "PropertyInspectorPath": "pi.html", + "DisableAutomaticStates": true, "States": [ { "Image": "images/ha-button-off", diff --git a/src/components/ServiceCallConfiguration.vue b/src/components/ServiceCallConfiguration.vue index 9200910..f30a14f 100644 --- a/src/components/ServiceCallConfiguration.vue +++ b/src/components/ServiceCallConfiguration.vue @@ -71,10 +71,10 @@
Available options
- {{ item.name }} {{ item.info.description }} + {{ item.name }}  (required) {{ item.info.description }}
@@ -156,8 +156,10 @@ const domainEntities = computed(() => { return []; } let selectedService = props.availableServices.filter(service => service.serviceId === props.modelValue.serviceId)[0] - if (selectedService && selectedService.target && Array.isArray(selectedService.target.entity)) { - let targetDomains = selectedService.target.entity.filter(entity => entity.domain).flatMap(entity => entity.domain); + if (selectedService && selectedService.target && selectedService.target.entity) { + // target.entity may contain a single or an array of entities. Make sure we always work with array. + let targetEntities = ensureArray(selectedService.target.entity); + let targetDomains = targetEntities.filter(entity => entity.domain).flatMap(entity => ensureArray(entity.domain)); if (targetDomains.length > 0) { return props.availableEntities.filter(entity => targetDomains.includes(entity.domain)).sort(titleSort); } else { @@ -173,7 +175,11 @@ const serviceDataInvalidFeedback = computed(() => { return ""; } try { - const renderedServiceData = nunjucks.renderString(serviceDataString, {ticks: 5, rotationPercent: 100, rotationAbsolute: 100}); + const renderedServiceData = nunjucks.renderString(serviceDataString, { + ticks: 5, + rotationPercent: 100, + rotationAbsolute: 100 + }); const json = JSON.parse(renderedServiceData); return (typeof json === "object") ? "" : "Service data must be an JSON object." @@ -199,4 +205,8 @@ const dataProperties = computed(() => { }) +function ensureArray(input) { + return Array.isArray(input) ? input : [input]; +} + diff --git a/src/modules/homeassistant/actions/service-action.js b/src/modules/homeassistant/actions/service-action.js index b53f2e1..e0af640 100644 --- a/src/modules/homeassistant/actions/service-action.js +++ b/src/modules/homeassistant/actions/service-action.js @@ -22,15 +22,17 @@ export class ServiceAction extends Action { if (typeof service !== 'string' || !service.trim()) { throw new Error('Service must be a non-empty string') } - if (!Array.isArray(entity_id)) { + if (entity_id && !Array.isArray(entity_id)) { throw new TypeError('entity_id must be an array') } if (typeof serviceData !== 'object' || serviceData === null) { throw new TypeError('serviceData must be an object') } + if (entity_id) { + this.target = {entity_id: entity_id} + } this.service = `${domain}.${service}` this.data = serviceData - this.target = { entity_id: entity_id } } } diff --git a/src/modules/homeassistant/homeassistant.js b/src/modules/homeassistant/homeassistant.js index e4353b8..dc0c41d 100644 --- a/src/modules/homeassistant/homeassistant.js +++ b/src/modules/homeassistant/homeassistant.js @@ -91,7 +91,7 @@ export class Homeassistant { callService(service, domain, entity_id = null, serviceData = null, callback = null) { let executeScriptCmd = new ExecuteScriptCommand(this.nextRequestId(), [ - new ServiceAction(domain, service, entity_id ? [entity_id] : [], serviceData || {}) + new ServiceAction(domain, service, entity_id ? [entity_id]: null, serviceData || {}) ]) this.sendCommand(executeScriptCmd, callback) }