renault-api icon indicating copy to clipboard operation
renault-api copied to clipboard

Support hvac-settings and hvac-schedule endpoint

Open Nebukadneza opened this issue 5 years ago • 13 comments

Thank you for this very clean and well-structured API package.

I’ve been looking at how it might be possible to modify the HVAC-schedule of a Zoe PH2 (same UI as charging schedule in the car). From an enduser-perspective, this is important, since HVAC schedules from the app are only executed if "hvac=program" mode is selected in the car. However, the user would always need to have one active program selected in the car, and has to remember to "shift it around" so it doesn’t trigger needlessly. If renault-api would support this endpoint, the user could have a cronjob that shifts a dummy-schedule forward by one day every day. That way the car can stay in "hvac=program" mode, with one always-active program that does not do any damag …

By decompiling the app, I found the endpoint to write this to be:

POST /commerce/v1/accounts/xxx/kamereon/kca/car-adapter/v2/cars/xxx/actions/hvac-schedule?country=xx

With the data almost the same as charging schedules, except for readyAtTime instead of startTime in the days definitions:

{'schedules': [{'id': 1,
   'activated': True,
   'friday': {'readyAtTime': 'T11:00Z'}},
  {'id': 2, 'activated': False},
  {'id': 3, 'activated': False},
  {'id': 4, 'activated': False},
  {'id': 5, 'activated': True, 'wednesday': {'readyAtTime': 'T15:15Z'}}]}

The return value, just with the charging schedule, looks like:

{'data': {'type': 'HvacSchedule',
  'id': '6344d356-4e78-4f89-981b-fa2eac98a251',
  'attributes': {'schedules': [{'id': 1,
     'activated': True,
     'friday': {'readyAtTime': 'T11:00Z'}},
    {'id': 2, 'activated': False},
    {'id': 3, 'activated': False},
    {'id': 4, 'activated': False},
    {'id': 5, 'activated': True, 'wednesday': {'readyAtTime': 'T15:15Z'}}]}}}

Similarly, the endpoint for reading this is:

GET /commerce/v1/accounts/xxx/kamereon/kca/car-adapter/v1/cars/xxx/hvac-settings?country=xx

Returning:

{'dateTime': '2020-12-05T13:36:14.562Z',
 'mode': 'scheduled',
 'schedules': [{'id': 1,
   'activated': True,
   'friday': {'readyAtTime': 'T11:00Z'}},
  {'id': 2, 'activated': False},
  {'id': 3, 'activated': False},
  {'id': 4, 'activated': False},
  {'id': 5, 'activated': True, 'wednesday': {'readyAtTime': 'T15:15Z'}}]}

I have started to try to get this into renault-api, but as I need some time to familiarize myself with how the data-model is structured, expect me to need a while. I wanted to post my finding here anyways, in case someone is quicker than me :relaxed: .

Thanks, -Dario

Nebukadneza avatar Dec 05 '20 13:12 Nebukadneza

Would this be fine?

 renault-api/ > poetry run renault-api ac-schedule 
Usage: renault-api ac-schedule [OPTIONS] COMMAND [ARGS]...

  Show or edit AC schedules.

Options:
  --help  Show this message and exit.

Commands:
  activate    Activate the schedule by 'id', where 'id' is in 1..5.
  deactivate  Deactivate the schedule by 'id', where 'id' is in 1..5.
  show        Show the currently configured schedule.
  ¿set?       Set a schedule entry at the given day and time, for the given schedule 'id'
  ¿unset?     Unset the entry scheduled at a given day and time, for the given schedule 'id'
--[ dario@yajirou ]---[ /home/dario/source/renault-api ]-------------------------------------------------------------------------------
 renault-api/ > poetry run renault-api ac-schedule show
Schedule mode is: scheduled
  Nr.  Active    Monday    Tuesday    Wednesday    Thursday    Friday    Saturday    Sunday
-----  --------  --------  ---------  -----------  ----------  --------  ----------  --------
    1  True      ---       ---        ---          ---         T11:00Z   ---         ---
    2  False     ---       ---        ---          ---         ---       ---         ---
    3  False     ---       ---        ---          ---         ---       ---         ---
    4  False     ---       ---        ---          ---         ---       ---         ---
    5  False     ---       ---        T15:15Z      ---         ---       ---         ---

I managed to get the printout somewhat usable, but I’m still struggling a bit with activation/deactivation. Didn’t look at tests so far, but of course planning to provide them once this is PR-worthy …

Nebukadneza avatar Dec 05 '20 19:12 Nebukadneza

There should be at least two separate PRs: one for the API and then a second one for the CLI.

The CLI is still work in progress - so not 100% sure on what we are going to end of with on that front. I'm for sure open to ideas. Did you look at #76 ?

epenet avatar Dec 05 '20 19:12 epenet

Fully agree on separating the API-layer and CLI work! Using the CLI to familiarize myself with the system and "toy around" was just a lot more convenient, given it’s automagic, credential-storage, etc. — for that reason I started my prototype on top of the add_cli branch. It should be easy to separate the 2 later on though.

Will report back when I have more ^_^

Nebukadneza avatar Dec 05 '20 20:12 Nebukadneza

Side-question: Does anyone happen to know what’s up with the weird time-format of both charge- and hvac schedules? It seems to be ISO 8601 "military zulu" (T<24h>:<min>Z), but i couldn’t find any timezone-conversion code in the app. I suspect at least the "zulu"(=UTC) part is a lie, and the time is going to be forwarded verbatim to the car, which interprets it as current localtime (i.e., with whatever DST rule is currently inplace) without any conversion.

Nebukadneza avatar Dec 06 '20 08:12 Nebukadneza

@Nebukadneza most of the original work is based on PyZE module. You can check here how he implement timezone conversions.

Regarding the CLI, this is how PyZE had it implemented on the charge scheduling: $ pyze schedule edit --friday 1530,30

epenet avatar Dec 06 '20 11:12 epenet

Second note: my charge schedule is currently blocked on Renault (I have a ticket open with them) and I use mostly "delayed start" mode but what I did notice at the end of October was that my default delayed start at 00:30 automatically got bumped to 23:30 so I think the timezone conversion might be required.

In which country are you based?

epenet avatar Dec 06 '20 11:12 epenet

Thanks for the link to pyze. I’ve just tried to verify with my car: I’m in Europe/Berlin which is UTC+1 or UTC+2 — Currently +1. The times I send via API are rendered 1:1 in the app, and on the cars EasyLink UI. I.e., if i send T11:00Z, the app and car show "Today, at 11:00". However, I don’t know what TZ the car is set to, and I can’t find a setting to verify/change this.

Since there should have been an offset of either 1 or 2 hours in some direction, this leads me to either "the car incorrectly interprets the zulu-timestamp as localtime" or "we don’t know enough". pyze seems to have taken the other assumption, and converts timestamps. Given the … uh … "quality" of renault software, I’m really unsure what to believe — both are plausible. More input needed, probably.

Nebukadneza avatar Dec 11 '20 13:12 Nebukadneza

In my opinion:

  • the Kamereon API (in src\kamereon\xxx.py) should never do any conversion and keep the UTC/Zulu times.
  • the Renault API (in src\renault_xxx.py) also shouldn't make any changes and should expect all timings to already be UTC/Zulu times.

However:

  • on display, the CLI should display times converted to local (maybe we add a utc flag to keep the UTC format)
  • on set, the CLI should convert to UTC if they are passed as hh:mm but keep them as they are if passed as Thh:mmZ

Since currently you are not implementing the CLI it is OK to not make any conversions

epenet avatar Dec 11 '20 14:12 epenet

@Nebukadneza I have written a small script that "shifts around an entry" in the air-conditioning program. https://gist.github.com/littleyoda/c982a6cd3136d7f6e785a81d9b3a5ad2

littleyoda avatar Dec 12 '21 21:12 littleyoda

Hi @littleyoda,

Thanks for the pointer and script. I have something similar which I use since a while: https://github.com/Nebukadneza/ze-schedule-shifter The quality is not that great, but the deployment style fits my needs very well.

Yours is great too, being rather more flexible …. :+1:

Nebukadneza avatar Dec 13 '21 10:12 Nebukadneza

Feel free to add a PR to this repo

epenet avatar Dec 13 '21 11:12 epenet

Hi @epenet,

I feel like this functionality of the 2 small projects shown doesn’t really belong here. We could, however, add a Projects using renault-api section in README.md, if you are in favor of that …?

Nebukadneza avatar Dec 13 '21 13:12 Nebukadneza

I totally agree with you. PR doesn't really make sense. I also only posted the link so that other people who have the same problem have a solution approach. The link here is enough for me.

littleyoda avatar Dec 13 '21 13:12 littleyoda