Closed rikroe closed 1 year ago
Base: 100.00% // Head: 100.00% // No change to project coverage :thumbsup:
Coverage data is based on head (
04e2b82
) compared to base (3e1bb9e
). Patch coverage: 100.00% of modified lines in pull request are covered.
:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.
Probably doesn't work with i3?
Probably doesn't work with i3?
trigger_charging_profile_update(charging_mode, precondition_climate)
should work with all (PH)EVs.
From what I understand from #440, you should be able to start/stop charging by working with charing windows and immediate/delayed charging.
I've tested all commands (iX driver), but only the trigger_charge_start and trigger_charge_stop succeeded. The start command failed once with the following error, but succeeded after a retry. I'm guessing this is caused by the fact that I triggered a stop command not soon before, IIRC the app gives the user a message then saying it can't process new remote commands yet.
Remote service failed with state 'ERROR'. Response: {'eventStatus': 'ERROR', 'errorDetails': {'title': None, 'description': None, 'presentationType': 'DIALOG', 'iconId': None, 'isRetriable': False, 'errorDetails': 'CHARGING_NOT_STARTED'}}
On the other two I get bad requests using the following commands:
result = asyncio.run(vehicle.remote_services.trigger_charging_settings_update(80, 16))
and
result = asyncio.run(vehicle.remote_services.trigger_charging_profile_update("DELAYED_CHARGING", "false"))
Is there more information I can provide to help?
@rikroe I added some change requests to your PR. The trigger_charging_profile_update was serializing already serialized (json) data. As a result I was getting bad request errors in my tests. After these changes, the trigger succeeds. I'm checking the charging_settings now.
I'm delighted that this pr exists. But as I'm not a proficient in python I tried it out with my BMW i3 no rex and using the commandline: bimmerconnected chargingprofile --charging-mode DELAYED_CHARGING user password region vin
it always responded in a http400 response like this:
DEBUG:asyncio:Using selector: KqueueSelector
DEBUG:bimmer_connected.account:Getting vehicle list
DEBUG:bimmer_connected.account:Getting vehicle list
DEBUG:bimmer_connected.api.authentication:Authenticating with MyBMW flow for North America & Rest of World.
DEBUG:httpx._client:HTTP Request: GET https://cocoapi.bmwgroup.com/eadrax-ucs/v1/presentation/oauth/config "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: POST https://customer.bmwgroup.com/gcdm/oauth/authenticate "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: POST https://customer.bmwgroup.com/gcdm/oauth/authenticate "HTTP/1.1 302 Found"
DEBUG:httpx._client:HTTP Request: POST https://customer.bmwgroup.com/gcdm/oauth/token "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: GET https://cocoapi.bmwgroup.com/eadrax-vcs/v4/vehicles "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: GET https://cocoapi.bmwgroup.com/eadrax-vcs/v4/vehicles "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: GET https://cocoapi.bmwgroup.com/eadrax-vcs/v4/vehicles/state "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: GET https://cocoapi.bmwgroup.com/eadrax-crccs/v2/vehicles?fields=charging-profile&has_charging_settings_capabilities=false "HTTP/1.1 200 OK"
DEBUG:bimmer_connected.vehicle.remote_services:Triggering remote service <Services.CHARGING_PROFILE: 'CHARGING_PROFILE'> with params None and data {"chargingMode": {"chargingPreference": "CHARGING_WINDOW", "endTimeSlot": "0001-01-01T12:00:00.000", "startTimeSlot": "0001-01-01T11:59:00.000", "type": "TIME_SLOT", "timerChange": "NO_CHANGE"}, "departureTimer": {"type": "WEEKLY_DEPARTURE_TIMER", "weeklyTimers": [{"daysOfTheWeek": ["MONDAY"], "id": 1, "time": "0001-01-01T12:00:00.000", "timerAction": "ACTIVATE"}, {"daysOfTheWeek": [], "id": 2, "time": "0001-01-01T18:00:00.000", "timerAction": "DEACTIVATE"}, {"daysOfTheWeek": [], "id": 3, "time": "0001-01-01T15:00:00.000", "timerAction": "DEACTIVATE"}, {"daysOfTheWeek": ["MONDAY"], "id": 4, "time": "0001-01-01T12:00:00.000", "timerAction": "DEACTIVATE"}]}, "isPreconditionForDepartureActive": false, "servicePack": "ATM"}
DEBUG:httpx._client:HTTP Request: POST https://cocoapi.bmwgroup.com/eadrax-crccs/v1/vehicles/WBYXXXXXXXX/charging-profile "HTTP/1.1 400 Bad Request"
Traceback (most recent call last):
File "/Users/jolly/Desktop/bimmer_connected/./bin/bimmerconnected", line 10, in <module>
sys.exit(main())
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/bimmer_connected/cli.py", line 356, in main
loop.run_until_complete(args.func(args))
File "/opt/homebrew/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/bimmer_connected/cli.py", line 240, in chargingprofile
status = await vehicle.remote_services.trigger_charging_profile_update(
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/bimmer_connected/vehicle/remote_services.py", line 281, in trigger_charging_profile_update
return await self.trigger_remote_service(
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/bimmer_connected/vehicle/remote_services.py", line 124, in trigger_remote_service
response = await client.post(
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_client.py", line 1848, in post
return await self.request(
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_client.py", line 1533, in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_client.py", line 1620, in send
response = await self._send_handling_auth(
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_client.py", line 1648, in _send_handling_auth
response = await self._send_handling_redirects(
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_client.py", line 1706, in _send_handling_redirects
raise exc
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_client.py", line 1688, in _send_handling_redirects
await hook(response)
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/bimmer_connected/api/client.py", line 69, in raise_for_status_event_handler
response.raise_for_status()
File "/Users/jolly/Desktop/bimmer_connected/lib/python3.10/site-packages/httpx/_models.py", line 749, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://cocoapi.bmwgroup.com/eadrax-crccs/v1/vehicles/WBYXXXXXXXX/charging-profile'
For more information check: https://httpstatuses.com/400
I've tried manually changing the servicePack to TBC1 ( like in the example responses ) in the source code but that did not help. Am I doing something wrong ? Or does it only work in the library not on the command line ?
I've tried manually changing the servicePack to TBC1 ( like in the example responses ) in the source code but that did not help. Am I doing something wrong ? Or does it only work in the library not on the command line ?
@jollyjinx that's the same problem I experienced. You need to make the changes I listed above locally in your files. Then when you run the cmdline, it works. (Not sure if I'm allowed or should commit the changes to the codebase myself, hence why I added several change requests.)
I've attached my changes in this zip file: bimmer_connected.zip. Unpack it in the bimmer_connected/bimmer_connected dir, so it can replace the 2 files.
Thanks @kriscremers for your debugging, really missed something there and pretty sure you found it. I'll review it this evening.
So if you're a little patient, you'll also get an new beta release making it easier to try out.
I've attached my changes in this zip file: bimmer_connected.zip. Unpack it in the bimmer_connected/bimmer_connected dir, so it can replace the 2 files.
@kriscremers I've replaced the files with the ones you provided, but it still has the same error. Neither --charging-mode DELAYED_CHARGING nor --charging-mode IMMEDIATE_CHARGING work.
Hey @kriscremers thanks again for pointing me to the issue regarding JSON formatting! Implemented it a little bit differently, the magic basically is in 452d541.
MyBMWJSONEncoder
) to make sure every object that we send can be converted into JSONhttpx.request(json=...)
, this will always encode the value given as JSON again, basically encoding the string that already is a valid JSON again. This of course leads to the data not being directly parseable anymoredata=
content=
and set the content-type
manually if we want to send JSON data, as no additional conversion takes placeI thought this shouldn't be able to occur as I thought I tested the parseability of the requests (and their completeness). However my mocked functions for the new request types were never called, so no parsing done...
This has been fixed as well now.
EDIT: Just released 0.13.0b2, so please try again :)
@rikroe aha, I didn't consider that, despite that fact that I often enough run against the same problems in dotnet where json is serialized in the http request call itself as well. This solution looks a lot cleaner than my quick hack, though. 😁
I also just finished testing the entire set of functionality, after having to reset the car's iDrive as it wasn't syncing again. Everything appears to be working straight out of the box as far as my tests show. 👍
Amazing and thanks for testing! Looks like we're finally close 😁
I'd like to see another test of an EV/PHEV without the full functionality, but then we should be good!
Success! - 👍 with commit 35a15b0 it now works switching between intermediate and delayed mode on my BMW i3 (no rex) Great work , Thanx a lot. I now can prevent charging more than I want on my underground parking garage.
Great work guys! Will this feature be available in Home Assitant integration as well?
Great work guys! Will this feature be available in Home Assitant integration as well?
If course! Although it will take at least a month (or more) to get it reviewed and merged. But I do have the basics ready.
Confirmed this worked on a Mini Electric too. Thanks! (Notably the charging immediate/delayed)
@gerard33 any chance we can see the start/stop charging functionality in the ha_custom_component soon?
The start/stop charging functionality is available in HA (without custom component) since 2023.5.0 and also in the latest version of the custom component.
Check for the select
entity.
@rikroe I'm running v2023.5.3 but I don't see it available. The only available entities are for the charging limit and mode:
I mean the commands trigger_charge_start() and trigger_charge_stop().
Looks like your car doesn't support this. My car neither but I can use delayed and immediate charging, which works fine in my case.
@gerard33 it does, I've tested and used these commands through python scripts. (See my comments above in this topic.) I can even drive this functionality over the BMW app.
I just did a quick search in the ha component and I can't find the start/stop trigger at all. Which is my point, it seems to be missing?
ha_custom_component: https://github.com/search?q=repo%3Abimmerconnected%2Fha_custom_component%20trigger_charge_start&type=code
bimmer_connected: https://github.com/search?q=repo%3Abimmerconnected%2Fbimmer_connected+trigger_charge_start&type=code
I think we never added it because we received feedback somewhere that it is not working properly. But that was before we understood more on the capabilities.
As soon as https://github.com/home-assistant/core/pull/92962 gets merged, we probably can also provide a switch entity to HA for those triggering charging start/stop.
@rikroe that would be great. The start/stop would make it easier to work with dynamic pricing tariffs along with solar energy production.
For now, you should be able to adjust that based on the charging mode select: DELAYED_CHARGING means don't charge if you don't have a charging plan for this moment.
@rikroe that isn't something I plan on using, since I don't only charge at home. If I start using delayed charging I'll need to switch every time I charge on the go, plus I'd still be unable to set the window to charge in.
Edit: just remembered I can call the start/stop functionality through python as well. Will give that a whirl for now.
The switch entity for charging on/off is included in 2023.6. If there are any problems, please open a new issue.
Breaking change
The
RemoteServices.trigger_charge_now()
service is renamed toRemoteServices.trigger_charge_start()
.Proposed change
Add remote services for electric vehicles:
trigger_charge_start()
(instead oftrigger_charge_now()
, uses new endpoint)trigger_charge_stop()
trigger_charging_settings_update(target_soc, ac_limit)
(many thanks @fredriklj for the traffic capture)trigger_charging_profile_update(charging_mode, precondition_climate)
(many thanks @RutgerBeyen for the traffic capture)All remote services have been refactored to include checks against the vehicle capabilities (provided in the
state
API). If your vehicle does not support a service, aValueError
will be raised. For example, not all EVs will support charging start/stop - it seems that you need an ID8 head unit for this (e.g. i4, i7, iX, but not iX3).Type of change
Additional information
Checklist