Hyundai-Kia-Connect / kia_uvo

A Home Assistant HACS integration that supports Kia Connect(Uvo) and Hyundai Bluelink. The integration supports the EU, Canada and the USA.
MIT License
426 stars 85 forks source link

IONIQ 5 (EUR): Scheduled departure as datetime object #720

Open kalaws opened 1 year ago

kalaws commented 1 year ago

Update: See below post for a way to get next departure as datetime object.


Thank you for the great work. Extremely useful.

My Data sensor includes reservInfo: day: item. I’m wondering if you could expose the data as a separate sensor? 1 is Monday, 7 is Sunday. Not sure how it is best presented? Datestamp? Separate sensor for each day of week? Either way, the point for me would be to match it to the present day of week to feed that info to an automation for charging.

IMG_7161

kalaws commented 1 year ago

Perhaps a sensor with one attribute for each day? Monday: True Tuesday: False And so on

kalaws commented 1 year ago

Perhaps the most reasonable way would be to expose a full timestamp of the next scheduled departure time, as indicated by the list of days. for instance, today the list would look as follows: Tuesday 2023/09/12 07:10:00 Wednesday 2023/09/13 07:10:00 Thursday 2023/09/14 07:10:00 Friday 2023/09/15 07:10:00 Monday 2023/09/18 07:10:00

State of sensor could be next scheduled departure as full timestamp. Rest of the list could be in attribute(s).

kalaws commented 1 year ago

Never mind, solved it by parsing the data in the following way, if anyone else tries to base automation off it:

{% set depday = state_attr('sensor.ioniq_5_data', 'vehicle_data').vehicleStatus.evStatus.reservChargeInfos.reservChargeInfo.reservChargeInfoDetail.reservInfo.day %}
{% set deptime = as_timestamp(strptime(states('sensor.ioniq_5_ev_first_scheduled_departure_time'), '%H:%M:%S')) | timestamp_custom('%H:%M:%S') %}
{% set bluelinknow = as_datetime((now().timestamp()+86400)|int | timestamp_local(True)) %}
{% set bluelinktomorrow = as_datetime((now().timestamp()+(86400*2))|int | timestamp_local(True)) %}
{% set nutid = as_timestamp(now()) | timestamp_custom('%H:%M:%S') %}

{% if bluelinknow.weekday() in depday and nutid <= deptime %}
  {% set sched = "on" %}
{% elif bluelinktomorrow.weekday() in depday and nutid >= deptime %}
  {% set sched = "on" %}
{% else %}
  {% set sched = "off" %}
{% endif %}
{{ sched }}

The bluelinknow is a correction of HA's now(), because in HA 0 is Monday, and in Bluelink 0 means Sunday. This way bluelinknow.weekday() can be used to check if today is listed among the scheduled weekdays.

My particular smart charging solution accepts only time of day as input, so my way might look convoluted to someone else. :)

kalaws commented 1 year ago

Here's a way to get the next scheduled departure as a datetime object, i.e., including date and time. I'm posting it since I guess more people will be interested. The whole replace() business is required because HA and Kia/Hyundai do not assume the same day of week as 0. There's probably a neater way of doing the replace - please post if you know of one.

{% set errdepday = state_attr('sensor.[YOURCAR]_data', 'vehicle_data').vehicleStatus.evStatus.reservChargeInfos.reservChargeInfo.reservChargeInfoDetail.reservInfo.day %}
{% set sched = states('binary_sensor.[YOURCAR]_ev_first_scheduled_departure') %}
{% set deptime = as_timestamp(strptime(states('sensor.[YOURCAR]_ev_first_scheduled_departure_time'), '%H:%M:%S')) | timestamp_custom('%H:%M:%S') %}

{% set depday = (errdepday|replace(6,7)|replace(0,6)|replace(1,0)|replace(2,1)|replace(3,2)|replace(4,3)|replace(5,4)|replace(7,5)|replace(', ','')|replace('[','')|replace("]",'')|replace("'",''))|list %}
{% set nutid = as_timestamp(now()) | timestamp_custom('%H:%M:%S') %}
{% if now().weekday() in depday|map('int') and nutid < deptime %}
  {% set startday = -1 %}
{% else %}
  {% set startday = 0 %}
{% endif %}
{% set ns = namespace(result=[]) %}
      {% for i in depday %}
      {% set days_delta = i|int - now().weekday() %}
      {% if days_delta <= startday %}
        {% set days_delta = days_delta + 7 %}
      {% endif %}

      {% set res = now() + timedelta(days_delta) %}
      {% set ns.result = ns.result + [(res.timestamp() | timestamp_custom('%Y-%m-%d '+deptime))] %}

      {% if not loop.last %}{% endif %}
      {%- endfor %}
{% set listan = ns.result | sort %}
  {{ as_datetime(listan[0]) }}

For second departure as datetime object, change the first three lines:

{% set errdepday = state_attr('sensor.[YOURCAR]_data', 'vehicle_data').vehicleStatus.evStatus.reservChargeInfos.reserveChargeInfo2.reservChargeInfoDetail.reservInfo.day %}
{% set sched = states('binary_sensor.[YOURCAR]_ev_second_scheduled_departure') %}
{% set deptime = as_timestamp(strptime(states('sensor.[YOURCAR]_ev_second_scheduled_departure_time'), '%H:%M:%S')) | timestamp_custom('%H:%M:%S') %}
cdnninja commented 1 year ago

Open to PRs. I don't own a Kia anymore so haven't done much on this.

kalaws commented 1 year ago

Sorry, I have no idea how to do this in proper code 😬