Skip to content

Commit

Permalink
Merge pull request #10 from Leggin/support-for-older-python-versions
Browse files Browse the repository at this point in the history
Support for older python versions
  • Loading branch information
Leggin authored Apr 26, 2023
2 parents da9bc4e + 2610c29 commit fc84df4
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 45 deletions.
11 changes: 8 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "dirigera"
version = "0.1.3"
version = "0.1.4"
description = "An unofficial Python client for controlling the IKEA Dirigera Smart Home Hub"
readme = "README.md"
authors = [{ name = "Leggin", email = "[email protected]" }]
Expand All @@ -17,9 +17,14 @@ dependencies = [
"requests >= 2.22.0",
"websocket-client >= 1.0.0",
]
requires-python = ">=3.10"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
Expand Down
13 changes: 13 additions & 0 deletions run-python-versions-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
declare -a arr=("3.7" "3.8" "3.9" "3.10" "3.11" "3.12")
set -e
set -o pipefail
for i in "${arr[@]}"
do
echo "$i"
docker run -v ~/src/dirigera:/dirigera python:"$i"-slim /bin/bash -c "
cd /dirigera
pip install -r requirements.txt > /dev/null
pip install -r dev-requirements.txt > /dev/null
bash run-test.sh"

done
13 changes: 7 additions & 6 deletions src/dirigera/devices/device.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
from typing import Optional, List


@dataclass
Expand All @@ -7,9 +8,9 @@ class Device:
custom_name: str
room_id: str
room_name: str
firmware_version: str | None
hardware_version: str | None
model: str | None
manufacturer: str | None
serial_number: str | None
can_receive: list[str]
firmware_version: Optional[str]
hardware_version: Optional[str]
model: Optional[str]
manufacturer: Optional[str]
serial_number: Optional[str]
can_receive: List[str]
8 changes: 4 additions & 4 deletions src/dirigera/devices/environment_sensor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Any
from typing import Any, Dict

from .device import Device
from ..hub.abstract_smart_home_hub import AbstractSmartHomeHub
Expand All @@ -18,7 +18,7 @@ class EnvironmentSensor(Device):

def refresh(self) -> None:
data = self.dirigera_client.get(route=f"/devices/{self.device_id}")
attributes: dict[str, Any] = data["attributes"]
attributes: Dict[str, Any] = data["attributes"]
self.firmware_version = attributes["firmwareVersion"]
self.current_temperature = attributes["currentTemperature"]
self.current_rh = attributes["currentRH"]
Expand All @@ -37,9 +37,9 @@ def set_name(self, name: str) -> None:


def dict_to_environment_sensor(
data: dict[str, Any], dirigera_client: AbstractSmartHomeHub
data: Dict[str, Any], dirigera_client: AbstractSmartHomeHub
):
attributes: dict[str, Any] = data["attributes"]
attributes: Dict[str, Any] = data["attributes"]
return EnvironmentSensor(
dirigera_client=dirigera_client,
device_id=data["id"],
Expand Down
22 changes: 11 additions & 11 deletions src/dirigera/devices/light.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
from enum import Enum
from typing import Any
from typing import Any, Optional, Dict

from .device import Device

Expand All @@ -19,17 +19,17 @@ class Light(Device):
dirigera_client: AbstractSmartHomeHub
is_reachable: bool
is_on: bool
startup_on_off: StartupEnum | None
light_level: int | None
color_temp: int | None
color_temp_min: int | None
color_temp_max: int | None
color_hue: int | None
color_saturation: float | None
startup_on_off: Optional[StartupEnum]
light_level: Optional[int]
color_temp: Optional[int]
color_temp_min: Optional[int]
color_temp_max: Optional[int]
color_hue: Optional[int]
color_saturation: Optional[float]

def refresh(self) -> None:
data = self.dirigera_client.get(route=f"/devices/{self.device_id}")
attributes: dict[str, Any] = data["attributes"]
attributes: Dict[str, Any] = data["attributes"]
self.device_id = data["id"]
self.is_reachable = data["isReachable"]
self.custom_name = attributes["customName"]
Expand Down Expand Up @@ -119,8 +119,8 @@ def set_startup_behaviour(self, behaviour: StartupEnum) -> None:
self.startup_on_off = behaviour


def dict_to_light(data: dict[str, Any], dirigera_client: AbstractSmartHomeHub):
attributes: dict[str, Any] = data["attributes"]
def dict_to_light(data: Dict[str, Any], dirigera_client: AbstractSmartHomeHub):
attributes: Dict[str, Any] = data["attributes"]

return Light(
dirigera_client=dirigera_client,
Expand Down
14 changes: 7 additions & 7 deletions src/dirigera/hub/abstract_smart_home_hub.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import abc
from typing import Any
from typing import Any, Dict, List


class AbstractSmartHomeHub(abc.ABC):
@abc.abstractmethod
def patch(self, route: str, data: dict[str, Any]) -> dict[str, Any]:
def patch(self, route: str, data: Dict[str, Any]) -> Dict[str, Any]:
raise NotImplementedError

@abc.abstractmethod
def get(self, route: str) -> dict[str, Any]:
def get(self, route: str) -> Dict[str, Any]:
raise NotImplementedError


class FakeDirigeraHub(AbstractSmartHomeHub):
def __init__(self) -> None:
self.patch_actions: list = []
self.get_actions: list = []
self.patch_actions: List = []
self.get_actions: List = []

def patch(self, route: str, data: dict[str, Any]) -> dict[str, Any]:
def patch(self, route: str, data: Dict[str, Any]) -> Dict[str, Any]:
self.patch_actions.append({"route": route, "data": data})

def get(self, route: str) -> dict[str, Any]:
def get(self, route: str) -> Dict[str, Any]:
self.get_actions.append({"route": route})
26 changes: 13 additions & 13 deletions src/dirigera/hub/hub.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ssl
from typing import Any
from typing import Any, Dict, List
import requests
import websocket
from urllib3.exceptions import InsecureRequestWarning
Expand Down Expand Up @@ -39,14 +39,14 @@ def headers(self):

def create_event_listener(
self,
on_open: Any | None = None,
on_message: Any | None = None,
on_error: Any | None = None,
on_close: Any | None = None,
on_ping: Any | None = None,
on_pong: Any | None = None,
on_data: Any | None = None,
on_cont_message: Any | None = None,
on_open: Any = None,
on_message: Any = None,
on_error: Any = None,
on_close: Any = None,
on_ping: Any = None,
on_pong: Any = None,
on_data: Any = None,
on_cont_message: Any = None,
):
wsapp = websocket.WebSocketApp(
self.websocket_base_url,
Expand All @@ -63,7 +63,7 @@ def create_event_listener(

wsapp.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

def patch(self, route: str, data: dict[str, Any]) -> dict[str, Any]:
def patch(self, route: str, data: Dict[str, Any]) -> Dict[str, Any]:
response = requests.patch(
f"{self.api_base_url}{route}",
headers=self.headers(),
Expand All @@ -74,7 +74,7 @@ def patch(self, route: str, data: dict[str, Any]) -> dict[str, Any]:
response.raise_for_status()
return response.text

def get(self, route: str) -> dict[str, Any]:
def get(self, route: str) -> Dict[str, Any]:
response = requests.get(
f"{self.api_base_url}{route}",
headers=self.headers(),
Expand All @@ -84,7 +84,7 @@ def get(self, route: str) -> dict[str, Any]:
response.raise_for_status()
return response.json()

def get_lights(self) -> list[Light]:
def get_lights(self) -> List[Light]:
"""
Fetches all lights registered in the Hub
"""
Expand All @@ -102,7 +102,7 @@ def get_light_by_name(self, lamp_name: str) -> Light:
raise AssertionError(f"No light found with name {lamp_name}")
return lights[0]

def get_environment_sensors(self) -> list[EnvironmentSensor]:
def get_environment_sensors(self) -> List[EnvironmentSensor]:
"""
Fetches all environment sensors registered in the Hub
"""
Expand Down
3 changes: 2 additions & 1 deletion tests/test_environment_sensor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Dict
import pytest
from src.dirigera.hub.abstract_smart_home_hub import FakeDirigeraHub
from src.dirigera.devices.environment_sensor import (
Expand Down Expand Up @@ -71,7 +72,7 @@ def test_set_name(fake_sensor: EnvironmentSensor, fake_client: FakeDirigeraHub):
assert fake_sensor.custom_name == new_name


def test_dict_to_sensor(fake_client: FakeDirigeraHub, sensor_dict: dict):
def test_dict_to_sensor(fake_client: FakeDirigeraHub, sensor_dict: Dict):
sensor = dict_to_environment_sensor(sensor_dict, fake_client)
assert sensor.device_id == sensor_dict["id"]
assert sensor.is_reachable == sensor_dict["isReachable"]
Expand Down

0 comments on commit fc84df4

Please sign in to comment.