-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Dacia Spring Support #459
Conversation
f3dora19
commented
Jan 3, 2022
- Add Dacia Spring Support
- Add Charge Pause/Resume endpoint
- Add fixtures
- Add tests
e888e30
to
15caeeb
Compare
Hello everybody, I made some changes on the api to be able to pause/resume dacia spring charge, but on the MyDacia application the only endpoint available to start the charge was totally different as the renault endpoint. |
I don't think using the brand label is the best way to differentiate between available endpoints. |
Also, in order to make it easier to review, could you please make at least two separate PRs?
|
Ok, differentiation is now pointing to the model code. But I do not understand the carGateway attribute, I don't find it in any code except for the duster fixtures, can you tell me more about it ? |
See #404 for carGateway. It is still work in progress... |
You should be able to run |
9f60fa0
to
3c11575
Compare
@epenet, yes, you've right I runned Just to inform you, I work on separate PRs like asked ! |
3c11575
to
6cad42d
Compare
* Add Dacia Spring charge pause/resume endpoint * Add tests
6cad42d
to
3eeb09e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that #480 is merged, you should be able to access the carGateway
property of the car adapter.
I suggest that you add a fixture for the carGateway of your dacia...
await vehicle.get_details() | ||
if ( | ||
vehicle._vehicle_details | ||
and vehicle._vehicle_details.get_model_code() == "XBG1VE" | ||
): |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the carGateway cannot be uses (it shows AVN also for the dacia spring), I suggest this:
await vehicle.get_details() | |
if ( | |
vehicle._vehicle_details | |
and vehicle._vehicle_details.get_model_code() == "XBG1VE" | |
): | |
details = await vehicle.get_details() | |
if details.get_model_code() == "XBG1VE": |
@afaucogney added the gateway details, and it seems that the dacia spring uses the same AVN gateway as the recent renault vehicles so I don't think we can use the carGateway to distinguish. |
Also, I have thought more about it and I think that you should move the logic to the VEHICLE_SPECIFICATIONS: Dict[str, Dict[str, Any]] = {
...
"XBG1VE": { # Dacia Spring
"charging-start-via-kcm": True,
},
} Then in def uses_endpoint_via_kcm(self, endpoint: str) -> bool:
"""Return True if model uses endpoint via kcm."""
# Default to False for unknown vehicles
if self.model and self.model.code:
return VEHICLE_SPECIFICATIONS.get(self.model.code, {}).get(
f"{endpoint}-via-kcm", True
)
return False # pragma: no cover |
* Modify tests * Modify Kamereon model Signed-off-by: Luc Viala <[email protected]>
There are some conflicts that need resolving. |
Hey @epenet, it will be very helpful if I can get a carGateway for the Spring, it could resolve lot of issues I get. |
To get the car gateway, you need to run this command: |
details = await vehicle.get_details() | ||
if details.get_model_code() == "XBG1VE": | ||
response = await vehicle.set_charge_pause_resume("resume") | ||
else: | ||
response = await vehicle.set_charge_start() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to keep the original method (simply set_charge_start) and move the logic there.
details = await vehicle.get_details() | |
if details.get_model_code() == "XBG1VE": | |
response = await vehicle.set_charge_pause_resume("resume") | |
else: | |
response = await vehicle.set_charge_start() | |
response = await vehicle.set_charge_start() |
details = await vehicle.get_details() | ||
if details.get_model_code() == "XBG1VE": | ||
response = await vehicle.set_charge_pause_resume("pause") | ||
click.echo(response.raw_data) | ||
else: | ||
response = None | ||
click.echo("Function unavailable") | ||
exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to simply create a new function against the vehicle, and make the check there (you can raise NotImplementedException for the other vehicles)
details = await vehicle.get_details() | |
if details.get_model_code() == "XBG1VE": | |
response = await vehicle.set_charge_pause_resume("pause") | |
click.echo(response.raw_data) | |
else: | |
response = None | |
click.echo("Function unavailable") | |
exit(1) | |
response = await vehicle.set_charge_stop() | |
click.echo(response.raw_data) |
return VEHICLE_SPECIFICATIONS.get(self.model.code, {}).get( | ||
f"{endpoint}-via-kcm", False | ||
) | ||
return False # pragma: no cover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are adding tests for this, so no need to exclude coverage:
return False # pragma: no cover | |
return False |
@@ -311,17 +320,28 @@ async def set_vehicle_action( | |||
vin: str, | |||
endpoint: str, | |||
attributes: Dict[str, Any], | |||
actions: str = "actions", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you add an argument in the middle of the list, it becomes a breaking change.
You have to add it at the bottom of the list to make it non-breaking (even with a default value).
I suggest:
attributes: Dict[str, Any],
endpoint_version: Optional[int] = None,
data_type: Optional[Dict[str, Any]] = None,
*,
car_adapter_type: str = "kca"
actions: str = "actions",
car_adapter_url = get_car_adapter_url( | ||
root_url=root_url, | ||
account_id=account_id, | ||
version=endpoint_version or _get_endpoint_version(ACTION_ENDPOINTS[endpoint]), | ||
vin=vin, | ||
) | ||
url = f"{car_adapter_url}/actions/{endpoint}" | ||
|
||
if actions == "charge": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to use a separate (new) argument to decide on the car_adapter_url:
if car_adapter_type == "kcm":
car_adapter_url = get_kcm_car_adapter_url(...
else:
car_adapter_url = get_car_adapter_url(...
async def set_charge_pause_resume( | ||
self, action: str | ||
) -> models.KamereonVehicleChargingStartActionData: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename to set_charge_stop. Then inside the function you check if uses_endpoint_via_kcm
, and send the correct request (pause or raise NotImplemented).
async def set_charge_pause_resume( | |
self, action: str | |
) -> models.KamereonVehicleChargingStartActionData: | |
async def set_charge_stop(self) -> models.KamereonVehicleChargingStartActionData: |
You can do the same in set_charge_start, which should check if uses_endpoint_via_kcm
, and send the correct request (kca start, or kcm resume).
Hi @lucviala |
Is this command correct? I get this with both my Renault vehicles and using both accounts (SFDC and MYRENAULT):
|