skodaconnect / homeassistant-skodaconnect

Skoda Connect - A home assistant plugin to add integration with your car
Apache License 2.0
233 stars 27 forks source link

Calling "skodaconnect.set_charge_limit" returns "Could not find associated coordinator for given vehicle" #246

Closed bkleif closed 11 months ago

bkleif commented 11 months ago

Describe the bug When calling the service "skodaconnect.set_charge_limit", it fails with "Could not find associated coordinator for given vehicle ".

I am just trying to call the service directly from developer tools. I have a Skoda Enyaq, and have also tried with other limits, such at 50.

service: skodaconnect.set_charge_limit data: device_id: 36xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxeae limit: 100

**Is this working in MySkoda app?*** Yes- but the app is so crap and unstable, it would be nice to do it from HA.

Latest working release I have not tried to call the service in previous releases. I am currently using 1.2.8

Debug logs

Traceback (most recent call last): File "/config/custom_components/skodaconnect/init.py", line 280, in get_car dev_coordinator = hass.data[DOMAIN][conf_entry]['data'].coordinator


KeyError: '23cba6bd0c353ca6262129f26f927648'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2067, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2104, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/skodaconnect/__init__.py", line 376, in set_charge_limit
    car = await get_car(service_call)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/skodaconnect/__init__.py", line 282, in get_car
    raise SkodaConfigException('Could not find associated coordinator for given vehicle')
skodaconnect.exceptions.SkodaConfigException: Could not find associated coordinator for given vehicle

**Installation:**
 - Hass OS 11.2, Core 2023.12.2

**Additional context**
The entities are working great, showing battery level, enabling climatisation and so on.
bkleif commented 11 months ago

Fixed the issue by deleting the helpers I had created which used sensors from the skodaconnect integration.

georgbachmann commented 9 months ago

I had the same issue. I added a template number entity (see following code) to be able to set it inside the UI and when I removed it, it worked calling the service from the developer tools.

template:
  - number:
      - name: enyaq_charge_limitation
        unique_id: "enyaq_charge_limitation"
        state: "{{ states('sensor.skoda_enyaq_minimum_charge_level') | int(0) }}"
        set_value:
          - service: skodaconnect.set_charge_limit
            data:
              limit: "{{ value | int(0) }}"
              device_id: <my-id>
        step: "10"
        min: "10"
        max: "100"

But the problem is that it only once. I did set it to 90 -> Send -> OK. Then changed it to 80 -> Send -> Error Or at least once per 20 seconds or so then it did work again once. In the logs I found this:

websocket_api script: Error executing script. Unexpected error for call_service at pos 1: Charging action already in progress
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 713, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 675, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/skodaconnect/__init__.py", line 380, in set_charge_limit
    state = await car.set_charge_limit(limit)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/skodaconnect/vehicle.py", line 534, in set_charge_limit
    return await self.set_charger(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/skodaconnect/vehicle.py", line 443, in set_charger
    raise SkodaRequestInProgressException('Charging action already in progress')
skodaconnect.exceptions.SkodaRequestInProgressException: Charging action already in progress

Seems that the API requests are taking that long? Or Skoda/VW has some limitations on how often they might get called?

This might also explain why the Skoda App is that crappy :D

Would be great to know how I can still have my number-template-entity so that I can have a slider of stepper or something similar.

Farfar commented 9 months ago

I had the same issue. I added a template number entity (see following code) to be able to set it inside the UI and when I removed it, it worked calling the service from the developer tools.

template:
  - number:
      - name: enyaq_charge_limitation
        unique_id: "enyaq_charge_limitation"
        state: "{{ states('sensor.skoda_enyaq_minimum_charge_level') | int(0) }}"
        set_value:
          - service: skodaconnect.set_charge_limit
            data:
              limit: "{{ value | int(0) }}"
              device_id: <my-id>
        step: "10"
        min: "10"
        max: "100"

But the problem is that it only once. I did set it to 90 -> Send -> OK. Then changed it to 80 -> Send -> Error Or at least once per 20 seconds or so then it did work again once. In the logs I found this:

websocket_api script: Error executing script. Unexpected error for call_service at pos 1: Charging action already in progress
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 713, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 675, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/skodaconnect/__init__.py", line 380, in set_charge_limit
    state = await car.set_charge_limit(limit)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/skodaconnect/vehicle.py", line 534, in set_charge_limit
    return await self.set_charger(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/skodaconnect/vehicle.py", line 443, in set_charger
    raise SkodaRequestInProgressException('Charging action already in progress')
skodaconnect.exceptions.SkodaRequestInProgressException: Charging action already in progress

Seems that the API requests are taking that long? Or Skoda/VW has some limitations on how often they might get called?

This might also explain why the Skoda App is that crappy :D

Would be great to know how I can still have my number-template-entity so that I can have a slider of stepper or something similar.

Some actions for older cars take a long time to complete, up to 3-5 minutes sometimes before some kind of timeout is reached in the backend if the vehicle doesn't respond. But it's also possible that the integration got hung up thinking there's a request still being processed. In that case a reload of the integration should help.

dvx76 commented 9 months ago

You can use the sensor.skoda_enyaq_request_results to determine if there's any ongoing request (which will cause any additional request to fail with Charging action already in progress).

I've wrapped the actions I use often in scripts which use that sensor to block until there's no more request in progress.

E.g.

alias: Skoda - Turn off Charging and Wait
sequence:
  - if:
      - condition: state
        entity_id: switch.tmbj......_charging
        state: "on"
    then:
      - type: turn_off
        device_id: e9d855c76d63e49117ae0d255699c12f
        entity_id: switch.tmbj......_charging
        domain: switch
      - delay:
          hours: 0
          minutes: 1
          seconds: 0
          milliseconds: 0
      - wait_template: "{{ is_state('sensor.skoda_enyaq_request_results', 'Success') }}"
        continue_on_timeout: true
        timeout: "300"
mode: single
icon: mdi:battery-clock-outline
georgbachmann commented 9 months ago

Ok, I see! I hope my 2023 Skoda ist not yet "old" @Farfar :) It's about half a year... I'll try that script, as I guess I can queue up scripts, right? So the slider might work again then? I'll give it a go in the evening! Thanks guys for your quick help! Cause doing the queuing and proper deduplication (like if I sent the e.g set_charge_limit with first 60, then 70, then 80 and while it's waiting for the 60 to process, just skip the 70 all together as the 80 will override it anyway) in the integration itself? Would that not be better? Btw. @dvx76 I don't know how sensitive the device_id is, but in samples I've seen previously it was always obscured... so you might want to update your sample to remove it?!? I don't know it it's sensitive or not... just a thought :)

dvx76 commented 9 months ago

I can queue up scripts, right?

Yes, that's what the mode does in the script config. https://www.home-assistant.io/integrations/script/#script-modes

So the slider might work again then?

I gave up having a slider for setting the charge limit, partially for this. I just have buttons for 60,70,80,90 and 100 in a row, with confirmation on tap_action.

while it's waiting for the 60 to process, just skip the 70 all together as the 80 will override it anyway) in the integration itself?

No. At best the integration will raise a Charging action already in progress error. You can potentially achieve this with a script with mode: restart which starts by waiting until any current request has completed (by inspecting sensor.skoda_enyaq_request_results)

I don't know how sensitive the device_id

It's fine as far as I know. It's just an internal ID in HA. It's the VIN, which appears in sensor names, which I don't like being public.