nielsfaber / scheduler-component

Custom component for HA that enables the creation of scheduler entities
GNU General Public License v3.0
634 stars 41 forks source link

Invalid value for entity_id in service call in actions. #143

Closed denes44 closed 2 years ago

denes44 commented 2 years ago

Checklist

Expected behavior

I have two parameters to the esphome.aquarium_control_dose_fertilizer service call, 'pump' and 'amount'. Lovelace code:

type: custom:scheduler-card
title: Fertilizer Schedule
standard_configuration: false
discover_existing: false
show_header_toggle: true
groups:
  - name: Fertilizer Pumps
    icon: mdi:pump
    include:
      - switch.aquarium_fertilizer_1
customize:
  switch.aquarium_fertilizer_1:
    actions:
      - service: esphome.aquarium_control_dose_fertilizer
        name: Dose Fertilizer
        variables:
          amount:
            name: Amount
            min: 1
            max: 40
            unit: ' ml'
          pump:
            name: Dosing Pump
            options:
              - value: '1'
display_options:
  icon: entity
  primary_info:
    - '{entity}: {action}'
    - additional-tasks
  secondary_info:
    - '{days} {time}'
    - '{name}'

Am I doing something wrong on the Lovelace side?

Home Assistant version: core-2021.10.7 HACS version: 1.16.0 Both the Scheduler component and card are updated to the latest version.

Actual behavior

I'm getting the following error in Home Assistant, when the scheduler wants to run the scheduled action:

Home Assistant log:

2021-11-05 21:00:00 ERROR (MainThread) [homeassistant.util.logging] Exception in async_timer_finished when dispatching 'scheduler_timer_finished': ('22b562',)
Traceback (most recent call last):
File "/config/custom_components/scheduler/switch.py", line 251, in async_timer_finished
await self._action_handler.async_queue_actions(
File "/config/custom_components/scheduler/actions.py", line 203, in async_queue_actions
await self.async_process_queue()
File "/config/custom_components/scheduler/actions.py", line 248, in async_process_queue
res = await self.async_execute_action(action, conditions, condition_type)
File "/config/custom_components/scheduler/actions.py", line 292, in async_execute_action
await async_call_from_config(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 165, in async_call_from_config
await hass.services.async_call(**params, blocking=blocking, context=context)
File "/usr/src/homeassistant/homeassistant/core.py", line 1445, in async_call
processed_data = handler.schema(service_data)
File "/usr/local/lib/python3.9/site-packages/voluptuous/schema_builder.py", line 272, in __call__
return self._compiled([], data)
File "/usr/local/lib/python3.9/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
return base_validate(path, iteritems(data), out)
File "/usr/local/lib/python3.9/site-packages/voluptuous/schema_builder.py", line 432, in validate_mapping
raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: extra keys not allowed @ data['entity_id']
denes44 commented 2 years ago

I found this in the Lovelace Scheduler card manual: Actions are linked to their entities, so the entity ID is sent together with the service call, it is not needed to add it to the service_data). So that's the reason I have an extra parameter for the service call.

However after creating an entity_id parameter as a string for the service call, I get the following error:

2021-11-08 11:16:00 ERROR (MainThread) [homeassistant.util.logging] Exception in async_timer_finished when dispatching 'scheduler_timer_finished': ('7874a5',)
Traceback (most recent call last):
File "/config/custom_components/scheduler/switch.py", line 251, in async_timer_finished
await self._action_handler.async_queue_actions(
File "/config/custom_components/scheduler/actions.py", line 203, in async_queue_actions
await self.async_process_queue()
File "/config/custom_components/scheduler/actions.py", line 248, in async_process_queue
res = await self.async_execute_action(action, conditions, condition_type)
File "/config/custom_components/scheduler/actions.py", line 292, in async_execute_action
await async_call_from_config(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 165, in async_call_from_config
await hass.services.async_call(**params, blocking=blocking, context=context)
File "/usr/src/homeassistant/homeassistant/core.py", line 1445, in async_call
processed_data = handler.schema(service_data)
File "/usr/local/lib/python3.9/site-packages/voluptuous/schema_builder.py", line 272, in __call__
return self._compiled([], data)
File "/usr/local/lib/python3.9/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
return base_validate(path, iteritems(data), out)
File "/usr/local/lib/python3.9/site-packages/voluptuous/schema_builder.py", line 432, in validate_mapping
raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: value should be a string for dictionary value @ data['entity_id']

If I change the entity_id parameter to int, I get this: voluptuous.error.MultipleInvalid: expected int for dictionary value @ data['entity_id']

What kind of value this scheduler is trying to send to the service call?!

nielsfaber commented 2 years ago

scheduler will send:

service: esphome.aquarium_control_dose_fertilizer
data:
  entity_id: switch.aquarium_fertilizer_1

Because you defined the action under the switch.aquarium_fertilizer_1 entity.

denes44 commented 2 years ago

With some more testing, I figured out, that the scheduler is sending a string ARRAY for the enitity_id, not a string. Why is that? I never seen any service call, that works with a string array for the enitity_id.

nielsfaber commented 2 years ago

False statement, scheduler does not do as such. Otherwise it wouldn’t work for any action.

I don’t know what’s the problem, therefore I don’t know how to help you either.

denes44 commented 2 years ago

It's not false statement, the scheduler indeed does as such. If the entity_id parameter would be a string, why home assistant gives this error message then? voluptuous.error.MultipleInvalid: value should be a string for dictionary value @ data['entity_id'] It the value indeed would be a string, I would not get an error message saying that the value is not a string.

This is from the HA Developer Tools page, if the prameters of the service call look like this, it works, and I don't get an error message:

Parameter | Description | Example -- | -- | -- amount |   | 42 entity_id | A list of strings. | ['Example text', 'Another example']

If the enitity_id parameter is a string, I get an error message, that the entity_id should be a string, but it is not:

Parameter | Description | Example -- | -- | -- amount |   | 42 entity_id |   | Example text

Here is the log output from esphome, showing that the scheduler is indeed sending a string array, rather than a string as a parameter:

[16:46:00][VV][api.service:470]: on_execute_service_request: ExecuteServiceRequest {
  key: 4235795531
  args: ExecuteServiceArgument {
  bool_: NO
  legacy_int: 0
  float_: 0
  string_: ''
  int_: 1
}
  args: ExecuteServiceArgument {
  bool_: NO
  legacy_int: 0
  float_: 0
  string_: ''
  int_: 0
  string_array: 'switch.aquarium_fertilizer_3'
}
}
nielsfaber commented 2 years ago

I don’t use esphome so I cannot help you

denes44 commented 2 years ago

Since it's a service call, it does not matter whom provides the service call itself, so esphome is irrelevalt in this case.

You said scheduler does not do as such (sending a string array for the entity_id). It is "false statement", this is the HA event log, which shows that the scheduler is sending an array, with only one element:

Event 61 fired 21:57:
{
    "event_type": "call_service",
    "data": {
        "domain": "light",
        "service": "turn_on",
        "service_data": {
            "transition": 1,
            "entity_id": [
                "light.bedroom_led_light"
            ]
        }
    },
    "origin": "LOCAL",
    "time_fired": "2021-11-14T20:57:00.005257+00:00",
    "context": {
        "id": "799fcc13ba8a3a16a18cdb6290027fb3",
        "parent_id": null,
        "user_id": null
    }
}

I used the built in _light.turnon service call, so nobody could say that this is a problem with esphome.

nielsfaber commented 2 years ago

Scheduler does not send a transition time when turning on a light. It seems that you are using customized actions which cause problems, I think we should focus on that. Maybe you should try first if scheduler works OK without customizations (e.g. for toggling an input_boolean). The aforementioned claim regarding entity_id being treated as array is wrong and I don’t want to discuss it more.

denes44 commented 2 years ago

Yes, it was a custom action. Here is the service call from another scheduler card I just created, and included all input_boolean entities:

Event 1 fired 22:43:
{
    "event_type": "call_service",
    "data": {
        "domain": "input_boolean",
        "service": "turn_on",
        "service_data": {
            "entity_id": [
                "input_boolean.aquarium_manual_light_control"
            ]
        }
    },
    "origin": "LOCAL",
    "time_fired": "2021-11-14T21:43:00.006699+00:00",
    "context": {
        "id": "b6669642dd60ea0ec10815fcd8c6e611",
        "parent_id": null,
        "user_id": null
    }
}

As far as I can see, the entity_id is still an array... :)

nielsfaber commented 2 years ago

I tried the same, and for me the result is the same. However, I also added:

_LOGGER.debug(service_call)

at https://github.com/nielsfaber/scheduler-component/blob/main/custom_components/scheduler/actions.py#L291 to see what scheduler is actually sending.

The result is:

2021-11-15 07:14:00 DEBUG (MainThread) [custom_components.scheduler.actions] {'service': 'input_boolean.turn_on', 'data': {}, 'entity_id': 'input_boolean.scheduler_test'}

In other words, scheduler is not sending an array but Home Assistant processes it into an array. I think this is because in the Developer Tools -> Services panel you can pick multiple entities as target, but I'm not sure. So I guess you will see the same result when calling a service from automation or similar. Which means this cannot be changed by scheduler.

I could try changing the format of the service call and making use of the new target attribute, since this is nowadays the preferred way of passing entity_id, but I doubt it will make a difference.

nielsfaber commented 2 years ago

I could try changing the format of the service call and making use of the new target attribute, since this is nowadays the preferred way of passing entity_id, but I doubt it will make a difference.

It gives the same result.

denes44 commented 2 years ago

From Lovelace UI, Node-RED, automations, etc. the service call looks like this:

Event 2 fired 09:25:
{
    "event_type": "call_service",
    "data": {
        "domain": "light",
        "service": "turn_off",
        "service_data": {
            "transition": 1,
            "entity_id": "light.bedroom_led_light"
        }
    },
    "origin": "LOCAL",
    "time_fired": "2021-11-15T08:25:20.795831+00:00",
    "context": {
        "id": "71e5d993e83d74781af164138a2e20a5",
        "parent_id": null,
        "user_id": "381e460bf95b48ca96ead368ce94cebb"
    }
}

The same for the input_boolean as well. It doesn't turn into an array automatically.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days