Skip to content

Commit

Permalink
feat(smartcar): get & set charge limit (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanPeterson1324 authored Apr 13, 2023
1 parent 98e5597 commit 8015c33
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
6 changes: 6 additions & 0 deletions smartcar/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ def format_capabilities(capabilities_list: List[dict]) -> List[Capability]:
[("is_plugged_in", bool), ("state", str), ("meta", namedtuple)],
)

ChargeLimit = NamedTuple("ChargeLimit", [("limit", float), ("meta", namedtuple)])

Battery = NamedTuple(
"Battery",
[("percent_remaining", float), ("range", float), ("meta", namedtuple)],
Expand Down Expand Up @@ -350,6 +352,9 @@ def select_named_tuple(path: str, response_or_dict) -> NamedTuple:
elif path == "location":
return Location(data["latitude"], data["longitude"], headers)

elif path == "charge/limit":
return ChargeLimit(data["limit"], headers)

elif path == "permissions":
return Permissions(
data["permissions"],
Expand All @@ -365,6 +370,7 @@ def select_named_tuple(path: str, response_or_dict) -> NamedTuple:
or path == "unlock"
or path == "start_charge"
or path == "stop_charge"
or path == "set_charge_limit"
):
return Action(data["status"], data["message"], headers)

Expand Down
33 changes: 33 additions & 0 deletions smartcar/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,22 @@ def attributes(self) -> types.Attributes:
response = helpers.requester("GET", url, headers=headers)
return types.select_named_tuple(path, response)

def get_charge_limit(self) -> types.ChargeLimit:
"""
GET Vehicle.get_charge_limit
Returns:
ChargeLimit = NamedTuple("ChargeLimit", [("limit", float), ("meta", namedtuple)])
Raises:
SmartcarException
"""
path = "charge/limit"
url = self._format_url(path)
headers = self._get_headers()
response = helpers.requester("GET", url, headers=headers)
return types.select_named_tuple(path, response)

# ===========================================
# Action (POST) Requests
# ===========================================
Expand Down Expand Up @@ -320,6 +336,23 @@ def stop_charge(self) -> types.Status:
)
return types.select_named_tuple("stop_charge", response)

def set_charge_limit(self, limit) -> types.Status:
"""
POST Vehicle.set_charge_limit
Returns:
Action: NamedTuple("Action", [("status", str), ("message", str), ("meta", rs.namedtuple)])
Raises:
SmartcarException
"""
url = self._format_url("charge/limit")
headers = self._get_headers(need_unit_system=False)
response = helpers.requester(
"POST", url, headers=headers, json={"limit": limit}
)
return types.select_named_tuple("set_charge_limit", response)

def batch(self, paths: List[str]) -> namedtuple:
"""
POST Vehicle.batch
Expand Down
4 changes: 3 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ def access_ford(client):
access_tesla namedtuple
"""
client = sc.AuthClient(*ah.get_auth_client_params())
code = ah.run_auth_flow(client.get_auth_url(["required:control_charge"]), "FORD")
code = ah.run_auth_flow(
client.get_auth_url(["required:read_charge", "required:control_charge"]), "FORD"
)
access = client.exchange_code(code)
yield access

Expand Down
14 changes: 14 additions & 0 deletions tests/e2e/test_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ def test_attributes(chevy_volt):
assert attributes._fields == ("id", "make", "model", "year", "meta")


def test_get_charge_limit(ford_car):
charge_limit = ford_car.get_charge_limit()
assert charge_limit is not None
assert type(charge_limit) == types.ChargeLimit
assert charge_limit._fields == ("limit", "meta")


def test_lock(chevy_volt):
response = chevy_volt.lock()
assert response.status == "success"
Expand Down Expand Up @@ -110,6 +117,13 @@ def test_stop_charge(ford_car):
assert response._fields == ("status", "message", "meta")


def test_set_charge_limit(ford_car):
response = ford_car.set_charge_limit(0.7)
assert response.status == "success"
assert type(response) == types.Action
assert response._fields == ("status", "message", "meta")


def test_batch_success(chevy_volt):
batch = chevy_volt.batch(["/odometer", "/location"])
assert batch is not None
Expand Down

0 comments on commit 8015c33

Please sign in to comment.