Skip to content

Commit

Permalink
feat: add defrost mode
Browse files Browse the repository at this point in the history
closes #62
  • Loading branch information
alandtse committed Apr 5, 2020
1 parent dafafc7 commit 9657222
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 2 deletions.
39 changes: 38 additions & 1 deletion teslajsonpy/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
https://github.com/zabuldon/teslajsonpy
"""
import time
from typing import Text
from typing import List, Optional, Text

from teslajsonpy.vehicle import VehicleDevice
from teslajsonpy.exceptions import UnknownPresetMode


class Climate(VehicleDevice):
Expand Down Expand Up @@ -43,6 +44,7 @@ def __init__(self, data, controller):
self.__passenger_temp_setting = None
self.__is_climate_on = None
self.__fan_status = None
self.__preset_mode: Text = None
self.__manual_update_time = 0

self.type = "HVAC (climate) system"
Expand Down Expand Up @@ -96,6 +98,10 @@ async def async_update(self, wake_if_asleep=False) -> None:
data["outside_temp"] if data["outside_temp"] else self.__outside_temp
)
self.__fan_status = data["fan_status"]
if data.get("defrost_mode") is not None:
self.__preset_mode = (
"defrost" if data.get("defrost_mode") == 1 else "normal"
)

async def set_temperature(self, temp):
"""Set both the driver and passenger temperature to temp."""
Expand Down Expand Up @@ -130,6 +136,37 @@ async def set_status(self, enabled):
self.__is_climate_on = False
await self.async_update()

async def set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode."""
if preset_mode not in self.preset_modes:
raise UnknownPresetMode(
f"{preset_mode} is not valid. Use {self.preset_modes}"
)
data = await self._controller.command(
self._id,
"set_preconditioning_max",
data={"on": preset_mode == "defrost"},
wake_if_asleep=True,
)
if data and data["response"]["result"]:
self.__preset_mode = preset_mode

@property
def preset_mode(self) -> Optional[str]:
"""Return the current preset mode, e.g., home, away, temp.
Requires SUPPORT_PRESET_MODE.
"""
return self.__preset_mode

@property
def preset_modes(self) -> Optional[List[str]]:
"""Return a list of available preset modes.
Requires SUPPORT_PRESET_MODE.
"""
return ["normal", "defrost"]

@staticmethod
def has_battery():
"""Return whether the device has a battery."""
Expand Down
6 changes: 6 additions & 0 deletions teslajsonpy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ class IncompleteCredentials(TeslaException):
"""Class of exceptions for incomplete credentials."""

pass


class UnknownPresetMode(TeslaException):
"""Class of exceptions for incomplete credentials."""

pass
3 changes: 2 additions & 1 deletion tests/tesla_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class TeslaMock:
def __init__(self, monkeypatch) -> None:
"""
Initialize mock.
Args:
monkeypatch (pytest.Monkeypatch): Monkeypatch.
"""
Expand Down Expand Up @@ -177,6 +177,7 @@ def command_ok():


RESULT_OK = {"response": {"reason": "", "result": True}}
RESULT_NOT_OK = {"response": {"reason": "", "result": False}}

# 408 - Request Timeout
RESULT_VEHICLE_UNAVAILABLE = {
Expand Down
29 changes: 29 additions & 0 deletions tests/unit_tests/test_climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from teslajsonpy.controller import Controller
from teslajsonpy.climate import Climate
from teslajsonpy.exceptions import UnknownPresetMode


def test_has_battery(monkeypatch):
Expand Down Expand Up @@ -34,6 +35,7 @@ def test_get_values_on_init(monkeypatch):
assert _climate.get_fan_status() is None
assert _climate.get_goal_temp() is None
assert _climate.is_hvac_enabled() is None
assert _climate.preset_mode is None


@pytest.mark.asyncio
Expand All @@ -57,6 +59,8 @@ async def test_get_values_after_update(monkeypatch):
assert _climate.get_goal_temp() == 21.6
assert not _climate.is_hvac_enabled() is None
assert not _climate.is_hvac_enabled()
assert _climate.preset_mode is not None
assert _climate.preset_mode == "normal"


@pytest.mark.asyncio
Expand Down Expand Up @@ -194,3 +198,28 @@ async def test_set_temperature(monkeypatch):

assert not _climate.get_goal_temp() is None
assert _climate.get_goal_temp() == 12.3


@pytest.mark.asyncio
async def test_set_preset_mode_no_success(monkeypatch):
"""Test set_temperature()."""

_mock = TeslaMock(monkeypatch)
_controller = Controller(None)

_data = _mock.data_request_vehicle()
_climate = Climate(_data, _controller)

await _climate.async_update()

preset_modes = _climate.preset_modes
for mode in preset_modes:
await _climate.set_preset_mode(mode)
assert _climate.preset_mode is not None
assert _climate.preset_mode == mode

with pytest.raises(UnknownPresetMode):
bad_modes = ["UKNOWN_MODE", "home", "auto", "away", "hot"]
for mode in bad_modes:
assert mode not in preset_modes
await _climate.set_preset_mode("mode")

0 comments on commit 9657222

Please sign in to comment.