From f2d9e7ea78d14a35daca365131682520fa20aa99 Mon Sep 17 00:00:00 2001 From: Khole Date: Sat, 25 Jun 2022 16:42:02 +0100 Subject: [PATCH 01/26] Start to build test framework --- .gitignore | 1 - pyhiveapi/apyhiveapi/__init__.py | 7 +++ pyhiveapi/apyhiveapi/data/camera.json | 17 ------ pyhiveapi/apyhiveapi/session.py | 9 ++- .../apyhiveapi/{data => test_data}/alarm.json | 0 .../apyhiveapi/test_data/cameraImage.json | 12 ++++ .../apyhiveapi/test_data/cameraRecording.json | 3 + .../apyhiveapi/{data => test_data}/data.json | 0 requirements_test.txt | 1 + setup.cfg | 10 +++- tests/API/async_auth.py | 1 - tests/__init__.py | 2 +- tests/apyhiveapi/__init__.py | 1 + tests/apyhiveapi/test_session.py | 11 ++++ tests/common.py | 55 ++++++++++++++++++- tests/pyhiveapi/__init__.py | 1 + tests/pyhiveapi/test_plug.py | 22 ++++++++ tests/pyhiveapi/test_session.py | 11 ++++ tests/test_hub.py | 8 --- 19 files changed, 135 insertions(+), 37 deletions(-) delete mode 100644 pyhiveapi/apyhiveapi/data/camera.json rename pyhiveapi/apyhiveapi/{data => test_data}/alarm.json (100%) create mode 100644 pyhiveapi/apyhiveapi/test_data/cameraImage.json create mode 100644 pyhiveapi/apyhiveapi/test_data/cameraRecording.json rename pyhiveapi/apyhiveapi/{data => test_data}/data.json (100%) delete mode 100644 tests/API/async_auth.py create mode 100644 tests/apyhiveapi/__init__.py create mode 100644 tests/apyhiveapi/test_session.py create mode 100644 tests/pyhiveapi/__init__.py create mode 100644 tests/pyhiveapi/test_plug.py create mode 100644 tests/pyhiveapi/test_session.py delete mode 100644 tests/test_hub.py diff --git a/.gitignore b/.gitignore index f261310..eff9266 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ pyhiveapi.egg-info # due to using tox and pytest .tox .cache -test* custom_tests/* # virtual environment folder diff --git a/pyhiveapi/apyhiveapi/__init__.py b/pyhiveapi/apyhiveapi/__init__.py index 7436221..926049b 100644 --- a/pyhiveapi/apyhiveapi/__init__.py +++ b/pyhiveapi/apyhiveapi/__init__.py @@ -1,11 +1,18 @@ """__init__.py.""" # pylint: skip-file +import os + if __name__ == "pyhiveapi": from .api.hive_api import HiveApi as API # noqa: F401 from .api.hive_auth import HiveAuth as Auth # noqa: F401 + + PATH = os.path.dirname(os.path.realpath(__file__)) + "/test_data/" + PATH = PATH.replace("/pyhiveapi/", "/apyhiveapi/") else: from .api.hive_async_api import HiveApiAsync as API # noqa: F401 from .api.hive_auth_async import HiveAuthAsync as Auth # noqa: F401 + PATH = os.path.dirname(os.path.realpath(__file__)) + "/test_data/" + from .helper.const import SMS_REQUIRED # noqa: F401 from .hive import Hive # noqa: F401 diff --git a/pyhiveapi/apyhiveapi/data/camera.json b/pyhiveapi/apyhiveapi/data/camera.json deleted file mode 100644 index 604ffbe..0000000 --- a/pyhiveapi/apyhiveapi/data/camera.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "cameraImage": { - "parsed": { - "events": [ - { - "thumbnailUrls": [ - "https://test.com/image" - ], - "hasRecording": true - } - ] - } - }, - "camaeraRecording": { - "parsed": "https://test.com/video" - } -} \ No newline at end of file diff --git a/pyhiveapi/apyhiveapi/session.py b/pyhiveapi/apyhiveapi/session.py index b1c7758..35376b7 100644 --- a/pyhiveapi/apyhiveapi/session.py +++ b/pyhiveapi/apyhiveapi/session.py @@ -4,13 +4,13 @@ import copy import json import operator -import os import time from datetime import datetime, timedelta from aiohttp.web import HTTPException from apyhiveapi import API, Auth +from . import PATH from .device_attributes import HiveAttributes from .helper.const import ACTIONS, DEVICES, HIVE_TYPES, PRODUCTS from .helper.hive_exceptions import ( @@ -111,8 +111,7 @@ def openFile(self, file: str): Returns: dict: Data from the chosen file. """ - path = os.path.dirname(os.path.realpath(__file__)) + "/data/" + file - path = path.replace("/pyhiveapi/", "/apyhiveapi/") + path = PATH + file with open(path) as j: data = json.loads(j.read()) @@ -364,8 +363,8 @@ async def getCamera(self, device): cameraImage = None cameraRecording = None if self.config.file: - cameraImage = self.openFile("camera.json") - cameraRecording = self.openFile("camera.json") + cameraImage = self.openFile("cameraImage.json") + cameraRecording = self.openFile("cameraRecording.json") elif self.tokens is not None: cameraImage = await self.api.getCameraImage(device) if cameraImage["parsed"]["events"][0]["hasRecording"] is True: diff --git a/pyhiveapi/apyhiveapi/data/alarm.json b/pyhiveapi/apyhiveapi/test_data/alarm.json similarity index 100% rename from pyhiveapi/apyhiveapi/data/alarm.json rename to pyhiveapi/apyhiveapi/test_data/alarm.json diff --git a/pyhiveapi/apyhiveapi/test_data/cameraImage.json b/pyhiveapi/apyhiveapi/test_data/cameraImage.json new file mode 100644 index 0000000..8671e10 --- /dev/null +++ b/pyhiveapi/apyhiveapi/test_data/cameraImage.json @@ -0,0 +1,12 @@ +{ + "parsed": { + "events": [ + { + "thumbnailUrls": [ + "https://test.com/image" + ], + "hasRecording": true + } + ] + } +} \ No newline at end of file diff --git a/pyhiveapi/apyhiveapi/test_data/cameraRecording.json b/pyhiveapi/apyhiveapi/test_data/cameraRecording.json new file mode 100644 index 0000000..569e0e7 --- /dev/null +++ b/pyhiveapi/apyhiveapi/test_data/cameraRecording.json @@ -0,0 +1,3 @@ +{ + "parsed": "https://test.com/video" +} \ No newline at end of file diff --git a/pyhiveapi/apyhiveapi/data/data.json b/pyhiveapi/apyhiveapi/test_data/data.json similarity index 100% rename from pyhiveapi/apyhiveapi/data/data.json rename to pyhiveapi/apyhiveapi/test_data/data.json diff --git a/requirements_test.txt b/requirements_test.txt index b654c22..bc78845 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1 +1,2 @@ +pyhiveapi tox \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index dcc68be..9378ff1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,10 +19,10 @@ classifiers = Programming Language :: Python :: 3.9 [options] -package_dir = +package_dir = = pyhiveapi packages = find: -python_requires = >=3.6.* +python_requires = >=3.6.* [options.packages.find] where = pyhiveapi @@ -66,3 +66,9 @@ warn_incomplete_stub = true warn_redundant_casts = true warn_unused_configs = true +[tool:pytest] +minversion = 6.0 +addopts = -ra -q +testpaths = + tests/pyhiveapi + tests/apyhiveapi \ No newline at end of file diff --git a/tests/API/async_auth.py b/tests/API/async_auth.py deleted file mode 100644 index b439b42..0000000 --- a/tests/API/async_auth.py +++ /dev/null @@ -1 +0,0 @@ -"""Test file.""" diff --git a/tests/__init__.py b/tests/__init__.py index d203639..cf2ff68 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1 @@ -"""Tests for pyhiveapi.""" +"""Apyhiveapi tests.""" diff --git a/tests/apyhiveapi/__init__.py b/tests/apyhiveapi/__init__.py new file mode 100644 index 0000000..cf2ff68 --- /dev/null +++ b/tests/apyhiveapi/__init__.py @@ -0,0 +1 @@ +"""Apyhiveapi tests.""" diff --git a/tests/apyhiveapi/test_session.py b/tests/apyhiveapi/test_session.py new file mode 100644 index 0000000..ba72772 --- /dev/null +++ b/tests/apyhiveapi/test_session.py @@ -0,0 +1,11 @@ +"""Tests for the session object.""" + +from tests.common import MockSession + + +async def test_start_session(): + """Test a session can be started.""" + hive = MockSession() + device_list = await hive.async_start_session() + + assert len(device_list) > 0 diff --git a/tests/common.py b/tests/common.py index 95f9d4a..2017f17 100644 --- a/tests/common.py +++ b/tests/common.py @@ -1,10 +1,61 @@ -"""Mock services for tests.""" +"""Test the helper method for writing tests.""" # pylint: skip-file +from dataclasses import dataclass +from apyhiveapi import Hive as HiveAsync + +from pyhiveapi import Hive as HiveSync + +USERNAME = "use@file.com" +PASSWORD = "Test12345" +TEMP_CONFIG = { + "username": USERNAME, + "password": PASSWORD, + "options": {"scan_interval": 120}, +} + + +@dataclass class MockConfig: """Mock config for tests.""" + username: str + password: str + device_data: dict + tokens: dict + options: dict + +@dataclass class MockDevice: - """Mock Device for tests.""" + """Mock config for tests.""" + + username: str + password: str + device_data: dict + tokens: dict + options: dict + + +class MockSession: + """Mock Session for tests.""" + + def __init__(self): + """Initialize the Mock Session.""" + self.async_hive = None + self.sync_hive = None + + def __exit__(self, exc_type, exc_value, traceback): + """Exit the mock session.""" + self.loop.close() + + def sync_start_session(self): + """Start a sync session.""" + self.sync_hive = HiveSync(username=USERNAME, password=PASSWORD) + return self.sync_hive.startSession(TEMP_CONFIG) + + async def async_start_session(self): + """Start a async session.""" + self.async_hive = HiveAsync(username=USERNAME, password=PASSWORD) + return await self.async_hive.startSession(TEMP_CONFIG) diff --git a/tests/pyhiveapi/__init__.py b/tests/pyhiveapi/__init__.py new file mode 100644 index 0000000..e84ef15 --- /dev/null +++ b/tests/pyhiveapi/__init__.py @@ -0,0 +1 @@ +"""Tests for library.""" diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py new file mode 100644 index 0000000..2c424ee --- /dev/null +++ b/tests/pyhiveapi/test_plug.py @@ -0,0 +1,22 @@ +"""Tests for the switch and plug object.""" + +from unittest.mock import patch + +from tests.common import MockSession + + +def test_switch_turn_on_success(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.deviceList["switch"][1] + + with patch( + "pyhiveapi.api.hive_api.HiveApi.setState", + return_value={"original": 200, "parsed": {}}, + ) as api_call: + result = hive_session.switch.turnOn(switch) + + assert result is True + assert len(api_call.mock_calls) == 1 diff --git a/tests/pyhiveapi/test_session.py b/tests/pyhiveapi/test_session.py new file mode 100644 index 0000000..d6e1aad --- /dev/null +++ b/tests/pyhiveapi/test_session.py @@ -0,0 +1,11 @@ +"""Tests for the session object.""" + +from tests.common import MockSession + + +def test_start_session(): + """Test a session can be started.""" + hive = MockSession() + device_list = hive.sync_start_session() + + assert len(device_list) > 0 diff --git a/tests/test_hub.py b/tests/test_hub.py deleted file mode 100644 index 6c83435..0000000 --- a/tests/test_hub.py +++ /dev/null @@ -1,8 +0,0 @@ -"""Test hub framework.""" - - -def test_hub_smoke(): - """Test for hub smoke.""" - result = None - - assert result From bac8f8cbb75bf9752a7d7d1ad070bc465e170330 Mon Sep 17 00:00:00 2001 From: Khole Date: Sat, 25 Jun 2022 19:07:26 +0100 Subject: [PATCH 02/26] updates to test framework and pylint --- pyhiveapi/apyhiveapi/action.py | 8 +- pyhiveapi/apyhiveapi/alarm.py | 2 +- pyhiveapi/apyhiveapi/api/hive_api.py | 8 +- pyhiveapi/apyhiveapi/api/hive_async_api.py | 6 +- pyhiveapi/apyhiveapi/camera.py | 8 +- pyhiveapi/apyhiveapi/heating.py | 24 +- pyhiveapi/apyhiveapi/helper/const.py | 113 +------ pyhiveapi/apyhiveapi/helper/hive_helper.py | 351 +++++++++++++++++++++ pyhiveapi/apyhiveapi/hotwater.py | 12 +- pyhiveapi/apyhiveapi/light.py | 20 +- pyhiveapi/apyhiveapi/plug.py | 8 +- pyhiveapi/apyhiveapi/sensor.py | 14 +- pyhiveapi/apyhiveapi/session.py | 282 ++++++++--------- tests/common.py | 4 +- tests/pyhiveapi/test_plug.py | 2 +- 15 files changed, 544 insertions(+), 318 deletions(-) diff --git a/pyhiveapi/apyhiveapi/action.py b/pyhiveapi/apyhiveapi/action.py index c4af98f..4343e60 100644 --- a/pyhiveapi/apyhiveapi/action.py +++ b/pyhiveapi/apyhiveapi/action.py @@ -84,14 +84,14 @@ async def setStatusOn(self, device: dict): final = False if device["hiveID"] in self.session.data.actions: - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.actions[device["hiveID"]] data.update({"enabled": True}) send = json.dumps(data) resp = await self.session.api.setAction(device["hiveID"], send) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -109,13 +109,13 @@ async def setStatusOff(self, device: dict): final = False if device["hiveID"] in self.session.data.actions: - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.actions[device["hiveID"]] data.update({"enabled": False}) send = json.dumps(data) resp = await self.session.api.setAction(device["hiveID"], send) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final diff --git a/pyhiveapi/apyhiveapi/alarm.py b/pyhiveapi/apyhiveapi/alarm.py index d85fdfb..4250542 100644 --- a/pyhiveapi/apyhiveapi/alarm.py +++ b/pyhiveapi/apyhiveapi/alarm.py @@ -58,7 +58,7 @@ async def setMode(self, device: dict, mode: str): device["hiveID"] in self.session.data.devices and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() resp = await self.session.api.setAlarm(mode=mode) if resp["original"] == 200: final = True diff --git a/pyhiveapi/apyhiveapi/api/hive_api.py b/pyhiveapi/apyhiveapi/api/hive_api.py index c81e282..9151f26 100644 --- a/pyhiveapi/apyhiveapi/api/hive_api.py +++ b/pyhiveapi/apyhiveapi/api/hive_api.py @@ -96,7 +96,7 @@ def refreshTokens(self, tokens={}): info = self.request("POST", url, jsc) data = json.loads(info.text) if "token" in data and self.session: - self.session.updateTokens(data) + self.session.update_tokens(data) self.urls.update({"base": data["platform"]["endpoint"]}) self.urls.update({"camera": data["platform"]["cameraPlatform"]}) self.json_return.update({"original": info.status_code}) @@ -142,11 +142,11 @@ def getAll(self): return json_return - def getAlarm(self, homeID=None): + def getAlarm(self, home_id=None): """Build and query alarm endpoint.""" if self.session is not None: - homeID = self.session.config.homeID - url = self.urls["base"] + self.urls["alarm"] + homeID + home_id = self.session.config.home_id + url = self.urls["base"] + self.urls["alarm"] + home_id try: info = self.request("GET", url) self.json_return.update({"original": info.status_code}) diff --git a/pyhiveapi/apyhiveapi/api/hive_async_api.py b/pyhiveapi/apyhiveapi/api/hive_async_api.py index c8018a1..f7d0da7 100644 --- a/pyhiveapi/apyhiveapi/api/hive_async_api.py +++ b/pyhiveapi/apyhiveapi/api/hive_async_api.py @@ -129,7 +129,7 @@ async def refreshTokens(self): if self.json_return["original"] == 200: info = self.json_return["parsed"] if "token" in info: - await self.session.updateTokens(info) + await self.session.update_tokens(info) self.baseUrl = info["platform"]["endpoint"] self.cameraBaseUrl = info["platform"]["cameraPlatform"] return True @@ -154,7 +154,7 @@ async def getAll(self): async def getAlarm(self): """Build and query alarm endpoint.""" json_return = {} - url = self.urls["alarm"] + self.session.config.homeID + url = self.urls["alarm"] + self.session.config.home_id try: resp = await self.request("get", url) json_return.update({"original": resp.status}) @@ -306,7 +306,7 @@ async def setAlarm(self, **kwargs): + "}" ) - url = f"{self.urls['alarm']}{self.session.config.homeID}" + url = f"{self.urls['alarm']}{self.session.config.home_id}" try: await self.isFileBeingUsed() resp = await self.request("post", url, data=jsc) diff --git a/pyhiveapi/apyhiveapi/camera.py b/pyhiveapi/apyhiveapi/camera.py index 7ccd006..1c9a8be 100644 --- a/pyhiveapi/apyhiveapi/camera.py +++ b/pyhiveapi/apyhiveapi/camera.py @@ -90,11 +90,11 @@ async def setCameraOn(self, device: dict, mode: str): device["hiveID"] in self.session.data.devices and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() resp = await self.session.api.setState(mode=mode) if resp["original"] == 200: final = True - await self.session.getCamera() + await self.session.get_camera() return final @@ -113,11 +113,11 @@ async def setCameraOff(self, device: dict, mode: str): device["hiveID"] in self.session.data.devices and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() resp = await self.session.api.setState(mode=mode) if resp["original"] == 200: final = True - await self.session.getCamera() + await self.session.get_camera() return final diff --git a/pyhiveapi/apyhiveapi/heating.py b/pyhiveapi/apyhiveapi/heating.py index 3581b9c..82dccba 100644 --- a/pyhiveapi/apyhiveapi/heating.py +++ b/pyhiveapi/apyhiveapi/heating.py @@ -261,21 +261,21 @@ async def setTargetTemperature(self, device: dict, new_temp: str): Returns: boolean: True/False if successful """ - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() final = False if ( device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], device["hiveID"], target=new_temp ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() final = True return final @@ -290,7 +290,7 @@ async def setMode(self, device: dict, new_mode: str): Returns: boolean: True/False if successful """ - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() final = False if ( @@ -303,7 +303,7 @@ async def setMode(self, device: dict, new_mode: str): ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() final = True return final @@ -321,7 +321,7 @@ async def setBoostOn(self, device: dict, mins: str, temp: float): """ if mins > 0 and temp >= await self.getMinTemperature(device): if temp <= await self.getMaxTemperature(device): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() final = False if ( @@ -338,7 +338,7 @@ async def setBoostOn(self, device: dict, mins: str, temp: float): ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() final = True return final @@ -359,9 +359,9 @@ async def setBoostOff(self, device: dict): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() if await self.getBoostStatus(device) == "ON": prev_mode = data["props"]["previous"]["mode"] if prev_mode == "MANUAL" or prev_mode == "OFF": @@ -377,7 +377,7 @@ async def setBoostOff(self, device: dict): data["type"], device["hiveID"], mode=prev_mode ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() final = True return final @@ -399,13 +399,13 @@ async def setHeatOnDemand(self, device: dict, state: str): and device["deviceData"]["online"] ): data = self.session.data.products[device["hiveID"]] - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() resp = await self.session.api.setState( data["type"], device["hiveID"], autoBoost=state ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() final = True return final diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py index 3b44924..854d274 100644 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ b/pyhiveapi/apyhiveapi/helper/const.py @@ -1,5 +1,5 @@ """Constants for Pyhiveapi.""" -# pylint: skip-file + SYNC_PACKAGE_NAME = "pyhiveapi" SYNC_PACKAGE_DIR = "/pyhiveapi/" ASYNC_PACKAGE_NAME = "apyhiveapi" @@ -55,114 +55,3 @@ "Sensor": ["motionsensor", "contactsensor"], "Switch": ["activeplug"], } -sensor_commands = { - "SMOKE_CO": "self.session.hub.getSmokeStatus(device)", - "DOG_BARK": "self.session.hub.getDogBarkStatus(device)", - "GLASS_BREAK": "self.session.hub.getGlassBreakStatus(device)", - "Camera_Temp": "self.session.camera.getCameraTemperature(device)", - "Heating_Current_Temperature": "self.session.heating.getCurrentTemperature(device)", - "Heating_Target_Temperature": "self.session.heating.getTargetTemperature(device)", - "Heating_State": "self.session.heating.getState(device)", - "Heating_Mode": "self.session.heating.getMode(device)", - "Heating_Boost": "self.session.heating.getBoostStatus(device)", - "Hotwater_State": "self.session.hotwater.getState(device)", - "Hotwater_Mode": "self.session.hotwater.getMode(device)", - "Hotwater_Boost": "self.session.hotwater.getBoost(device)", - "Battery": 'self.session.attr.getBattery(device["device_id"])', - "Mode": 'self.session.attr.getMode(device["hiveID"])', - "Availability": "self.online(device)", - "Connectivity": "self.online(device)", - "Power": "self.session.switch.getPowerUsage(device)", -} - -PRODUCTS = { - "sense": [ - 'addList("binary_sensor", p, haName="Glass Detection", hiveType="GLASS_BREAK")', - 'addList("binary_sensor", p, haName="Smoke Detection", hiveType="SMOKE_CO")', - 'addList("binary_sensor", p, haName="Dog Bark Detection", hiveType="DOG_BARK")', - ], - "heating": [ - 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("switch", p, haName=" Heat on Demand", hiveType="Heating_Heat_On_Demand", category="config")', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', - 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', - ], - "trvcontrol": [ - 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', - 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', - ], - "hotwater": [ - 'addList("water_heater", p,)', - 'addList("sensor", p, haName="Hotwater State", hiveType="Hotwater_State", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Mode", hiveType="Hotwater_Mode", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Boost", hiveType="Hotwater_Boost", category="diagnostic")', - ], - "activeplug": [ - 'addList("switch", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - 'addList("sensor", p, haName=" Power", hiveType="Power", category="diagnostic")', - ], - "warmwhitelight": [ - 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], - "tuneablelight": [ - 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], - "colourtuneablelight": [ - 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], - # "hivecamera": [ - # 'addList("camera", p)', - # 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - # 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - # 'addList("sensor", p, haName=" Temperature", hiveType="Camera_Temp", category="diagnostic")', - # ], - "motionsensor": [ - 'addList("binary_sensor", p)', - ], - "contactsensor": ['addList("binary_sensor", p)'], -} - -DEVICES = { - "contactsensor": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], - "hub": [ - 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity", category="diagnostic")', - ], - "motionsensor": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], - "sense": [ - 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity")', - ], - "siren": ['addList("alarm_control_panel", d)'], - "thermostatui": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], - "trv": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', - ], -} - -ACTIONS = ( - 'addList("switch", a, hiveName=a["name"], haName=a["name"], hiveType="action")' -) diff --git a/pyhiveapi/apyhiveapi/helper/hive_helper.py b/pyhiveapi/apyhiveapi/helper/hive_helper.py index 2da30d0..fda5c1b 100644 --- a/pyhiveapi/apyhiveapi/helper/hive_helper.py +++ b/pyhiveapi/apyhiveapi/helper/hive_helper.py @@ -207,3 +207,354 @@ def getHeatOnDemandDevice(self, device: dict): trv = self.session.data.products.get(device["HiveID"]) thermostat = self.session.data.products.get(trv["state"]["zone"]) return thermostat + + async def call_sensor_function(self, device): + """Helper to decide which function to call.""" + if device["hiveType"] == "SMOKE_CO": + return await self.session.hub.getSmokeStatus(device) + if device["hiveType"] == "DOG_BARK": + return await self.session.hub.getDogBarkStatus(device) + if device["hiveType"] == "GLASS_BREAK": + return await self.session.hub.getGlassBreakStatus(device) + if device["hiveType"] == "Camera_Temp": + return await self.session.camera.getCameraTemperature(device) + if device["hiveType"] == "Heating_Current_Temperature": + return await self.session.heating.getCurrentTemperature(device) + if device["hiveType"] == "Heating_Target_Temperature": + return await self.session.heating.getTargetTemperature(device) + if device["hiveType"] == "Heating_State": + return await self.session.heating.getState(device) + if device["hiveType"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): + return await self.session.heating.getMode(device) + if device["hiveType"] == "Heating_Boost": + return await self.session.heating.getBoostStatus(device) + if device["hiveType"] == "Hotwater_State": + return await self.session.hotwater.getState(device) + if device["hiveType"] == "Hotwater_Boost": + return await self.session.hotwater.getBoost(device) + if device["hiveType"] == "Battery": + return await self.session.attr.getBattery(device["device_id"]) + if device["hiveType"] in ("Availability", "Connectivity"): + return await self.online(device) + if device["hiveType"] == "Power": + return await self.session.switch.getPowerUsage(device) + return None + + async def call_products_to_add(self, entity_type, product): + """Helper to add a product to the list.""" + if entity_type == "sense": + self.session.add_list( + "binary_sensor", + product, + haName="Glass Detection", + hiveType="GLASS_BREAK", + ) + self.session.add_list( + "binary_sensor", product, haName="Smoke Detection", hiveType="SMOKE_CO" + ) + self.session.add_list( + "binary_sensor", + product, + haName="Dog Bark Detection", + hiveType="DOG_BARK", + ) + if entity_type == "heating": + self.session.add_list( + "climate", product, temperatureunit=self.data["user"]["temperatureUnit"] + ) + self.session.add_list( + "switch", + product, + haName=" Heat on Demand", + hiveType="Heating_Heat_On_Demand", + category="config", + ) + self.session.add_list( + "sensor", + product, + haName=" Current Temperature", + hiveType="Heating_Current_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Target Temperature", + hiveType="Heating_Target_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" State", + hiveType="Heating_State", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Heating_Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Boost", + hiveType="Heating_Boost", + category="diagnostic", + ) + if entity_type == "trvcontrol": + self.session.add_list( + "climate", product, temperatureunit=self.data["user"]["temperatureUnit"] + ) + self.session.add_list( + "sensor", + product, + haName=" Current Temperature", + hiveType="Heating_Current_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Target Temperature", + hiveType="Heating_Target_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" State", + hiveType="Heating_State", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Heating_Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Boost", + hiveType="Heating_Boost", + category="diagnostic", + ) + if entity_type == "hotwater": + self.session.add_list( + "water_heater", + product, + ) + self.session.add_list( + "sensor", + product, + haName="Hotwater State", + hiveType="Hotwater_State", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName="Hotwater Mode", + hiveType="Hotwater_Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName="Hotwater Boost", + hiveType="Hotwater_Boost", + category="diagnostic", + ) + if entity_type == "activeplug": + self.session.add_list("switch", product) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Power", + hiveType="Power", + category="diagnostic", + ) + if entity_type == "warmwhitelight": + self.session.add_list("light", product) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + if entity_type == "tuneablelight": + self.session.add_list("light", product) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + if entity_type == "colourtuneablelight": + self.session.add_list("light", product) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + if entity_type == "hivecamera": + self.session.add_list("camera", product) + self.session.add_list( + "sensor", + product, + haName=" Mode", + hiveType="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + haName=" Temperature", + hiveType="Camera_Temp", + category="diagnostic", + ) + if entity_type == "motionsensor": + self.session.add_list("binary_sensor", product) + if entity_type == "contactsensor": + self.session.add_list("binary_sensor", product) + return None + + async def call_devices_to_add(self, entity_type, device): + """Helper to add a device to the list.""" + if entity_type == "contactsensor": + self.session.add_list( + "sensor", + device, + haName=" Battery Level", + hiveType="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + if entity_type == "hub": + self.session.add_list( + "binary_sensor", + device, + haName="Hive Hub Status", + hiveType="Connectivity", + category="diagnostic", + ) + if entity_type == "motionsensor": + self.session.add_list( + "sensor", + device, + haName=" Battery Level", + hiveType="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + if entity_type == "sense": + self.session.add_list( + "binary_sensor", + device, + haName="Hive Hub Status", + hiveType="Connectivity", + ) + if entity_type == "siren": + self.session.add_list("alarm_control_panel", device) + if entity_type == "thermostatui": + self.session.add_list( + "sensor", + device, + haName=" Battery Level", + hiveType="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + if entity_type == "trv": + self.session.add_list( + "sensor", + device, + haName=" Battery Level", + hiveType="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + haName=" Availability", + hiveType="Availability", + category="diagnostic", + ) + + async def call_action_to_add(self, action): + """Helper to add an action to the list.""" + await self.session.add_list( + "switch", + action, + hiveName=action["name"], + haName=action["name"], + hiveType="action", + ) diff --git a/pyhiveapi/apyhiveapi/hotwater.py b/pyhiveapi/apyhiveapi/hotwater.py index 08a9e6f..cb50840 100644 --- a/pyhiveapi/apyhiveapi/hotwater.py +++ b/pyhiveapi/apyhiveapi/hotwater.py @@ -127,14 +127,14 @@ async def setMode(self, device: dict, new_mode: str): final = False if device["hiveID"] in self.session.data.products: - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], device["hiveID"], mode=new_mode ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -155,14 +155,14 @@ async def setBoostOn(self, device: dict, mins: int): and device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], device["hiveID"], mode="BOOST", boost=mins ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -182,14 +182,14 @@ async def setBoostOff(self, device: dict): and await self.getBoost(device) == "ON" and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] prev_mode = data["props"]["previous"]["mode"] resp = await self.session.api.setState( data["type"], device["hiveID"], mode=prev_mode ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() final = True return final diff --git a/pyhiveapi/apyhiveapi/light.py b/pyhiveapi/apyhiveapi/light.py index 703abe7..ce9c416 100644 --- a/pyhiveapi/apyhiveapi/light.py +++ b/pyhiveapi/apyhiveapi/light.py @@ -180,7 +180,7 @@ async def setStatusOff(self, device: dict): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], device["hiveID"], status="OFF" @@ -188,7 +188,7 @@ async def setStatusOff(self, device: dict): if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -207,7 +207,7 @@ async def setStatusOn(self, device: dict): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( @@ -215,7 +215,7 @@ async def setStatusOn(self, device: dict): ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -235,7 +235,7 @@ async def setBrightness(self, device: dict, n_brightness: int): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], @@ -245,7 +245,7 @@ async def setBrightness(self, device: dict, n_brightness: int): ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -265,7 +265,7 @@ async def setColorTemp(self, device: dict, color_temp: int): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] if data["type"] == "tuneablelight": @@ -284,7 +284,7 @@ async def setColorTemp(self, device: dict, color_temp: int): if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -304,7 +304,7 @@ async def setColor(self, device: dict, new_color: list): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( @@ -317,7 +317,7 @@ async def setColor(self, device: dict, new_color: list): ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final diff --git a/pyhiveapi/apyhiveapi/plug.py b/pyhiveapi/apyhiveapi/plug.py index c86e535..60d10e5 100644 --- a/pyhiveapi/apyhiveapi/plug.py +++ b/pyhiveapi/apyhiveapi/plug.py @@ -66,14 +66,14 @@ async def setStatusOn(self, device: dict): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], data["id"], status="ON" ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final @@ -92,14 +92,14 @@ async def setStatusOff(self, device: dict): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] resp = await self.session.api.setState( data["type"], data["id"], status="OFF" ) if resp["original"] == 200: final = True - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices() return final diff --git a/pyhiveapi/apyhiveapi/sensor.py b/pyhiveapi/apyhiveapi/sensor.py index ceb0b99..2c1c323 100644 --- a/pyhiveapi/apyhiveapi/sensor.py +++ b/pyhiveapi/apyhiveapi/sensor.py @@ -1,6 +1,6 @@ """Hive Sensor Module.""" # pylint: skip-file -from .helper.const import HIVE_TYPES, HIVETOHA, sensor_commands +from .helper.const import HIVE_TYPES, HIVETOHA class HiveSensor: @@ -108,17 +108,11 @@ async def getSensor(self, device: dict): elif device["hiveID"] in self.session.data.products: data = self.session.data.products.get(device["hiveID"], {}) - if ( - dev_data["hiveType"] in sensor_commands - or dev_data.get("custom", None) in sensor_commands - ): - code = sensor_commands.get( - dev_data["hiveType"], - sensor_commands.get(dev_data["custom"]), - ) + sensor_state = self.session.helper.call_sensor_function(dev_data) + if sensor_state is not None: dev_data.update( { - "status": {"state": await eval(code)}, + "status": {"state": sensor_state}, "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), } diff --git a/pyhiveapi/apyhiveapi/session.py b/pyhiveapi/apyhiveapi/session.py index 35376b7..52a5ed0 100644 --- a/pyhiveapi/apyhiveapi/session.py +++ b/pyhiveapi/apyhiveapi/session.py @@ -1,5 +1,5 @@ """Hive Session Module.""" -# pylint: skip-file + import asyncio import copy import json @@ -12,7 +12,7 @@ from . import PATH from .device_attributes import HiveAttributes -from .helper.const import ACTIONS, DEVICES, HIVE_TYPES, PRODUCTS +from .helper.const import HIVE_TYPES from .helper.hive_exceptions import ( HiveApiError, HiveFailedToRefreshTokens, @@ -48,7 +48,7 @@ def __init__( self, username: str = None, password: str = None, - websession: object = None, + web_session: object = None, ): """Initialise the base variable values. @@ -61,11 +61,11 @@ def __init__( username=username, password=password, ) - self.api = API(hiveSession=self, websession=websession) + self.api = API(hiveSession=self, websession=web_session) self.helper = HiveHelper(self) self.attr = HiveAttributes(self) self.log = Logger(self) - self.updateLock = asyncio.Lock() + self.update_lock = asyncio.Lock() self.tokens = Map( { "tokenData": {}, @@ -75,12 +75,10 @@ def __init__( ) self.config = Map( { - "alarm": False, "battery": [], - "camera": False, "errorList": {}, "file": False, - "homeID": None, + "home_id": None, "lastUpdated": datetime.now(), "mode": [], "scanInterval": timedelta(seconds=120), @@ -100,9 +98,9 @@ def __init__( } ) self.devices = {} - self.deviceList = {} + self.device_list = {} - def openFile(self, file: str): + def open_file(self, file: str): """Open a file. Args: @@ -112,12 +110,12 @@ def openFile(self, file: str): dict: Data from the chosen file. """ path = PATH + file - with open(path) as j: - data = json.loads(j.read()) + with open(path, encoding="utf-8") as json_file: + data = json.loads(json_file.read()) return data - def addList(self, entityType: str, data: dict, **kwargs: dict): + def add_list(self, entity_type: str, data: dict, **kwargs: dict): """Add entity to the list. Args: @@ -140,7 +138,7 @@ def addList(self, entityType: str, data: dict, **kwargs: dict): "hiveID": data.get("id", ""), "hiveName": device_name, "hiveType": data.get("type", ""), - "haType": entityType, + "haType": entity_type, "deviceData": device.get("props", data.get("props", {})), "parentDevice": data.get("parent", None), "isGroup": data.get("isGroup", False), @@ -154,36 +152,34 @@ def addList(self, entityType: str, data: dict, **kwargs: dict): formatted_data["haName"] = device_name formatted_data.update(kwargs) except KeyError as error: - self.logger.error(error) + self.log.error(error) - self.deviceList[entityType].append(formatted_data) + self.device_list[entity_type].append(formatted_data) return formatted_data - async def updateInterval(self, new_interval: timedelta): + async def update_interval(self, new_interval: timedelta): """Update the scan interval. Args: new_interval (int): New interval for polling. """ - if type(new_interval) == int: + if isinstance(new_interval, int): new_interval = timedelta(seconds=new_interval) + if new_interval < timedelta(seconds=15): + new_interval = timedelta(seconds=15) + self.config.scanInterval = new_interval - interval = new_interval - if interval < timedelta(seconds=15): - interval = timedelta(seconds=15) - self.config.scanInterval = interval - - async def useFile(self, username: str = None): + async def use_file(self, username: str = None): """Update to check if file is being used. Args: username (str, optional): Looks for use@file.com. Defaults to None. """ - using_file = True if username == "use@file.com" else False + using_file = bool(username == "use@file.com") if using_file: self.config.file = True - async def updateTokens(self, tokens: dict, update_expiry_time: bool = True): + async def update_tokens(self, tokens: dict, update_expiry_time: bool = True): """Update session tokens. Args: @@ -236,7 +232,7 @@ async def login(self): print("no_internet_available") if "AuthenticationResult" in result: - await self.updateTokens(result) + await self.update_tokens(result) return result async def sms2fa(self, code, session): @@ -260,10 +256,10 @@ async def sms2fa(self, code, session): print("no_internet_available") if "AuthenticationResult" in result: - await self.updateTokens(result) + await self.update_tokens(result) return result - async def deviceLogin(self): + async def device_login(self): """Login to hive account using device authentication. Raises: @@ -278,16 +274,16 @@ async def deviceLogin(self): raise HiveUnknownConfiguration try: - result = await self.auth.deviceLogin() - except HiveInvalidDeviceAuthentication: - raise HiveInvalidDeviceAuthentication + result = await self.auth.device_login() + except HiveInvalidDeviceAuthentication as exc: + raise HiveInvalidDeviceAuthentication from exc if "AuthenticationResult" in result: - await self.updateTokens(result) + await self.update_tokens(result) self.tokens.tokenExpiry = timedelta(seconds=0) return result - async def hiveRefreshTokens(self): + async def hive_refresh_tokens(self): """Refresh Hive tokens. Returns: @@ -297,45 +293,42 @@ async def hiveRefreshTokens(self): if self.config.file: return None - else: - expiry_time = self.tokens.tokenCreated + self.tokens.tokenExpiry - if datetime.now() >= expiry_time: - result = await self.auth.refresh_token( - self.tokens.tokenData["refreshToken"] - ) - if "AuthenticationResult" in result: - await self.updateTokens(result) - else: - raise HiveFailedToRefreshTokens + expiry_time = self.tokens.tokenCreated + self.tokens.tokenExpiry + if datetime.now() >= expiry_time: + result = await self.auth.refresh_token( + self.tokens.tokenData["refreshToken"] + ) + + if "AuthenticationResult" in result: + await self.update_tokens(result) + else: + raise HiveFailedToRefreshTokens return result - async def updateData(self, device: dict): + async def update_data(self): """Get latest data for Hive nodes - rate limiting. - Args: - device (dict): Device requesting the update. - Returns: boolean: True/False if update was successful """ updated = False - ep = self.config.lastUpdate + self.config.scanInterval - if datetime.now() >= ep and not self.updateLock.locked(): + expiry_time = self.config.lastUpdate + self.config.scanInterval + if datetime.now() >= expiry_time and not self.update_lock.locked(): try: - await self.updateLock.acquire() - await self.getDevices(device["hiveID"]) - if len(self.deviceList["camera"]) > 0: + await self.update_lock.acquire() + await self.get_devices() + if len(self.device_list["camera"]) > 0: for camera in self.data.camera: - await self.getCamera(self.devices[camera]) + await self.get_camera(self.devices[camera]) updated = True finally: - self.updateLock.release() + self.update_lock.release() return updated - async def getAlarm(self): + async def get_alarm(self): """Get alarm data. Raises: @@ -343,38 +336,38 @@ async def getAlarm(self): HiveApiError: An API error code has been returned. """ if self.config.file: - api_resp_d = self.openFile("alarm.json") + api_resp_d = self.open_file("alarm.json") elif self.tokens is not None: api_resp_d = await self.api.getAlarm() if operator.contains(str(api_resp_d["original"]), "20") is False: raise HTTPException - elif api_resp_d["parsed"] is None: + if api_resp_d["parsed"] is None: raise HiveApiError self.data.alarm = api_resp_d["parsed"] - async def getCamera(self, device): + async def get_camera(self, device): """Get camera data. Raises: HTTPException: HTTP error has occurred updating the devices. HiveApiError: An API error code has been returned. """ - cameraImage = None - cameraRecording = None + camera_image = None + camera_recording = None if self.config.file: - cameraImage = self.openFile("cameraImage.json") - cameraRecording = self.openFile("cameraRecording.json") + camera_image = self.open_file("cameraImage.json") + camera_recording = self.open_file("cameraRecording.json") elif self.tokens is not None: - cameraImage = await self.api.getCameraImage(device) - if cameraImage["parsed"]["events"][0]["hasRecording"] is True: - cameraRecording = await self.api.getCameraRecording( - device, cameraImage["parsed"]["events"][0]["eventId"] + camera_image = await self.api.getCameraImage(device) + if camera_image["parsed"]["events"][0]["hasRecording"] is True: + camera_recording = await self.api.getCameraRecording( + device, camera_image["parsed"]["events"][0]["eventId"] ) - if operator.contains(str(cameraImage["original"]), "20") is False: + if operator.contains(str(camera_image["original"]), "20") is False: raise HTTPException - elif cameraImage["parsed"] is None: + if camera_image["parsed"] is None: raise HiveApiError else: raise NoApiToken @@ -383,17 +376,17 @@ async def getCamera(self, device): self.data.camera[device["id"]]["cameraImage"] = None self.data.camera[device["id"]]["cameraRecording"] = None - if cameraImage is not None: + if camera_image is not None: self.data.camera[device["id"]] = {} - self.data.camera[device["id"]]["cameraImage"] = cameraImage["parsed"][ + self.data.camera[device["id"]]["cameraImage"] = camera_image["parsed"][ "events" ][0] - if cameraRecording is not None: - self.data.camera[device["id"]]["cameraRecording"] = cameraRecording[ + if camera_recording is not None: + self.data.camera[device["id"]]["cameraRecording"] = camera_recording[ "parsed" ] - async def getDevices(self, n_id: str): + async def get_devices(self): """Get latest data for Hive nodes. Args: @@ -411,47 +404,45 @@ async def getDevices(self, n_id: str): try: if self.config.file: - api_resp_d = self.openFile("data.json") + api_resp_d = self.open_file("data.json") elif self.tokens is not None: - await self.hiveRefreshTokens() + await self.hive_refresh_tokens() api_resp_d = await self.api.getAll() if operator.contains(str(api_resp_d["original"]), "20") is False: raise HTTPException - elif api_resp_d["parsed"] is None: + if api_resp_d["parsed"] is None: raise HiveApiError api_resp_p = api_resp_d["parsed"] - tmpProducts = {} - tmpDevices = {} - tmpActions = {} - - for hiveType in api_resp_p: - if hiveType == "user": - self.data.user = api_resp_p[hiveType] - self.config.userID = api_resp_p[hiveType]["id"] - if hiveType == "products": - for aProduct in api_resp_p[hiveType]: - tmpProducts.update({aProduct["id"]: aProduct}) - if hiveType == "devices": - for aDevice in api_resp_p[hiveType]: - tmpDevices.update({aDevice["id"]: aDevice}) - if aDevice["type"] == "siren": - self.config.alarm = True - if aDevice["type"] == "hivecamera": - await self.getCamera(aDevice) - if hiveType == "actions": - for aAction in api_resp_p[hiveType]: - tmpActions.update({aAction["id"]: aAction}) - if hiveType == "homes": - self.config.homeID = api_resp_p[hiveType]["homes"][0]["id"] - - if len(tmpProducts) > 0: - self.data.products = copy.deepcopy(tmpProducts) - if len(tmpDevices) > 0: - self.data.devices = copy.deepcopy(tmpDevices) - self.data.actions = copy.deepcopy(tmpActions) - if self.config.alarm: - await self.getAlarm() + tmp_products = {} + tmp_devices = {} + tmp_actions = {} + + for hive_type in api_resp_p: + if hive_type == "user": + self.data.user = api_resp_p[hive_type] + self.config.userID = api_resp_p[hive_type]["id"] + if hive_type == "products": + for product in api_resp_p[hive_type]: + tmp_products.update({product["id"]: product}) + if hive_type == "devices": + for device in api_resp_p[hive_type]: + tmp_devices.update({device["id"]: device}) + if device["type"] == "siren": + await self.get_alarm() + if device["type"] == "hivecamera": + await self.get_camera(device) + if hive_type == "actions": + for action in api_resp_p[hive_type]: + tmp_actions.update({action["id"]: action}) + if hive_type == "homes": + self.config.home_id = api_resp_p[hive_type]["homes"][0]["id"] + + if len(tmp_products) > 0: + self.data.products = copy.deepcopy(tmp_products) + if len(tmp_devices) > 0: + self.data.devices = copy.deepcopy(tmp_devices) + self.data.actions = copy.deepcopy(tmp_actions) self.config.lastUpdate = datetime.now() get_nodes_successful = True except (OSError, RuntimeError, HiveApiError, ConnectionError, HTTPException): @@ -459,7 +450,7 @@ async def getDevices(self, n_id: str): return get_nodes_successful - async def startSession(self, config: dict = {}): + async def start_session(self, config: dict): """Setup the Hive platform. Args: @@ -472,14 +463,14 @@ async def startSession(self, config: dict = {}): Returns: list: List of devices """ - await self.useFile(config.get("username", self.config.username)) - await self.updateInterval( + await self.use_file(config.get("username", self.config.username)) + await self.update_interval( config.get("options", {}).get("scan_interval", self.config.scanInterval) ) if config != {}: if "tokens" in config and not self.config.file: - await self.updateTokens(config["tokens"], False) + await self.update_tokens(config["tokens"], False) if "device_data" in config and not self.config.file: self.auth.device_group_key = config["device_data"][0] @@ -490,61 +481,61 @@ async def startSession(self, config: dict = {}): raise HiveUnknownConfiguration try: - await self.getDevices("No_ID") + await self.get_devices() except HTTPException: return HTTPException if self.data.devices == {} or self.data.products == {}: raise HiveReauthRequired - return await self.createDevices() + return await self.create_devices() - async def createDevices(self): + async def create_devices(self): """Create list of devices. Returns: list: List of devices """ - self.deviceList["alarm_control_panel"] = [] - self.deviceList["binary_sensor"] = [] - self.deviceList["camera"] = [] - self.deviceList["climate"] = [] - self.deviceList["light"] = [] - self.deviceList["sensor"] = [] - self.deviceList["switch"] = [] - self.deviceList["water_heater"] = [] + self.device_list["alarm_control_panel"] = [] + self.device_list["binary_sensor"] = [] + self.device_list["camera"] = [] + self.device_list["climate"] = [] + self.device_list["light"] = [] + self.device_list["sensor"] = [] + self.device_list["switch"] = [] + self.device_list["water_heater"] = [] hive_type = HIVE_TYPES["Heating"] + HIVE_TYPES["Switch"] + HIVE_TYPES["Light"] - for aProduct in self.data.products: - p = self.data.products[aProduct] - if p.get("isGroup", False): + for product in self.data.products: + current_product = self.data.products[product] + if current_product.get("isGroup", False): continue - product_list = PRODUCTS.get(self.data.products[aProduct]["type"], []) - for code in product_list: - eval("self." + code) + self.helper.call_products_to_add( + self.data.products[product]["type"], current_product + ) - if self.data.products[aProduct]["type"] in hive_type: - self.config.mode.append(p["id"]) + if self.data.products[product]["type"] in hive_type: + self.config.mode.append(current_product["id"]) hive_type = HIVE_TYPES["Thermo"] + HIVE_TYPES["Sensor"] - for aDevice in self.data["devices"]: - d = self.data.devices[aDevice] - device_list = DEVICES.get(self.data.devices[aDevice]["type"], []) - for code in device_list: - eval("self." + code) + for device in self.data["devices"]: + current_device = self.data.devices[device] + self.helper.call_devices_to_add( + self.data.devices[device]["type"], current_device + ) - if self.data["devices"][aDevice]["type"] in hive_type: - self.config.battery.append(d["id"]) + if self.data["devices"][device]["type"] in hive_type: + self.config.battery.append(current_device["id"]) if "action" in HIVE_TYPES["Switch"]: for action in self.data["actions"]: - a = self.data["actions"][action] # noqa: F841 - eval("self." + ACTIONS) + current_action = self.data["actions"][action] + self.helper.call_action_to_add(current_action) - return self.deviceList + return self.device_list @staticmethod - def epochTime(date_time: any, pattern: str, action: str): + def epoch_time(date_time: any, pattern: str, action: str): """date/time conversion to epoch. Args: @@ -557,8 +548,9 @@ def epochTime(date_time: any, pattern: str, action: str): """ if action == "to_epoch": pattern = "%d.%m.%Y %H:%M:%S" - epochtime = int(time.mktime(time.strptime(str(date_time), pattern))) - return epochtime - elif action == "from_epoch": + epoch_time = int(time.mktime(time.strptime(str(date_time), pattern))) + return epoch_time + if action == "from_epoch": date = datetime.fromtimestamp(int(date_time)).strftime(pattern) return date + return None diff --git a/tests/common.py b/tests/common.py index 2017f17..03a11bc 100644 --- a/tests/common.py +++ b/tests/common.py @@ -53,9 +53,9 @@ def __exit__(self, exc_type, exc_value, traceback): def sync_start_session(self): """Start a sync session.""" self.sync_hive = HiveSync(username=USERNAME, password=PASSWORD) - return self.sync_hive.startSession(TEMP_CONFIG) + return self.sync_hive.start_session(TEMP_CONFIG) async def async_start_session(self): """Start a async session.""" self.async_hive = HiveAsync(username=USERNAME, password=PASSWORD) - return await self.async_hive.startSession(TEMP_CONFIG) + return await self.async_hive.start_session(TEMP_CONFIG) diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py index 2c424ee..5bf6550 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_plug.py @@ -10,7 +10,7 @@ def test_switch_turn_on_success(): hive = MockSession() hive.sync_start_session() hive_session = hive.sync_hive - switch = hive_session.session.deviceList["switch"][1] + switch = hive_session.session.device_list["switch"][1] with patch( "pyhiveapi.api.hive_api.HiveApi.setState", From b09fe158c8e66f4a1a41068789beb8f83ad5b106 Mon Sep 17 00:00:00 2001 From: Khole Date: Sat, 25 Jun 2022 19:07:58 +0100 Subject: [PATCH 03/26] missed changes --- pyhiveapi/apyhiveapi/helper/hive_helper.py | 8 ++++++-- pyhiveapi/apyhiveapi/session.py | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pyhiveapi/apyhiveapi/helper/hive_helper.py b/pyhiveapi/apyhiveapi/helper/hive_helper.py index fda5c1b..c007615 100644 --- a/pyhiveapi/apyhiveapi/helper/hive_helper.py +++ b/pyhiveapi/apyhiveapi/helper/hive_helper.py @@ -260,7 +260,9 @@ async def call_products_to_add(self, entity_type, product): ) if entity_type == "heating": self.session.add_list( - "climate", product, temperatureunit=self.data["user"]["temperatureUnit"] + "climate", + product, + temperatureunit=self.session.data["user"]["temperatureUnit"], ) self.session.add_list( "switch", @@ -306,7 +308,9 @@ async def call_products_to_add(self, entity_type, product): ) if entity_type == "trvcontrol": self.session.add_list( - "climate", product, temperatureunit=self.data["user"]["temperatureUnit"] + "climate", + product, + temperatureunit=self.session.data["user"]["temperatureUnit"], ) self.session.add_list( "sensor", diff --git a/pyhiveapi/apyhiveapi/session.py b/pyhiveapi/apyhiveapi/session.py index 52a5ed0..3b5a739 100644 --- a/pyhiveapi/apyhiveapi/session.py +++ b/pyhiveapi/apyhiveapi/session.py @@ -510,7 +510,7 @@ async def create_devices(self): current_product = self.data.products[product] if current_product.get("isGroup", False): continue - self.helper.call_products_to_add( + await self.helper.call_products_to_add( self.data.products[product]["type"], current_product ) @@ -520,7 +520,7 @@ async def create_devices(self): hive_type = HIVE_TYPES["Thermo"] + HIVE_TYPES["Sensor"] for device in self.data["devices"]: current_device = self.data.devices[device] - self.helper.call_devices_to_add( + await self.helper.call_devices_to_add( self.data.devices[device]["type"], current_device ) @@ -530,7 +530,7 @@ async def create_devices(self): if "action" in HIVE_TYPES["Switch"]: for action in self.data["actions"]: current_action = self.data["actions"][action] - self.helper.call_action_to_add(current_action) + await self.helper.call_action_to_add(current_action) return self.device_list From 0e7e56b9caaaa52e32dba163eb37108ea3f4ca35 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sun, 26 Jun 2022 16:25:21 +0100 Subject: [PATCH 04/26] mark test as asyncio --- tests/apyhiveapi/test_session.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/apyhiveapi/test_session.py b/tests/apyhiveapi/test_session.py index ba72772..7dda40e 100644 --- a/tests/apyhiveapi/test_session.py +++ b/tests/apyhiveapi/test_session.py @@ -1,8 +1,9 @@ """Tests for the session object.""" from tests.common import MockSession +import pytest - +@pytest.mark.asyncio async def test_start_session(): """Test a session can be started.""" hive = MockSession() From 397ed964ce3ebd6d5a879c73b2f18c4d14956afe Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 2 Jul 2022 10:20:06 +0100 Subject: [PATCH 05/26] update settings.json --- .vscode/settings.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7688f82..770fc6b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,8 @@ { "python.testing.pytestArgs": [], "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true + "python.testing.pytestEnabled": true, + "[python]": { + "editor.showUnused": false, + }, } \ No newline at end of file From 71056338cc2477c557d1899fcfe3ae06ee90d991 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 2 Jul 2022 18:53:31 +0100 Subject: [PATCH 06/26] Add plug tests for sync and async --- .gitignore | 1 + .vscode/settings.json | 3 +- .vscode/tasks.json | 95 +++++++++++++++++++++++ requirements_test.txt | 2 - requirements_test_all.txt | 4 + tests/apyhiveapi/test_plug.py | 127 +++++++++++++++++++++++++++++++ tests/apyhiveapi/test_session.py | 4 +- tests/common.py | 4 - tests/pyhiveapi/test_plug.py | 97 ++++++++++++++++++++++- 9 files changed, 328 insertions(+), 9 deletions(-) create mode 100644 .vscode/tasks.json delete mode 100644 requirements_test.txt create mode 100644 requirements_test_all.txt create mode 100644 tests/apyhiveapi/test_plug.py diff --git a/.gitignore b/.gitignore index d2ef908..65ee091 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__/ build dist pyhiveapi.egg-info +*.coverage # due to using tox and pytest .tox diff --git a/.vscode/settings.json b/.vscode/settings.json index 770fc6b..46987f9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,9 @@ { - "python.testing.pytestArgs": [], + "python.testing.pytestArgs": ["--disable-warnings"], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "[python]": { "editor.showUnused": false, }, + "python.formatting.provider": "black", } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..bf8a4ac --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,95 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Pytest", + "type": "shell", + "command": "pytest --timeout=10 tests", + "dependsOn": ["Install all Test Requirements"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Flake8", + "type": "shell", + "command": "pre-commit run flake8 --all-files", + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Pylint", + "type": "shell", + "command": "pylint homeassistant", + "dependsOn": ["Install all Requirements"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Code Coverage", + "detail": "Generate code coverage report for a given integration.", + "type": "shell", + "command": "pytest --cov-report html --cov=apyhiveapi tests/", + "dependsOn": ["Install all Test Requirements"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Install all Requirements", + "type": "shell", + "command": "pip3 install --use-deprecated=legacy-resolver -r requirements_all.txt", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Install all Test Requirements", + "type": "shell", + "command": "pip3 install --use-deprecated=legacy-resolver -r requirements_test_all.txt", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + ], + "inputs": [] + } + \ No newline at end of file diff --git a/requirements_test.txt b/requirements_test.txt deleted file mode 100644 index bc78845..0000000 --- a/requirements_test.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyhiveapi -tox \ No newline at end of file diff --git a/requirements_test_all.txt b/requirements_test_all.txt new file mode 100644 index 0000000..5f45c9e --- /dev/null +++ b/requirements_test_all.txt @@ -0,0 +1,4 @@ +pyhiveapi +pytest +pytest-cov +tox \ No newline at end of file diff --git a/tests/apyhiveapi/test_plug.py b/tests/apyhiveapi/test_plug.py new file mode 100644 index 0000000..6b390c1 --- /dev/null +++ b/tests/apyhiveapi/test_plug.py @@ -0,0 +1,127 @@ +"""Tests for the switch and plug object.""" + +from unittest.mock import patch + +import pytest + +from tests.common import MockSession + + +@pytest.mark.asyncio +async def test_switch_update_switch(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + device_data = await hive_session.switch.getSwitch(switch) + + assert device_data != {} + + +@pytest.mark.asyncio +async def test_switch_get_plug_state(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + state = await hive_session.switch.getSwitchState(switch) + + assert state in (True, False) + + +@pytest.mark.asyncio +async def test_switch_get_heat_on_demand_state(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][0] + state = await hive_session.switch.getSwitchState(switch) + + assert state in (True, False) + + +@pytest.mark.asyncio +async def test_switch_turn_on_successfully(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + return_value={"original": 200, "parsed": {}}, + ) as api_call: + result = await hive_session.switch.turnOn(switch) + + assert result is True + assert len(api_call.mock_calls) == 1 + + +@pytest.mark.asyncio +async def test_switch_turn_off_unsuccessfully(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + return_value={"original": 401, "parsed": {}}, + ) as api_call: + result = await hive_session.switch.turnOff(switch) + + assert result is False + assert len(api_call.mock_calls) == 1 + + +@pytest.mark.asyncio +async def test_switch_heat_on_demand_turn_on_successfully(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][0] + + with patch( + "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + return_value={"original": 200, "parsed": {}}, + ) as api_call: + result = await hive_session.switch.turnOn(switch) + + assert result is True + assert len(api_call.mock_calls) == 1 + + +@pytest.mark.asyncio +async def test_switch_heat_on_demand_turn_on_unsuccessfully(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][0] + + with patch( + "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + return_value={"original": 401, "parsed": {}}, + ) as api_call: + result = await hive_session.switch.turnOff(switch) + + assert result is False + assert len(api_call.mock_calls) == 1 + + +@pytest.mark.asyncio +async def test_plug_get_power_usage(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + power_usage = await hive_session.switch.getPowerUsage(switch) + + assert power_usage is not None diff --git a/tests/apyhiveapi/test_session.py b/tests/apyhiveapi/test_session.py index 7dda40e..5a2be39 100644 --- a/tests/apyhiveapi/test_session.py +++ b/tests/apyhiveapi/test_session.py @@ -1,8 +1,10 @@ """Tests for the session object.""" -from tests.common import MockSession import pytest +from tests.common import MockSession + + @pytest.mark.asyncio async def test_start_session(): """Test a session can be started.""" diff --git a/tests/common.py b/tests/common.py index 03a11bc..10a5e35 100644 --- a/tests/common.py +++ b/tests/common.py @@ -46,10 +46,6 @@ def __init__(self): self.async_hive = None self.sync_hive = None - def __exit__(self, exc_type, exc_value, traceback): - """Exit the mock session.""" - self.loop.close() - def sync_start_session(self): """Start a sync session.""" self.sync_hive = HiveSync(username=USERNAME, password=PASSWORD) diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py index 5bf6550..abd7df4 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_plug.py @@ -5,7 +5,40 @@ from tests.common import MockSession -def test_switch_turn_on_success(): +def test_switch_update_switch(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + device_data = hive_session.switch.getSwitch(switch) + + assert device_data != {} + + +def test_switch_get_plug_state(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + state = hive_session.switch.getSwitchState(switch) + + assert state in (True, False) + + +def test_switch_get_heat_on_demand_state(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][0] + state = hive_session.switch.getSwitchState(switch) + + assert state in (True, False) + + +def test_switch_turn_on_successfully(): """Test a session can be started.""" hive = MockSession() hive.sync_start_session() @@ -20,3 +53,65 @@ def test_switch_turn_on_success(): assert result is True assert len(api_call.mock_calls) == 1 + + +def test_switch_turn_off_unsuccessfully(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "pyhiveapi.api.hive_api.HiveApi.setState", + return_value={"original": 401, "parsed": {}}, + ) as api_call: + result = hive_session.switch.turnOff(switch) + + assert result is False + assert len(api_call.mock_calls) == 1 + + +def switch_heat_on_demand_turn_on_successfully(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][0] + + with patch( + "pyhiveapi.api.hive_api.HiveApi.setState", + return_value={"original": 200, "parsed": {}}, + ) as api_call: + result = hive_session.switch.turnOn(switch) + + assert result is True + assert len(api_call.mock_calls) == 1 + + +def test_switch_heat_on_demand_turn_on_unsuccessfully(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][0] + + with patch( + "pyhiveapi.api.hive_api.HiveApi.setState", + return_value={"original": 401, "parsed": {}}, + ) as api_call: + result = hive_session.switch.turnOff(switch) + + assert result is False + assert len(api_call.mock_calls) == 1 + + +def test_plug_get_power_usage(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + power_usage = hive_session.switch.getPowerUsage(switch) + + assert power_usage is not None From d989f1dec33a04bb1a11950ea3663c84a0ea9384 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 2 Jul 2022 19:36:41 +0100 Subject: [PATCH 07/26] updates tests --- tests/apyhiveapi/test_plug.py | 13 +++++++++++++ tests/pyhiveapi/test_plug.py | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tests/apyhiveapi/test_plug.py b/tests/apyhiveapi/test_plug.py index 6b390c1..c5293bf 100644 --- a/tests/apyhiveapi/test_plug.py +++ b/tests/apyhiveapi/test_plug.py @@ -31,6 +31,19 @@ async def test_switch_get_plug_state(): assert state in (True, False) +@pytest.mark.asyncio +async def test_switch_get_plug_state_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + hive_session.session.data.products.pop(switch["hiveID"]) + state = await hive_session.switch.getState(switch) + + assert state is None + + @pytest.mark.asyncio async def test_switch_get_heat_on_demand_state(): """Test a session can be started.""" diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py index abd7df4..7f62dc5 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_plug.py @@ -27,6 +27,18 @@ def test_switch_get_plug_state(): assert state in (True, False) +def test_switch_get_plug_state_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + hive_session.session.data.products.pop(switch["hiveID"]) + state = hive_session.switch.getState(switch) + + assert state is None + + def test_switch_get_heat_on_demand_state(): """Test a session can be started.""" hive = MockSession() From 9076e5e788824f703c3b89d27da6f8122580f961 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 9 Jul 2022 11:11:59 +0100 Subject: [PATCH 08/26] rename core folder from pyhiveapi to src --- .github/workflows/ci.yml | 24 +++++++++---------- MANIFEST.in | 2 +- setup.cfg | 8 +++---- setup.py | 4 ++-- {pyhiveapi => src}/apyhiveapi/__init__.py | 0 {pyhiveapi => src}/apyhiveapi/action.py | 0 {pyhiveapi => src}/apyhiveapi/alarm.py | 0 {pyhiveapi => src}/apyhiveapi/api/__init__.py | 0 {pyhiveapi => src}/apyhiveapi/api/hive_api.py | 0 .../apyhiveapi/api/hive_async_api.py | 0 .../apyhiveapi/api/hive_auth.py | 0 .../apyhiveapi/api/hive_auth_async.py | 0 {pyhiveapi => src}/apyhiveapi/camera.py | 0 .../apyhiveapi/device_attributes.py | 0 {pyhiveapi => src}/apyhiveapi/heating.py | 0 .../apyhiveapi/helper/__init__.py | 0 {pyhiveapi => src}/apyhiveapi/helper/const.py | 0 .../apyhiveapi/helper/debugger.py | 0 .../apyhiveapi/helper/hive_exceptions.py | 0 .../apyhiveapi/helper/hive_helper.py | 0 .../apyhiveapi/helper/hivedataclasses.py | 0 .../apyhiveapi/helper/logger.py | 0 {pyhiveapi => src}/apyhiveapi/helper/map.py | 0 {pyhiveapi => src}/apyhiveapi/hive.py | 0 {pyhiveapi => src}/apyhiveapi/hotwater.py | 0 {pyhiveapi => src}/apyhiveapi/hub.py | 0 {pyhiveapi => src}/apyhiveapi/light.py | 0 {pyhiveapi => src}/apyhiveapi/plug.py | 0 {pyhiveapi => src}/apyhiveapi/sensor.py | 0 {pyhiveapi => src}/apyhiveapi/session.py | 1 + .../apyhiveapi/test_data/alarm.json | 0 .../apyhiveapi/test_data/cameraImage.json | 0 .../apyhiveapi/test_data/cameraRecording.json | 0 .../apyhiveapi/test_data/data.json | 0 34 files changed, 20 insertions(+), 19 deletions(-) rename {pyhiveapi => src}/apyhiveapi/__init__.py (100%) rename {pyhiveapi => src}/apyhiveapi/action.py (100%) rename {pyhiveapi => src}/apyhiveapi/alarm.py (100%) rename {pyhiveapi => src}/apyhiveapi/api/__init__.py (100%) rename {pyhiveapi => src}/apyhiveapi/api/hive_api.py (100%) rename {pyhiveapi => src}/apyhiveapi/api/hive_async_api.py (100%) rename {pyhiveapi => src}/apyhiveapi/api/hive_auth.py (100%) rename {pyhiveapi => src}/apyhiveapi/api/hive_auth_async.py (100%) rename {pyhiveapi => src}/apyhiveapi/camera.py (100%) rename {pyhiveapi => src}/apyhiveapi/device_attributes.py (100%) rename {pyhiveapi => src}/apyhiveapi/heating.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/__init__.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/const.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/debugger.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/hive_exceptions.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/hive_helper.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/hivedataclasses.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/logger.py (100%) rename {pyhiveapi => src}/apyhiveapi/helper/map.py (100%) rename {pyhiveapi => src}/apyhiveapi/hive.py (100%) rename {pyhiveapi => src}/apyhiveapi/hotwater.py (100%) rename {pyhiveapi => src}/apyhiveapi/hub.py (100%) rename {pyhiveapi => src}/apyhiveapi/light.py (100%) rename {pyhiveapi => src}/apyhiveapi/plug.py (100%) rename {pyhiveapi => src}/apyhiveapi/sensor.py (100%) rename {pyhiveapi => src}/apyhiveapi/session.py (99%) rename {pyhiveapi => src}/apyhiveapi/test_data/alarm.json (100%) rename {pyhiveapi => src}/apyhiveapi/test_data/cameraImage.json (100%) rename {pyhiveapi => src}/apyhiveapi/test_data/cameraRecording.json (100%) rename {pyhiveapi => src}/apyhiveapi/test_data/data.json (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4966248..a4c0797 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,9 +36,9 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} restore-keys: | - ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements_test.txt') }}- + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements_test_all.txt') }}- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }} ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}- - name: Create Python virtual environment @@ -47,7 +47,7 @@ jobs: python -m venv venv . venv/bin/activate pip install -U "pip<20.3" setuptools - pip install -r requirements.txt -r requirements_test.txt + pip install -r requirements.txt -r requirements_test_all.txt - name: Restore pre-commit environment from cache id: cache-precommit uses: actions/cache@v2.1.4 @@ -84,7 +84,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -128,7 +128,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -172,7 +172,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -219,7 +219,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -266,7 +266,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -313,7 +313,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -357,7 +357,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -404,7 +404,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | @@ -448,7 +448,7 @@ jobs: ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ - hashFiles('requirements_test.txt') }} + hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' run: | diff --git a/MANIFEST.in b/MANIFEST.in index 776f831..209f3fa 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ recursive-include pyhiveapi * include requirements.txt -include requirements_test.txt +include requirements_test_all.txt recursive-include data * \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 9378ff1..59abc13 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,8 +3,8 @@ name = pyhiveapi description = A Python library to interface with the Hive API keywords = Hive API Library license = MIT -author = Rendili -author_email = rendili@outlook.com +author = KJonline +author_email = kjtech6@outlook.com url = https://github.com/Pyhive/pyhiveapi project_urls = Source = https://github.com/Pyhive/Pyhiveapi @@ -20,12 +20,12 @@ classifiers = [options] package_dir = - = pyhiveapi + = src packages = find: python_requires = >=3.6.* [options.packages.find] -where = pyhiveapi +where = src [build-system] requires = ["setuptools>=40.6.2", "wheel", "unasync"] diff --git a/setup.py b/setup.py index 9d8b338..6e0fbff 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ def requirements_from_file(filename="requirements.txt"): setup( - version="0.5.13", + version="0.5.14", package_data={"data": ["*.json"]}, include_package_data=True, cmdclass={ @@ -33,5 +33,5 @@ def requirements_from_file(filename="requirements.txt"): ) }, install_requires=requirements_from_file(), - extras_require={"dev": requirements_from_file("requirements_test.txt")}, + extras_require={"dev": requirements_from_file("requirements_test_all.txt")}, ) diff --git a/pyhiveapi/apyhiveapi/__init__.py b/src/apyhiveapi/__init__.py similarity index 100% rename from pyhiveapi/apyhiveapi/__init__.py rename to src/apyhiveapi/__init__.py diff --git a/pyhiveapi/apyhiveapi/action.py b/src/apyhiveapi/action.py similarity index 100% rename from pyhiveapi/apyhiveapi/action.py rename to src/apyhiveapi/action.py diff --git a/pyhiveapi/apyhiveapi/alarm.py b/src/apyhiveapi/alarm.py similarity index 100% rename from pyhiveapi/apyhiveapi/alarm.py rename to src/apyhiveapi/alarm.py diff --git a/pyhiveapi/apyhiveapi/api/__init__.py b/src/apyhiveapi/api/__init__.py similarity index 100% rename from pyhiveapi/apyhiveapi/api/__init__.py rename to src/apyhiveapi/api/__init__.py diff --git a/pyhiveapi/apyhiveapi/api/hive_api.py b/src/apyhiveapi/api/hive_api.py similarity index 100% rename from pyhiveapi/apyhiveapi/api/hive_api.py rename to src/apyhiveapi/api/hive_api.py diff --git a/pyhiveapi/apyhiveapi/api/hive_async_api.py b/src/apyhiveapi/api/hive_async_api.py similarity index 100% rename from pyhiveapi/apyhiveapi/api/hive_async_api.py rename to src/apyhiveapi/api/hive_async_api.py diff --git a/pyhiveapi/apyhiveapi/api/hive_auth.py b/src/apyhiveapi/api/hive_auth.py similarity index 100% rename from pyhiveapi/apyhiveapi/api/hive_auth.py rename to src/apyhiveapi/api/hive_auth.py diff --git a/pyhiveapi/apyhiveapi/api/hive_auth_async.py b/src/apyhiveapi/api/hive_auth_async.py similarity index 100% rename from pyhiveapi/apyhiveapi/api/hive_auth_async.py rename to src/apyhiveapi/api/hive_auth_async.py diff --git a/pyhiveapi/apyhiveapi/camera.py b/src/apyhiveapi/camera.py similarity index 100% rename from pyhiveapi/apyhiveapi/camera.py rename to src/apyhiveapi/camera.py diff --git a/pyhiveapi/apyhiveapi/device_attributes.py b/src/apyhiveapi/device_attributes.py similarity index 100% rename from pyhiveapi/apyhiveapi/device_attributes.py rename to src/apyhiveapi/device_attributes.py diff --git a/pyhiveapi/apyhiveapi/heating.py b/src/apyhiveapi/heating.py similarity index 100% rename from pyhiveapi/apyhiveapi/heating.py rename to src/apyhiveapi/heating.py diff --git a/pyhiveapi/apyhiveapi/helper/__init__.py b/src/apyhiveapi/helper/__init__.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/__init__.py rename to src/apyhiveapi/helper/__init__.py diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/src/apyhiveapi/helper/const.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/const.py rename to src/apyhiveapi/helper/const.py diff --git a/pyhiveapi/apyhiveapi/helper/debugger.py b/src/apyhiveapi/helper/debugger.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/debugger.py rename to src/apyhiveapi/helper/debugger.py diff --git a/pyhiveapi/apyhiveapi/helper/hive_exceptions.py b/src/apyhiveapi/helper/hive_exceptions.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/hive_exceptions.py rename to src/apyhiveapi/helper/hive_exceptions.py diff --git a/pyhiveapi/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/hive_helper.py rename to src/apyhiveapi/helper/hive_helper.py diff --git a/pyhiveapi/apyhiveapi/helper/hivedataclasses.py b/src/apyhiveapi/helper/hivedataclasses.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/hivedataclasses.py rename to src/apyhiveapi/helper/hivedataclasses.py diff --git a/pyhiveapi/apyhiveapi/helper/logger.py b/src/apyhiveapi/helper/logger.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/logger.py rename to src/apyhiveapi/helper/logger.py diff --git a/pyhiveapi/apyhiveapi/helper/map.py b/src/apyhiveapi/helper/map.py similarity index 100% rename from pyhiveapi/apyhiveapi/helper/map.py rename to src/apyhiveapi/helper/map.py diff --git a/pyhiveapi/apyhiveapi/hive.py b/src/apyhiveapi/hive.py similarity index 100% rename from pyhiveapi/apyhiveapi/hive.py rename to src/apyhiveapi/hive.py diff --git a/pyhiveapi/apyhiveapi/hotwater.py b/src/apyhiveapi/hotwater.py similarity index 100% rename from pyhiveapi/apyhiveapi/hotwater.py rename to src/apyhiveapi/hotwater.py diff --git a/pyhiveapi/apyhiveapi/hub.py b/src/apyhiveapi/hub.py similarity index 100% rename from pyhiveapi/apyhiveapi/hub.py rename to src/apyhiveapi/hub.py diff --git a/pyhiveapi/apyhiveapi/light.py b/src/apyhiveapi/light.py similarity index 100% rename from pyhiveapi/apyhiveapi/light.py rename to src/apyhiveapi/light.py diff --git a/pyhiveapi/apyhiveapi/plug.py b/src/apyhiveapi/plug.py similarity index 100% rename from pyhiveapi/apyhiveapi/plug.py rename to src/apyhiveapi/plug.py diff --git a/pyhiveapi/apyhiveapi/sensor.py b/src/apyhiveapi/sensor.py similarity index 100% rename from pyhiveapi/apyhiveapi/sensor.py rename to src/apyhiveapi/sensor.py diff --git a/pyhiveapi/apyhiveapi/session.py b/src/apyhiveapi/session.py similarity index 99% rename from pyhiveapi/apyhiveapi/session.py rename to src/apyhiveapi/session.py index 3b5a739..fda968c 100644 --- a/pyhiveapi/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -8,6 +8,7 @@ from datetime import datetime, timedelta from aiohttp.web import HTTPException + from apyhiveapi import API, Auth from . import PATH diff --git a/pyhiveapi/apyhiveapi/test_data/alarm.json b/src/apyhiveapi/test_data/alarm.json similarity index 100% rename from pyhiveapi/apyhiveapi/test_data/alarm.json rename to src/apyhiveapi/test_data/alarm.json diff --git a/pyhiveapi/apyhiveapi/test_data/cameraImage.json b/src/apyhiveapi/test_data/cameraImage.json similarity index 100% rename from pyhiveapi/apyhiveapi/test_data/cameraImage.json rename to src/apyhiveapi/test_data/cameraImage.json diff --git a/pyhiveapi/apyhiveapi/test_data/cameraRecording.json b/src/apyhiveapi/test_data/cameraRecording.json similarity index 100% rename from pyhiveapi/apyhiveapi/test_data/cameraRecording.json rename to src/apyhiveapi/test_data/cameraRecording.json diff --git a/pyhiveapi/apyhiveapi/test_data/data.json b/src/apyhiveapi/test_data/data.json similarity index 100% rename from pyhiveapi/apyhiveapi/test_data/data.json rename to src/apyhiveapi/test_data/data.json From c5c4aa061dbed743a818f0e401b1c6e2d78b1902 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 9 Jul 2022 11:19:32 +0100 Subject: [PATCH 09/26] update tasks --- .vscode/tasks.json | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index bf8a4ac..5848bb1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -5,7 +5,7 @@ "label": "Pytest", "type": "shell", "command": "pytest --timeout=10 tests", - "dependsOn": ["Install all Test Requirements"], + "dependsOn": ["Install all Test Requirements", "Install Package Locally"], "group": { "kind": "test", "isDefault": true @@ -33,7 +33,7 @@ { "label": "Pylint", "type": "shell", - "command": "pylint homeassistant", + "command": "pylint src", "dependsOn": ["Install all Requirements"], "group": { "kind": "test", @@ -49,8 +49,8 @@ "label": "Code Coverage", "detail": "Generate code coverage report for a given integration.", "type": "shell", - "command": "pytest --cov-report html --cov=apyhiveapi tests/", - "dependsOn": ["Install all Test Requirements"], + "command": "pytest --cov-report html --cov=apyhiveapi tests/apyhiveapi && pytest --cov-report html --cov=pyhiveapi --cov-append tests/pyhiveapi", + "dependsOn": ["Install all Test Requirements", "Install Package Locally"], "group": { "kind": "test", "isDefault": true @@ -89,6 +89,20 @@ }, "problemMatcher": [] }, + { + "label": "Install Package Locally", + "type": "shell", + "command": "pip3 install --upgrade --use-deprecated=legacy-resolver .", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, ], "inputs": [] } From 15b0721b174ef8826f0aa11564968d0f0fded2a3 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 9 Jul 2022 11:21:14 +0100 Subject: [PATCH 10/26] update requirments text file --- .github/workflows/ci.yml | 26 +++++++++++++------------- .github/workflows/python-package.yml | 2 +- MANIFEST.in | 4 ++-- setup.py | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4c0797..547fb1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,11 +35,11 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} restore-keys: | - ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements_test_all.txt') }}- - ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements.txt') }} + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }}- + ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ hashFiles('requirements_all.txt') }} ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}- - name: Create Python virtual environment if: steps.cache-venv.outputs.cache-hit != 'true' @@ -47,7 +47,7 @@ jobs: python -m venv venv . venv/bin/activate pip install -U "pip<20.3" setuptools - pip install -r requirements.txt -r requirements_test_all.txt + pip install -r requirements_all.txt -r requirements_test_all.txt - name: Restore pre-commit environment from cache id: cache-precommit uses: actions/cache@v2.1.4 @@ -83,7 +83,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -127,7 +127,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -171,7 +171,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -218,7 +218,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -265,7 +265,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -312,7 +312,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -356,7 +356,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -403,7 +403,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' @@ -447,7 +447,7 @@ jobs: key: >- ${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{ steps.python.outputs.python-version }}-${{ - hashFiles('requirements.txt') }}-${{ + hashFiles('requirements_all.txt') }}-${{ hashFiles('requirements_test_all.txt') }} - name: Fail job if Python cache restore failed if: steps.cache-venv.outputs.cache-hit != 'true' diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 4342e45..9c6a901 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -23,7 +23,7 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install flake8 - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + if [ -f requirements_all.txt ]; then pip install -r requirements_all.txt; fi - name: Lint with flake8 run: | # stop the build if there are Python syntax errors. diff --git a/MANIFEST.in b/MANIFEST.in index 209f3fa..d04c8c0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -recursive-include pyhiveapi * -include requirements.txt +recursive-include src * +include requirements_all.txt include requirements_test_all.txt recursive-include data * \ No newline at end of file diff --git a/setup.py b/setup.py index 6e0fbff..aaf298e 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ from setuptools import setup -def requirements_from_file(filename="requirements.txt"): +def requirements_from_file(filename="requirements_all.txt"): """Get requirements from file.""" with open(os.path.join(os.path.dirname(__file__), filename)) as r: reqs = r.read().strip().split("\n") From e34dbd8a59b12cd462e551c1649ed4431838db6f Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 9 Jul 2022 11:21:57 +0100 Subject: [PATCH 11/26] update filename for requirements_all.txt --- requirements.txt => requirements_all.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename requirements.txt => requirements_all.txt (100%) diff --git a/requirements.txt b/requirements_all.txt similarity index 100% rename from requirements.txt rename to requirements_all.txt From 0f50e54c25183e2b49ba38dbb5d4a89ffe7ed75f Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 9 Jul 2022 11:39:36 +0100 Subject: [PATCH 12/26] update tasks and coverage --- .coveragerc | 4 ++++ .vscode/tasks.json | 8 +++++++- src/apyhiveapi/helper/const.py | 6 ------ 3 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..f34ec9a --- /dev/null +++ b/.coveragerc @@ -0,0 +1,4 @@ +[run] +source = src +omit = + */__init__.py \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5848bb1..4e6f625 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,6 +3,7 @@ "tasks": [ { "label": "Pytest", + "detail": "Execute pytest tests for pyhiveapi/apyhiveapi", "type": "shell", "command": "pytest --timeout=10 tests", "dependsOn": ["Install all Test Requirements", "Install Package Locally"], @@ -18,6 +19,7 @@ }, { "label": "Flake8", + "detail": "Run flake8 checks on the libary", "type": "shell", "command": "pre-commit run flake8 --all-files", "group": { @@ -32,6 +34,7 @@ }, { "label": "Pylint", + "detail": "Run pylint checks on the libary", "type": "shell", "command": "pylint src", "dependsOn": ["Install all Requirements"], @@ -47,7 +50,7 @@ }, { "label": "Code Coverage", - "detail": "Generate code coverage report for a given integration.", + "detail": "Generate local code coverage report.", "type": "shell", "command": "pytest --cov-report html --cov=apyhiveapi tests/apyhiveapi && pytest --cov-report html --cov=pyhiveapi --cov-append tests/pyhiveapi", "dependsOn": ["Install all Test Requirements", "Install Package Locally"], @@ -63,6 +66,7 @@ }, { "label": "Install all Requirements", + "detail": "Install all requirements needed to run pyhiveapi/apyihiveapi ", "type": "shell", "command": "pip3 install --use-deprecated=legacy-resolver -r requirements_all.txt", "group": { @@ -77,6 +81,7 @@ }, { "label": "Install all Test Requirements", + "detail": "Install all test requirement for pytest.", "type": "shell", "command": "pip3 install --use-deprecated=legacy-resolver -r requirements_test_all.txt", "group": { @@ -91,6 +96,7 @@ }, { "label": "Install Package Locally", + "detail": "Install pyhiveapi/apyhiveapi locally.", "type": "shell", "command": "pip3 install --upgrade --use-deprecated=legacy-resolver .", "group": { diff --git a/src/apyhiveapi/helper/const.py b/src/apyhiveapi/helper/const.py index 854d274..994d6b0 100644 --- a/src/apyhiveapi/helper/const.py +++ b/src/apyhiveapi/helper/const.py @@ -1,12 +1,6 @@ """Constants for Pyhiveapi.""" - -SYNC_PACKAGE_NAME = "pyhiveapi" -SYNC_PACKAGE_DIR = "/pyhiveapi/" -ASYNC_PACKAGE_NAME = "apyhiveapi" -ASYNC_PACKAGE_DIR = "/apyhiveapi/" SMS_REQUIRED = "SMS_MFA" - # HTTP return codes. HTTP_OK = 200 HTTP_CREATED = 201 From c0b81b4ca429620edec82a488cfd50e5c01bd812 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 9 Jul 2022 13:57:32 +0100 Subject: [PATCH 13/26] add hub tests --- .coveragerc | 3 +- tests/apyhiveapi/test_hub.py | 126 ++++++++++++++++++++++++++++++++++ tests/apyhiveapi/test_plug.py | 64 ++++++++++++++++- tests/pyhiveapi/test_hub.py | 115 +++++++++++++++++++++++++++++++ tests/pyhiveapi/test_plug.py | 62 ++++++++++++++++- 5 files changed, 366 insertions(+), 4 deletions(-) create mode 100644 tests/apyhiveapi/test_hub.py create mode 100644 tests/pyhiveapi/test_hub.py diff --git a/.coveragerc b/.coveragerc index f34ec9a..7b55066 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,4 +1,5 @@ [run] source = src omit = - */__init__.py \ No newline at end of file + */__init__.py + */debugger.py \ No newline at end of file diff --git a/tests/apyhiveapi/test_hub.py b/tests/apyhiveapi/test_hub.py new file mode 100644 index 0000000..e5fd03e --- /dev/null +++ b/tests/apyhiveapi/test_hub.py @@ -0,0 +1,126 @@ +"""Tests for the hub object.""" + +import pytest + +from tests.common import MockSession + + +@pytest.mark.asyncio +async def test_hub_get_smoke_status_detected(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + smoke_sensor = hive_session.session.device_list["binary_sensor"][1] + hive_session.session.data.products[smoke_sensor["hiveID"]]["props"]["sensors"][ + "SMOKE_CO" + ]["active"] = True + state = await hive_session.hub.getSmokeStatus(smoke_sensor) + + assert state == 1 + + +@pytest.mark.asyncio +async def test_hub_get_smoke_status_not_detected(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + smoke_sensor = hive_session.session.device_list["binary_sensor"][1] + + state = await hive_session.hub.getSmokeStatus(smoke_sensor) + + assert state == 0 + + +@pytest.mark.asyncio +async def test_hub_get_smoke_status_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + smoke_sensor = hive_session.session.device_list["binary_sensor"][1] + hive_session.session.data.products.pop(smoke_sensor["hiveID"]) + state = await hive_session.hub.getSmokeStatus(smoke_sensor) + + assert state is None + + +@pytest.mark.asyncio +async def test_hub_get_glass_break_detected(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + glass_sensor = hive_session.session.device_list["binary_sensor"][0] + state = await hive_session.hub.getGlassBreakStatus(glass_sensor) + + assert state == 1 + + +@pytest.mark.asyncio +async def test_hub_get_glass_break_not_detected(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + glass_sensor = hive_session.session.device_list["binary_sensor"][1] + hive_session.session.data.products[glass_sensor["hiveID"]]["props"]["sensors"][ + "GLASS_BREAK" + ]["active"] = False + state = await hive_session.hub.getGlassBreakStatus(glass_sensor) + + assert state == 0 + + +@pytest.mark.asyncio +async def test_hub_get_glass_break_detection_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + glass_sensor = hive_session.session.device_list["binary_sensor"][0] + hive_session.session.data.products.pop(glass_sensor["hiveID"]) + state = await hive_session.hub.getGlassBreakStatus(glass_sensor) + + assert state is None + + +@pytest.mark.asyncio +async def test_hub_get_dog_bark_detected(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + dog_sensor = hive_session.session.device_list["binary_sensor"][2] + hive_session.session.data.products[dog_sensor["hiveID"]]["props"]["sensors"][ + "DOG_BARK" + ]["active"] = True + state = await hive_session.hub.getDogBarkStatus(dog_sensor) + + assert state == 1 + + +@pytest.mark.asyncio +async def test_hub_get_dog_bark_not_detected(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + dog_sensor = hive_session.session.device_list["binary_sensor"][2] + state = await hive_session.hub.getDogBarkStatus(dog_sensor) + + assert state == 0 + + +@pytest.mark.asyncio +async def test_hub_get_dog_bark_detection_status_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + dog_sensor = hive_session.session.device_list["binary_sensor"][2] + hive_session.session.data.products.pop(dog_sensor["hiveID"]) + state = await hive_session.hub.getDogBarkStatus(dog_sensor) + + assert state is None diff --git a/tests/apyhiveapi/test_plug.py b/tests/apyhiveapi/test_plug.py index c5293bf..8238124 100644 --- a/tests/apyhiveapi/test_plug.py +++ b/tests/apyhiveapi/test_plug.py @@ -8,7 +8,7 @@ @pytest.mark.asyncio -async def test_switch_update_switch(): +async def test_switch_update_switch_online(): """Test a session can be started.""" hive = MockSession() await hive.async_start_session() @@ -19,6 +19,19 @@ async def test_switch_update_switch(): assert device_data != {} +@pytest.mark.asyncio +async def test_switch_update_switch_offline(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + switch["deviceData"]["online"] = False + device_data = await hive_session.switch.getSwitch(switch) + + assert device_data["hiveID"] in hive_session.session.config.errorList + + @pytest.mark.asyncio async def test_switch_get_plug_state(): """Test a session can be started.""" @@ -74,6 +87,42 @@ async def test_switch_turn_on_successfully(): assert len(api_call.mock_calls) == 1 +@pytest.mark.asyncio +async def test_switch_turn_on_unsuccessfully(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + return_value={"original": 401, "parsed": {}}, + ) as api_call: + result = await hive_session.switch.turnOn(switch) + + assert result is False + assert len(api_call.mock_calls) == 1 + + +@pytest.mark.asyncio +async def test_switch_turn_off_successfully(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + return_value={"original": 200, "parsed": {}}, + ) as api_call: + result = await hive_session.switch.turnOff(switch) + + assert result is True + assert len(api_call.mock_calls) == 1 + + @pytest.mark.asyncio async def test_switch_turn_off_unsuccessfully(): """Test a session can be started.""" @@ -138,3 +187,16 @@ async def test_plug_get_power_usage(): power_usage = await hive_session.switch.getPowerUsage(switch) assert power_usage is not None + + +@pytest.mark.asyncio +async def test_plug_get_power_usage_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + await hive.async_start_session() + hive_session = hive.async_hive + switch = hive_session.session.device_list["switch"][1] + hive_session.session.data.products.pop(switch["hiveID"]) + state = await hive_session.switch.getPowerUsage(switch) + + assert state is None diff --git a/tests/pyhiveapi/test_hub.py b/tests/pyhiveapi/test_hub.py new file mode 100644 index 0000000..46d3c69 --- /dev/null +++ b/tests/pyhiveapi/test_hub.py @@ -0,0 +1,115 @@ +"""Tests for the hub object.""" + +from tests.common import MockSession + + +def test_hub_get_smoke_status_detected(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + smoke_sensor = hive_session.session.device_list["binary_sensor"][1] + hive_session.session.data.products[smoke_sensor["hiveID"]]["props"]["sensors"][ + "SMOKE_CO" + ]["active"] = True + state = hive_session.hub.getSmokeStatus(smoke_sensor) + + assert state == 1 + + +def test_hub_get_smoke_status_not_detected(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + smoke_sensor = hive_session.session.device_list["binary_sensor"][1] + + state = hive_session.hub.getSmokeStatus(smoke_sensor) + + assert state == 0 + + +def test_hub_get_smoke_status_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + smoke_sensor = hive_session.session.device_list["binary_sensor"][1] + hive_session.session.data.products.pop(smoke_sensor["hiveID"]) + state = hive_session.hub.getSmokeStatus(smoke_sensor) + + assert state is None + + +def test_hub_get_glass_break_detected(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + glass_sensor = hive_session.session.device_list["binary_sensor"][0] + state = hive_session.hub.getGlassBreakStatus(glass_sensor) + + assert state == 1 + + +def test_hub_get_glass_break_not_detected(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + glass_sensor = hive_session.session.device_list["binary_sensor"][1] + hive_session.session.data.products[glass_sensor["hiveID"]]["props"]["sensors"][ + "GLASS_BREAK" + ]["active"] = False + state = hive_session.hub.getGlassBreakStatus(glass_sensor) + + assert state == 0 + + +def test_hub_get_glass_break_detection_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + glass_sensor = hive_session.session.device_list["binary_sensor"][0] + hive_session.session.data.products.pop(glass_sensor["hiveID"]) + state = hive_session.hub.getGlassBreakStatus(glass_sensor) + + assert state is None + + +def test_hub_get_dog_bark_detected(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + dog_sensor = hive_session.session.device_list["binary_sensor"][2] + hive_session.session.data.products[dog_sensor["hiveID"]]["props"]["sensors"][ + "DOG_BARK" + ]["active"] = True + state = hive_session.hub.getDogBarkStatus(dog_sensor) + + assert state == 1 + + +def test_hub_get_dog_bark_not_detected(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + dog_sensor = hive_session.session.device_list["binary_sensor"][2] + state = hive_session.hub.getDogBarkStatus(dog_sensor) + + assert state == 0 + + +def test_hub_get_dog_bark_detection_status_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + dog_sensor = hive_session.session.device_list["binary_sensor"][2] + hive_session.session.data.products.pop(dog_sensor["hiveID"]) + state = hive_session.hub.getDogBarkStatus(dog_sensor) + + assert state is None diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py index 7f62dc5..50b81a8 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_plug.py @@ -5,7 +5,7 @@ from tests.common import MockSession -def test_switch_update_switch(): +def test_switch_update_switch_online(): """Test a session can be started.""" hive = MockSession() hive.sync_start_session() @@ -16,6 +16,18 @@ def test_switch_update_switch(): assert device_data != {} +def test_switch_update_switch_offline(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + switch["deviceData"]["online"] = False + device_data = hive_session.switch.getSwitch(switch) + + assert device_data["hiveID"] in hive_session.session.config.errorList + + def test_switch_get_plug_state(): """Test a session can be started.""" hive = MockSession() @@ -67,6 +79,40 @@ def test_switch_turn_on_successfully(): assert len(api_call.mock_calls) == 1 +def test_switch_turn_on_unsuccessfully(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "pyhiveapi.api.hive_api.HiveApi.setState", + return_value={"original": 401, "parsed": {}}, + ) as api_call: + result = hive_session.switch.turnOn(switch) + + assert result is False + assert len(api_call.mock_calls) == 1 + + +def test_switch_turn_off_successfully(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + + with patch( + "pyhiveapi.api.hive_api.HiveApi.setState", + return_value={"original": 200, "parsed": {}}, + ) as api_call: + result = hive_session.switch.turnOff(switch) + + assert result is True + assert len(api_call.mock_calls) == 1 + + def test_switch_turn_off_unsuccessfully(): """Test a session can be started.""" hive = MockSession() @@ -84,7 +130,7 @@ def test_switch_turn_off_unsuccessfully(): assert len(api_call.mock_calls) == 1 -def switch_heat_on_demand_turn_on_successfully(): +def test_switch_heat_on_demand_turn_on_successfully(): """Test a session can be started.""" hive = MockSession() hive.sync_start_session() @@ -127,3 +173,15 @@ def test_plug_get_power_usage(): power_usage = hive_session.switch.getPowerUsage(switch) assert power_usage is not None + + +def test_plug_get_power_usage_with_key_error(): + """Test a session can be started.""" + hive = MockSession() + hive.sync_start_session() + hive_session = hive.sync_hive + switch = hive_session.session.device_list["switch"][1] + hive_session.session.data.products.pop(switch["hiveID"]) + state = hive_session.switch.getPowerUsage(switch) + + assert state is None From 2d3d1faa94e2367fa079a65e73fe8e8b931c56f4 Mon Sep 17 00:00:00 2001 From: ribbal Date: Tue, 23 Jul 2024 10:03:36 +0100 Subject: [PATCH 14/26] fix 'hot water' sensor name format --- pyhiveapi/apyhiveapi/helper/const.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py index 42e8fe7..8345444 100644 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ b/pyhiveapi/apyhiveapi/helper/const.py @@ -101,9 +101,9 @@ ], "hotwater": [ 'addList("water_heater", p,)', - 'addList("sensor", p, haName="Hotwater State", hiveType="Hotwater_State", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Mode", hiveType="Hotwater_Mode", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Boost", hiveType="Hotwater_Boost", category="diagnostic")', + 'addList("sensor", p, haName="Hot Water State", hiveType="Hotwater_State", category="diagnostic")', + 'addList("sensor", p, haName="Hot Water Mode", hiveType="Hotwater_Mode", category="diagnostic")', + 'addList("sensor", p, haName="Hot Water Boost", hiveType="Hotwater_Boost", category="diagnostic")', ], "activeplug": [ 'addList("switch", p)', From 9244d96f9d50e87a28237aff63ff2dca18808926 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Wed, 20 Nov 2024 17:39:26 +0000 Subject: [PATCH 15/26] Update python version and const --- pyhiveapi/apyhiveapi/helper/const.py | 6 +++--- setup.cfg | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py index 42e8fe7..8345444 100644 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ b/pyhiveapi/apyhiveapi/helper/const.py @@ -101,9 +101,9 @@ ], "hotwater": [ 'addList("water_heater", p,)', - 'addList("sensor", p, haName="Hotwater State", hiveType="Hotwater_State", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Mode", hiveType="Hotwater_Mode", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Boost", hiveType="Hotwater_Boost", category="diagnostic")', + 'addList("sensor", p, haName="Hot Water State", hiveType="Hotwater_State", category="diagnostic")', + 'addList("sensor", p, haName="Hot Water Mode", hiveType="Hotwater_Mode", category="diagnostic")', + 'addList("sensor", p, haName="Hot Water Boost", hiveType="Hotwater_Boost", category="diagnostic")', ], "activeplug": [ 'addList("switch", p)', diff --git a/setup.cfg b/setup.cfg index 27b27d3..c81ed27 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,16 +13,17 @@ classifiers = Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: OSI Approved :: MIT License - Programming Language :: Python :: 3.6 - 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 + [options] package_dir = = pyhiveapi packages = find: -python_requires = >=3.6 +python_requires = >=3.8.* [options.packages.find] where = pyhiveapi From f088065a89ee22e7dfbf64d58f1fe816e290ff1a Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 9 Dec 2024 22:51:41 +0000 Subject: [PATCH 16/26] update formatting standards to confrom with pylint --- .gitignore | 1 + .vscode/tasks.json | 205 +++++----- pyhiveapi/apyhiveapi/helper/const.py | 6 +- requirements_test_all.txt | 2 + setup.cfg | 4 +- src/apyhiveapi/action.py | 10 +- src/apyhiveapi/alarm.py | 14 +- src/apyhiveapi/api/hive_api.py | 38 +- src/apyhiveapi/api/hive_async_api.py | 49 ++- src/apyhiveapi/camera.py | 22 +- src/apyhiveapi/device_attributes.py | 14 +- src/apyhiveapi/heating.py | 519 ++++++++++++++++++++++++ src/apyhiveapi/helper/const.py | 119 ++++++ src/apyhiveapi/helper/debugger.py | 8 +- src/apyhiveapi/helper/hive_helper.py | 24 +- src/apyhiveapi/helper/logger.py | 2 +- src/apyhiveapi/hotwater.py | 550 ++++++++++++------------- src/apyhiveapi/hub.py | 6 +- src/apyhiveapi/plug.py | 26 +- src/apyhiveapi/session.py | 579 +++++++++++++++++++++++++++ tests/apyhiveapi/test_hub.py | 18 +- tests/apyhiveapi/test_session.py | 2 +- tests/common.py | 4 +- tests/pyhiveapi/test_hub.py | 20 +- tests/pyhiveapi/test_session.py | 4 +- 25 files changed, 1740 insertions(+), 506 deletions(-) diff --git a/.gitignore b/.gitignore index 65ee091..192a913 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ build dist pyhiveapi.egg-info *.coverage +venv # due to using tox and pytest .tox diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4e6f625..f36eb4a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,115 +1,114 @@ { "version": "2.0.0", "tasks": [ - { - "label": "Pytest", - "detail": "Execute pytest tests for pyhiveapi/apyhiveapi", - "type": "shell", - "command": "pytest --timeout=10 tests", - "dependsOn": ["Install all Test Requirements", "Install Package Locally"], - "group": { - "kind": "test", - "isDefault": true + { + "label": "Pytest", + "detail": "Execute pytest tests for pyhiveapi/apyhiveapi", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pytest", "--timeout=10", "tests"], + "dependsOn": ["Install all Test Requirements", "Install Package Locally"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "presentation": { - "reveal": "always", - "panel": "new" + { + "label": "Flake8", + "detail": "Run flake8 checks on the library", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pre-commit", "run", "flake8", "--all-files"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "problemMatcher": [] - }, - { - "label": "Flake8", - "detail": "Run flake8 checks on the libary", - "type": "shell", - "command": "pre-commit run flake8 --all-files", - "group": { - "kind": "test", - "isDefault": true + { + "label": "Pylint", + "detail": "Run pylint checks on the library", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pylint", "src"], + "dependsOn": ["Install all Requirements"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "presentation": { - "reveal": "always", - "panel": "new" + { + "label": "Code Coverage", + "detail": "Generate local code coverage report.", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pytest", "--cov-report", "html", "--cov=apyhiveapi", "tests/apyhiveapi", "--cov-report", "html", "--cov=pyhiveapi", "--cov-append", "tests/pyhiveapi"], + "dependsOn": ["Install all Test Requirements", "Install Package Locally"], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "problemMatcher": [] - }, - { - "label": "Pylint", - "detail": "Run pylint checks on the libary", - "type": "shell", - "command": "pylint src", - "dependsOn": ["Install all Requirements"], - "group": { - "kind": "test", - "isDefault": true + { + "label": "Install all Requirements", + "detail": "Install all requirements needed to run pyhiveapi/apyihiveapi ", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pip", "install", "-r", "requirements_all.txt"], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "presentation": { - "reveal": "always", - "panel": "new" + { + "label": "Install all Test Requirements", + "detail": "Install all test requirement for pytest.", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pip", "install", "-r", "requirements_test_all.txt"], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "problemMatcher": [] - }, - { - "label": "Code Coverage", - "detail": "Generate local code coverage report.", - "type": "shell", - "command": "pytest --cov-report html --cov=apyhiveapi tests/apyhiveapi && pytest --cov-report html --cov=pyhiveapi --cov-append tests/pyhiveapi", - "dependsOn": ["Install all Test Requirements", "Install Package Locally"], - "group": { - "kind": "test", - "isDefault": true + { + "label": "Install Package Locally", + "detail": "Install pyhiveapi/apyhiveapi locally.", + "type": "shell", + "command": "${command:python.interpreterPath}", + "args": ["-m", "pip", "install", "-e", "."], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always" + }, + "problemMatcher": [] }, - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - }, - { - "label": "Install all Requirements", - "detail": "Install all requirements needed to run pyhiveapi/apyihiveapi ", - "type": "shell", - "command": "pip3 install --use-deprecated=legacy-resolver -r requirements_all.txt", - "group": { - "kind": "build", - "isDefault": true - }, - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - }, - { - "label": "Install all Test Requirements", - "detail": "Install all test requirement for pytest.", - "type": "shell", - "command": "pip3 install --use-deprecated=legacy-resolver -r requirements_test_all.txt", - "group": { - "kind": "build", - "isDefault": true - }, - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - }, - { - "label": "Install Package Locally", - "detail": "Install pyhiveapi/apyhiveapi locally.", - "type": "shell", - "command": "pip3 install --upgrade --use-deprecated=legacy-resolver .", - "group": { - "kind": "build", - "isDefault": true - }, - "presentation": { - "reveal": "always", - "panel": "new" - }, - "problemMatcher": [] - }, ], "inputs": [] - } - \ No newline at end of file +} \ No newline at end of file diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py index 8345444..64e6aaf 100644 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ b/pyhiveapi/apyhiveapi/helper/const.py @@ -56,9 +56,9 @@ "Switch": ["activeplug"], } sensor_commands = { - "SMOKE_CO": "self.session.hub.getSmokeStatus(device)", - "DOG_BARK": "self.session.hub.getDogBarkStatus(device)", - "GLASS_BREAK": "self.session.hub.getGlassBreakStatus(device)", + "SMOKE_CO": "self.session.hub.get_smoke_status(device)", + "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", + "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", "Camera_Temp": "self.session.camera.getCameraTemperature(device)", "Current_Temperature": "self.session.heating.getCurrentTemperature(device)", "Heating_Current_Temperature": "self.session.heating.getCurrentTemperature(device)", diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 5f45c9e..6700af6 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1,4 +1,6 @@ pyhiveapi +pylint pytest pytest-cov +pytest-timeout tox \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 11dbf31..15bcebc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,7 +23,7 @@ classifiers = package_dir = = src packages = find: -python_requires = >=3.8.* +python_requires = >=3.8 [options.packages.find] where = src @@ -69,7 +69,7 @@ warn_unused_configs = true [tool:pytest] minversion = 6.0 -addopts = -ra -q +addopts = -ra -q --timeout=10 testpaths = tests/pyhiveapi tests/apyhiveapi \ No newline at end of file diff --git a/src/apyhiveapi/action.py b/src/apyhiveapi/action.py index 4343e60..04834a9 100644 --- a/src/apyhiveapi/action.py +++ b/src/apyhiveapi/action.py @@ -19,7 +19,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getAction(self, device: dict): + async def get_action(self, device: dict): """Action device to update. Args: @@ -37,7 +37,7 @@ async def getAction(self, device: dict): "hiveType": device["hiveType"], "haName": device["haName"], "haType": device["haType"], - "status": {"state": await self.getState(device)}, + "status": {"state": await self.get_state(device)}, "power_usage": None, "deviceData": {}, "custom": device.get("custom", None), @@ -51,7 +51,7 @@ async def getAction(self, device: dict): return "REMOVE" return device - async def getState(self, device: dict): + async def get_state(self, device: dict): """Get action state. Args: @@ -70,7 +70,7 @@ async def getState(self, device: dict): return final - async def setStatusOn(self, device: dict): + async def set_status_on(self, device: dict): """Set action turn on. Args: @@ -95,7 +95,7 @@ async def setStatusOn(self, device: dict): return final - async def setStatusOff(self, device: dict): + async def set_status_off(self, device: dict): """Set action to turn off. Args: diff --git a/src/apyhiveapi/alarm.py b/src/apyhiveapi/alarm.py index 4250542..177dd31 100644 --- a/src/apyhiveapi/alarm.py +++ b/src/apyhiveapi/alarm.py @@ -11,7 +11,7 @@ class HiveHomeShield: alarmType = "Alarm" - async def getMode(self): + async def get_mode(self): """Get current mode of the alarm. Returns: @@ -27,7 +27,7 @@ async def getMode(self): return state - async def getState(self, device: dict): + async def get_state(self, device: dict): """Get the alarm triggered state. Returns: @@ -43,7 +43,7 @@ async def getState(self, device: dict): return state - async def setMode(self, device: dict, mode: str): + async def set_mode(self, device: dict, mode: str): """Set the alarm mode. Args: @@ -59,7 +59,7 @@ async def setMode(self, device: dict, mode: str): and device["deviceData"]["online"] ): await self.session.hive_refresh_tokens() - resp = await self.session.api.setAlarm(mode=mode) + resp = await self.session.api.set_alarm(mode=mode) if resp["original"] == 200: final = True await self.session.getAlarm() @@ -82,7 +82,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getAlarm(self, device: dict): + async def get_alarm(self, device: dict): """Get alarm data. Args: @@ -108,8 +108,8 @@ async def getAlarm(self, device: dict): "device_id": device["device_id"], "device_name": device["device_name"], "status": { - "state": await self.getState(device), - "mode": await self.getMode(), + "state": await self.get_state(device), + "mode": await self.get_mode(), }, "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), diff --git a/src/apyhiveapi/api/hive_api.py b/src/apyhiveapi/api/hive_api.py index 9151f26..1e957bd 100644 --- a/src/apyhiveapi/api/hive_api.py +++ b/src/apyhiveapi/api/hive_api.py @@ -12,9 +12,9 @@ class HiveApi: """Hive API Code.""" - def __init__(self, hiveSession=None, websession=None, token=None): + def __init__(self, hive_session=None, websession=None, token=None): """Hive API initialisation.""" - self.cameraBaseUrl = "prod.hcam.bgchtest.info" + self.camera_base_url = "prod.hcam.bgchtest.info" self.urls = { "properties": "https://sso.hivehome.com/", "login": "https://beekeeper.hivehome.com/1.0/cognito/login", @@ -25,8 +25,10 @@ def __init__(self, hiveSession=None, websession=None, token=None): "holiday_mode": "/holiday-mode", "all": "/nodes/all?products=true&devices=true&actions=true", "alarm": "/security-lite?homeId=", - "cameraImages": f"https://event-history-service.{self.cameraBaseUrl}/v1/events/cameras?latest=true&cameraId={{0}}", - "cameraRecordings": f"https://event-history-service.{self.cameraBaseUrl}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", + "cameraImages": f"https://event-history-service.{self.camera_base_u +rl}/v1/events/cameras?latest=true&cameraId={{0}}", + "cameraRecordings": f"https://event-history-service.{self.camera_base_u +rl}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", "devices": "/devices", "products": "/products", "actions": "/actions", @@ -37,7 +39,7 @@ def __init__(self, hiveSession=None, websession=None, token=None): "original": "No response to Hive API request", "parsed": "No response to Hive API request", } - self.session = hiveSession + self.session = hive_session self.token = token def request(self, type, url, jsc=None, camera=False): @@ -80,7 +82,7 @@ def request(self, type, url, jsc=None, camera=False): url=url, headers=self.headers, data=jsc, timeout=self.timeout ) - def refreshTokens(self, tokens={}): + def refresh_tokens(self, tokens={}): """Get new session tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" url = self.urls["refresh"] if self.session is not None: @@ -106,7 +108,7 @@ def refreshTokens(self, tokens={}): return self.json_return - def getLoginInfo(self): + def get_login_info(self): """Get login properties to make the login request.""" url = self.urls["properties"] try: @@ -129,7 +131,7 @@ def getLoginInfo(self): except (OSError, RuntimeError, ZeroDivisionError): self.error() - def getAll(self): + def get_all(self): """Build and query all endpoint.""" json_return = {} url = self.urls["base"] + self.urls["all"] @@ -142,7 +144,7 @@ def getAll(self): return json_return - def getAlarm(self, home_id=None): + def get_alarm(self, home_id=None): """Build and query alarm endpoint.""" if self.session is not None: home_id = self.session.config.home_id @@ -156,7 +158,7 @@ def getAlarm(self, home_id=None): return self.json_return - def getCameraImage(self, device=None, accessToken=None): + def get_camera_image(self, device=None, accessToken=None): """Build and query camera endpoint.""" json_return = {} url = self.urls["cameraImages"].format(device["props"]["hardwareIdentifier"]) @@ -169,7 +171,7 @@ def getCameraImage(self, device=None, accessToken=None): return json_return - def getCameraRecording(self, device=None, eventId=None): + def get_camera_recording(self, device=None, eventId=None): """Build and query camera endpoint.""" json_return = {} url = self.urls["cameraRecordings"].format( @@ -184,7 +186,7 @@ def getCameraRecording(self, device=None, eventId=None): return json_return - def getDevices(self): + def get_devices(self): """Call the get devices endpoint.""" url = self.urls["base"] + self.urls["devices"] try: @@ -196,7 +198,7 @@ def getDevices(self): return self.json_return - def getProducts(self): + def get_products(self): """Call the get products endpoint.""" url = self.urls["base"] + self.urls["products"] try: @@ -208,7 +210,7 @@ def getProducts(self): return self.json_return - def getActions(self): + def get_actions(self): """Call the get actions endpoint.""" url = self.urls["base"] + self.urls["actions"] try: @@ -220,7 +222,7 @@ def getActions(self): return self.json_return - def motionSensor(self, sensor, fromepoch, toepoch): + def motion_sensor(self, sensor, fromepoch, toepoch): """Call a way to get motion sensor info.""" url = ( self.urls["base"] @@ -243,7 +245,7 @@ def motionSensor(self, sensor, fromepoch, toepoch): return self.json_return - def getWeather(self, weather_url): + def get_weather(self, weather_url): """Call endpoint to get local weather from Hive API.""" t_url = self.urls["weather"] + weather_url url = t_url.replace(" ", "%20") @@ -256,7 +258,7 @@ def getWeather(self, weather_url): return self.json_return - def setState(self, n_type, n_id, **kwargs): + def set_state(self, n_type, n_id, **kwargs): """Set the state of a Device.""" jsc = ( "{" @@ -277,7 +279,7 @@ def setState(self, n_type, n_id, **kwargs): return self.json_return - def setAction(self, n_id, data): + def set_action(self, n_id, data): """Set the state of a Action.""" jsc = data url = self.urls["base"] + self.urls["actions"] + "/" + n_id diff --git a/src/apyhiveapi/api/hive_async_api.py b/src/apyhiveapi/api/hive_async_api.py index f894e84..5952297 100644 --- a/src/apyhiveapi/api/hive_async_api.py +++ b/src/apyhiveapi/api/hive_async_api.py @@ -91,7 +91,7 @@ async def request( raise HiveApiError - def getLoginInfo(self): + def get_login_info(self): """Get login properties to make the login request.""" url = "https://sso.hivehome.com/" @@ -112,7 +112,7 @@ def getLoginInfo(self): loginData.update({"REGION": json_data["HiveSSOPoolId"]}) return loginData - async def refreshTokens(self): + async def refresh_tokens(self): """Refresh tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" url = self.urls["refresh"] if self.session is not None: @@ -139,7 +139,7 @@ async def refreshTokens(self): return self.json_return - async def getAll(self): + async def get_all(self): """Build and query all endpoint.""" json_return = {} url = self.urls["all"] @@ -152,7 +152,7 @@ async def getAll(self): return json_return - async def getAlarm(self): + async def get_alarm(self): """Build and query alarm endpoint.""" json_return = {} url = self.urls["alarm"] + self.session.config.home_id @@ -165,7 +165,7 @@ async def getAlarm(self): return json_return - async def getCameraImage(self, device): + async def get_camera_image(self, device): """Build and query alarm endpoint.""" json_return = {} url = self.urls["cameraImages"].format(device["props"]["hardwareIdentifier"]) @@ -178,7 +178,7 @@ async def getCameraImage(self, device): return json_return - async def getCameraRecording(self, device, eventId): + async def get_camera_recording(self, device, eventId): """Build and query alarm endpoint.""" json_return = {} url = self.urls["cameraRecordings"].format( @@ -194,7 +194,7 @@ async def getCameraRecording(self, device, eventId): return json_return - async def getDevices(self): + async def get_devices(self): """Call the get devices endpoint.""" json_return = {} url = self.urls["devices"] @@ -207,7 +207,7 @@ async def getDevices(self): return json_return - async def getProducts(self): + async def get_products(self): """Call the get products endpoint.""" json_return = {} url = self.urls["products"] @@ -220,7 +220,7 @@ async def getProducts(self): return json_return - async def getActions(self): + async def get_actions(self): """Call the get actions endpoint.""" json_return = {} url = self.urls["actions"] @@ -233,7 +233,7 @@ async def getActions(self): return json_return - async def motionSensor(self, sensor, fromepoch, toepoch): + async def motion_sensor(self, sensor, fromepoch, toepoch): """Call a way to get motion sensor info.""" json_return = {} url = ( @@ -257,7 +257,7 @@ async def motionSensor(self, sensor, fromepoch, toepoch): return json_return - async def getWeather(self, weather_url): + async def get_weather(self, weather_url): """Call endpoint to get local weather from Hive API.""" json_return = {} t_url = self.urls["weather"] + weather_url @@ -271,7 +271,7 @@ async def getWeather(self, weather_url): return json_return - async def setState(self, n_type, n_id, **kwargs): + async def set_state(self, n_type, n_id, **kwargs): """Set the state of a Device.""" json_return = {} jsc = ( @@ -284,7 +284,7 @@ async def setState(self, n_type, n_id, **kwargs): url = self.urls["nodes"].format(n_type, n_id) try: - await self.isFileBeingUsed() + await self.is_file_being_used() resp = await self.request("post", url, data=jsc) json_return["original"] = resp.status json_return["parsed"] = await resp.json(content_type=None) @@ -296,7 +296,7 @@ async def setState(self, n_type, n_id, **kwargs): return json_return - async def setAlarm(self, **kwargs): + async def set_alarm(self, **kwargs): """Set the state of the alarm.""" json_return = {} jsc = ( @@ -309,7 +309,7 @@ async def setAlarm(self, **kwargs): url = f"{self.urls['alarm']}{self.session.config.home_id}" try: - await self.isFileBeingUsed() + await self.is_file_being_used() resp = await self.request("post", url, data=jsc) json_return["original"] = resp.status json_return["parsed"] = await resp.json(content_type=None) @@ -321,12 +321,12 @@ async def setAlarm(self, **kwargs): return json_return - async def setAction(self, n_id, data): + async def set_action(self, n_id, data): """Set the state of a Action.""" jsc = data url = self.urls["actions"] + "/" + n_id try: - await self.isFileBeingUsed() + await self.is_file_being_used() await self.request("put", url, data=jsc) except (FileInUse, OSError, RuntimeError, ConnectionError) as e: if e.__class__.__name__ == "FileInUse": @@ -340,7 +340,20 @@ async def error(self): """An error has occurred iteracting with the Hive API.""" raise web_exceptions.HTTPError - async def isFileBeingUsed(self): + async def is_file_being_used(self): """Check if running in file mode.""" if self.session.config.file: raise FileInUse() + + async def close(self): + """Close the aiohttp session.""" + if self.websession and not self.websession.closed: + await self.websession.close() + + async def __aenter__(self): + """Async enter.""" + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + """Async exit.""" + await self.close() diff --git a/src/apyhiveapi/camera.py b/src/apyhiveapi/camera.py index 1c9a8be..6bf1694 100644 --- a/src/apyhiveapi/camera.py +++ b/src/apyhiveapi/camera.py @@ -11,7 +11,7 @@ class HiveCamera: cameraType = "Camera" - async def getCameraTemperature(self, device: dict): + async def get_camera_temperature(self, device: dict): """Get the camera state. Returns: @@ -27,7 +27,7 @@ async def getCameraTemperature(self, device: dict): return state - async def getCameraState(self, device: dict): + async def get_camera_state(self, device: dict): """Get the camera state. Returns: @@ -43,7 +43,7 @@ async def getCameraState(self, device: dict): return state - async def getCameraImageURL(self, device: dict): + async def get_camera_image_url(self, device: dict): """Get the camera image url. Returns: @@ -60,7 +60,7 @@ async def getCameraImageURL(self, device: dict): return state - async def getCameraRecodringURL(self, device: dict): + async def get_camera_recording_url(self, device: dict): """Get the camera recording url. Returns: @@ -75,7 +75,7 @@ async def getCameraRecodringURL(self, device: dict): return state - async def setCameraOn(self, device: dict, mode: str): + async def set_camera_on(self, device: dict, mode: str): """Set the camera state to on. Args: @@ -98,7 +98,7 @@ async def setCameraOn(self, device: dict, mode: str): return final - async def setCameraOff(self, device: dict, mode: str): + async def set_camera_off(self, device: dict, mode: str): """Set the camera state to on. Args: @@ -137,7 +137,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getCamera(self, device: dict): + async def get_camera(self, device: dict): """Get camera data. Args: @@ -163,10 +163,10 @@ async def getCamera(self, device: dict): "device_id": device["device_id"], "device_name": device["device_name"], "status": { - "temperature": await self.getCameraTemperature(device), - "state": await self.getCameraState(device), - "imageURL": await self.getCameraImageURL(device), - "recordingURL": await self.getCameraRecodringURL(device), + "temperature": await self.get_camera_temperature(device), + "state": await self.get_camera_state(device), + "imageURL": await self.get_camera_image_url(device), + "recordingURL": await self.get_camera_recording_url(device), }, "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), diff --git a/src/apyhiveapi/device_attributes.py b/src/apyhiveapi/device_attributes.py index 7821181..2477ef2 100644 --- a/src/apyhiveapi/device_attributes.py +++ b/src/apyhiveapi/device_attributes.py @@ -17,7 +17,7 @@ def __init__(self, session: object = None): self.session.log = Logger() self.type = "Attribute" - async def stateAttributes(self, n_id: str, _type: str): + async def state_attributes(self, n_id: str, _type: str): """Get HA State Attributes. Args: @@ -30,16 +30,16 @@ async def stateAttributes(self, n_id: str, _type: str): attr = {} if n_id in self.session.data.products or n_id in self.session.data.devices: - attr.update({"available": (await self.onlineOffline(n_id))}) + attr.update({"available": (await self.online_offline(n_id))}) if n_id in self.session.config.battery: - battery = await self.getBattery(n_id) + battery = await self.get_battery(n_id) if battery is not None: attr.update({"battery": str(battery) + "%"}) if n_id in self.session.config.mode: - attr.update({"mode": (await self.getMode(n_id))}) + attr.update({"mode": (await self.get_mode(n_id))}) return attr - async def onlineOffline(self, n_id: str): + async def online_offline(self, n_id: str): """Check if device is online. Args: @@ -58,7 +58,7 @@ async def onlineOffline(self, n_id: str): return state - async def getMode(self, n_id: str): + async def get_mode(self, n_id: str): """Get sensor mode. Args: @@ -79,7 +79,7 @@ async def getMode(self, n_id: str): return final - async def getBattery(self, n_id: str): + async def get_battery(self, n_id: str): """Get device battery level. Args: diff --git a/src/apyhiveapi/heating.py b/src/apyhiveapi/heating.py index e69de29..a2e29e1 100644 --- a/src/apyhiveapi/heating.py +++ b/src/apyhiveapi/heating.py @@ -0,0 +1,519 @@ +"""Hive Heating Module.""" +# pylint: skip-file +from .helper.const import HIVETOHA + + +class HiveHeating: + """Hive Heating Code. + + Returns: + object: heating + """ + + heatingType = "Heating" + + async def getMinTemperature(self, device: dict): + """Get heating minimum target temperature. + + Args: + device (dict): Device to get min temp for. + + Returns: + int: Minimum temperature + """ + if device["hiveType"] == "nathermostat": + return self.session.data.products[device["hiveID"]]["props"]["minHeat"] + return 5 + + async def getMaxTemperature(self, device: dict): + """Get heating maximum target temperature. + + Args: + device (dict): Device to get max temp for. + + Returns: + int: Maximum temperature + """ + if device["hiveType"] == "nathermostat": + return self.session.data.products[device["hiveID"]]["props"]["maxHeat"] + return 32 + + async def getCurrentTemperature(self, device: dict): + """Get heating current temperature. + + Args: + device (dict): Device to get current temperature for. + + Returns: + float: current temperature + """ + from datetime import datetime + + f_state = None + state = None + final = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["props"]["temperature"] + + if device["hiveID"] in self.session.data.minMax: + if self.session.data.minMax[device["hiveID"]]["TodayDate"] == str( + datetime.date(datetime.now()) + ): + if state < self.session.data.minMax[device["hiveID"]]["TodayMin"]: + self.session.data.minMax[device["hiveID"]]["TodayMin"] = state + + if state > self.session.data.minMax[device["hiveID"]]["TodayMax"]: + self.session.data.minMax[device["hiveID"]]["TodayMax"] = state + else: + data = { + "TodayMin": state, + "TodayMax": state, + "TodayDate": str(datetime.date(datetime.now())), + } + self.session.data.minMax[device["hiveID"]].update(data) + + if state < self.session.data.minMax[device["hiveID"]]["RestartMin"]: + self.session.data.minMax[device["hiveID"]]["RestartMin"] = state + + if state > self.session.data.minMax[device["hiveID"]]["RestartMax"]: + self.session.data.minMax[device["hiveID"]]["RestartMax"] = state + else: + data = { + "TodayMin": state, + "TodayMax": state, + "TodayDate": str(datetime.date(datetime.now())), + "RestartMin": state, + "RestartMax": state, + } + self.session.data.minMax[device["hiveID"]] = data + + f_state = round(float(state), 1) + final = f_state + except KeyError as e: + await self.session.log.error(e) + + return final + + async def getTargetTemperature(self, device: dict): + """Get heating target temperature. + + Args: + device (dict): Device to get target temperature for. + + Returns: + str: Target temperature. + """ + state = None + + try: + data = self.session.data.products[device["hiveID"]] + state = float(data["state"].get("target", None)) + state = float(data["state"].get("heat", state)) + except (KeyError, TypeError) as e: + await self.session.log.error(e) + + return state + + async def getMode(self, device: dict): + """Get heating current mode. + + Args: + device (dict): Device to get current mode for. + + Returns: + str: Current Mode + """ + state = None + final = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["state"]["mode"] + if state == "BOOST": + state = data["props"]["previous"]["mode"] + final = HIVETOHA[self.heatingType].get(state, state) + except KeyError as e: + await self.session.log.error(e) + + return final + + async def getState(self, device: dict): + """Get heating current state. + + Args: + device (dict): Device to get state for. + + Returns: + str: Current state. + """ + state = None + final = None + + try: + current_temp = await self.getCurrentTemperature(device) + target_temp = await self.getTargetTemperature(device) + if current_temp < target_temp: + state = "ON" + else: + state = "OFF" + final = HIVETOHA[self.heatingType].get(state, state) + except KeyError as e: + await self.session.log.error(e) + + return final + + async def getCurrentOperation(self, device: dict): + """Get heating current operation. + + Args: + device (dict): Device to get current operation for. + + Returns: + str: Current operation. + """ + state = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["props"]["working"] + except KeyError as e: + await self.session.log.error(e) + + return state + + async def getBoostStatus(self, device: dict): + """Get heating boost current status. + + Args: + device (dict): Device to get boost status for. + + Returns: + str: Boost status. + """ + state = None + + try: + data = self.session.data.products[device["hiveID"]] + state = HIVETOHA["Boost"].get(data["state"].get("boost", False), "ON") + except KeyError as e: + await self.session.log.error(e) + + return state + + async def getBoostTime(self, device: dict): + """Get heating boost time remaining. + + Args: + device (dict): device to get boost time for. + + Returns: + str: Boost time. + """ + if await self.getBoostStatus(device) == "ON": + state = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["state"]["boost"] + except KeyError as e: + await self.session.log.error(e) + + return state + return None + + async def getHeatOnDemand(self, device): + """Get heat on demand status. + + Args: + device ([dictionary]): [Get Heat on Demand status for Thermostat device.] + + Returns: + str: [Return True or False for the Heat on Demand status.] + """ + state = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["props"]["autoBoost"]["active"] + except KeyError as e: + await self.session.log.error(e) + + return state + + @staticmethod + async def getOperationModes(): + """Get heating list of possible modes. + + Returns: + list: Operation modes. + """ + return ["SCHEDULE", "MANUAL", "OFF"] + + async def setTargetTemperature(self, device: dict, new_temp: str): + """Set heating target temperature. + + Args: + device (dict): Device to set target temperature for. + new_temp (str): New temperature. + + Returns: + boolean: True/False if successful + """ + await self.session.hiveRefreshTokens() + final = False + + if ( + device["hiveID"] in self.session.data.products + and device["deviceData"]["online"] + ): + await self.session.hiveRefreshTokens() + data = self.session.data.products[device["hiveID"]] + resp = await self.session.api.setState( + data["type"], device["hiveID"], target=new_temp + ) + + if resp["original"] == 200: + await self.session.getDevices(device["hiveID"]) + final = True + + return final + + async def setMode(self, device: dict, new_mode: str): + """Set heating mode. + + Args: + device (dict): Device to set mode for. + new_mode (str): New mode to be set. + + Returns: + boolean: True/False if successful + """ + await self.session.hiveRefreshTokens() + final = False + + if ( + device["hiveID"] in self.session.data.products + and device["deviceData"]["online"] + ): + data = self.session.data.products[device["hiveID"]] + resp = await self.session.api.setState( + data["type"], device["hiveID"], mode=new_mode + ) + + if resp["original"] == 200: + await self.session.getDevices(device["hiveID"]) + final = True + + return final + + async def setBoostOn(self, device: dict, mins: str, temp: float): + """Turn heating boost on. + + Args: + device (dict): Device to boost. + mins (str): Number of minutes to boost for. + temp (float): Temperature to boost to. + + Returns: + boolean: True/False if successful + """ + if int(mins) > 0 and int(temp) >= await self.getMinTemperature(device): + if int(temp) <= await self.getMaxTemperature(device): + await self.session.hiveRefreshTokens() + final = False + + if ( + device["hiveID"] in self.session.data.products + and device["deviceData"]["online"] + ): + data = self.session.data.products[device["hiveID"]] + resp = await self.session.api.setState( + data["type"], + device["hiveID"], + mode="BOOST", + boost=mins, + target=temp, + ) + + if resp["original"] == 200: + await self.session.getDevices(device["hiveID"]) + final = True + + return final + return None + + async def setBoostOff(self, device: dict): + """Turn heating boost off. + + Args: + device (dict): Device to update boost for. + + Returns: + boolean: True/False if successful + """ + final = False + + if ( + device["hiveID"] in self.session.data.products + and device["deviceData"]["online"] + ): + await self.session.hiveRefreshTokens() + data = self.session.data.products[device["hiveID"]] + await self.session.getDevices(device["hiveID"]) + if await self.getBoostStatus(device) == "ON": + prev_mode = data["props"]["previous"]["mode"] + if prev_mode == "MANUAL" or prev_mode == "OFF": + pre_temp = data["props"]["previous"].get("target", 7) + resp = await self.session.api.setState( + data["type"], + device["hiveID"], + mode=prev_mode, + target=pre_temp, + ) + else: + resp = await self.session.api.setState( + data["type"], device["hiveID"], mode=prev_mode + ) + if resp["original"] == 200: + await self.session.getDevices(device["hiveID"]) + final = True + + return final + + async def setHeatOnDemand(self, device: dict, state: str): + """Enable or disable Heat on Demand for a Thermostat. + + Args: + device ([dictionary]): [This is the Thermostat device you want to update.] + state ([str]): [This is the state you want to set. (Either "ENABLED" or "DISABLED")] + + Returns: + [boolean]: [Return True or False if the Heat on Demand was set successfully.] + """ + final = False + + if ( + device["hiveID"] in self.session.data.products + and device["deviceData"]["online"] + ): + data = self.session.data.products[device["hiveID"]] + await self.session.hiveRefreshTokens() + resp = await self.session.api.setState( + data["type"], device["hiveID"], autoBoost=state + ) + + if resp["original"] == 200: + await self.session.getDevices(device["hiveID"]) + final = True + + return final + + +class Climate(HiveHeating): + """Climate class for Home Assistant. + + Args: + Heating (object): Heating class + """ + + def __init__(self, session: object = None): + """Initialise heating. + + Args: + session (object, optional): Used to interact with hive account. Defaults to None. + """ + self.session = session + + async def getClimate(self, device: dict): + """Get heating data. + + Args: + device (dict): Device to update. + + Returns: + dict: Updated device. + """ + device["deviceData"].update( + {"online": await self.session.attr.onlineOffline(device["device_id"])} + ) + + if device["deviceData"]["online"]: + dev_data = {} + self.session.helper.deviceRecovered(device["device_id"]) + data = self.session.data.devices[device["device_id"]] + dev_data = { + "hiveID": device["hiveID"], + "hiveName": device["hiveName"], + "hiveType": device["hiveType"], + "haName": device["haName"], + "haType": device["haType"], + "device_id": device["device_id"], + "device_name": device["device_name"], + "temperatureunit": device["temperatureunit"], + "min_temp": await self.getMinTemperature(device), + "max_temp": await self.getMaxTemperature(device), + "status": { + "current_temperature": await self.getCurrentTemperature(device), + "target_temperature": await self.getTargetTemperature(device), + "action": await self.getCurrentOperation(device), + "mode": await self.getMode(device), + "boost": await self.getBoostStatus(device), + }, + "deviceData": data.get("props", None), + "parentDevice": data.get("parent", None), + "custom": device.get("custom", None), + "attributes": await self.session.attr.stateAttributes( + device["device_id"], device["hiveType"] + ), + } + self.session.devices.update({device["hiveID"]: dev_data}) + return self.session.devices[device["hiveID"]] + else: + await self.session.log.errorCheck( + device["device_id"], "ERROR", device["deviceData"]["online"] + ) + return device + + async def getScheduleNowNextLater(self, device: dict): + """Hive get heating schedule now, next and later. + + Args: + device (dict): Device to get schedule for. + + Returns: + dict: Schedule now, next and later + """ + online = await self.session.attr.onlineOffline(device["device_id"]) + current_mode = await self.getMode(device) + state = None + + try: + if online and current_mode == "SCHEDULE": + data = self.session.data.products[device["hiveID"]] + state = self.session.helper.getScheduleNNL(data["state"]["schedule"]) + except KeyError as e: + await self.session.log.error(e) + + return state + + async def minmaxTemperature(self, device: dict): + """Min/Max Temp. + + Args: + device (dict): device to get min/max temperature for. + + Returns: + dict: Shows min/max temp for the day. + """ + state = None + final = None + + try: + state = self.session.data.minMax[device["hiveID"]] + final = state + except KeyError as e: + await self.session.log.error(e) + + return final \ No newline at end of file diff --git a/src/apyhiveapi/helper/const.py b/src/apyhiveapi/helper/const.py index 994d6b0..49c7456 100644 --- a/src/apyhiveapi/helper/const.py +++ b/src/apyhiveapi/helper/const.py @@ -1,6 +1,12 @@ """Constants for Pyhiveapi.""" +# pylint: skip-file +SYNC_PACKAGE_NAME = "pyhiveapi" +SYNC_PACKAGE_DIR = "/pyhiveapi/" +ASYNC_PACKAGE_NAME = "apyhiveapi" +ASYNC_PACKAGE_DIR = "/apyhiveapi/" SMS_REQUIRED = "SMS_MFA" + # HTTP return codes. HTTP_OK = 200 HTTP_CREATED = 201 @@ -49,3 +55,116 @@ "Sensor": ["motionsensor", "contactsensor"], "Switch": ["activeplug"], } +sensor_commands = { + "SMOKE_CO": "self.session.hub.get_smoke_status(device)", + "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", + "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", + "Camera_Temp": "self.session.camera.getCameraTemperature(device)", + "Current_Temperature": "self.session.heating.getCurrentTemperature(device)", + "Heating_Current_Temperature": "self.session.heating.getCurrentTemperature(device)", + "Heating_Target_Temperature": "self.session.heating.getTargetTemperature(device)", + "Heating_State": "self.session.heating.getState(device)", + "Heating_Mode": "self.session.heating.getMode(device)", + "Heating_Boost": "self.session.heating.getBoostStatus(device)", + "Hotwater_State": "self.session.hotwater.getState(device)", + "Hotwater_Mode": "self.session.hotwater.getMode(device)", + "Hotwater_Boost": "self.session.hotwater.getBoost(device)", + "Battery": 'self.session.attr.getBattery(device["device_id"])', + "Mode": 'self.session.attr.getMode(device["hiveID"])', + "Availability": "self.online(device)", + "Connectivity": "self.online(device)", + "Power": "self.session.switch.getPowerUsage(device)", +} + +PRODUCTS = { + "sense": [ + 'addList("binary_sensor", p, haName="Glass Detection", hiveType="GLASS_BREAK")', + 'addList("binary_sensor", p, haName="Smoke Detection", hiveType="SMOKE_CO")', + 'addList("binary_sensor", p, haName="Dog Bark Detection", hiveType="DOG_BARK")', + ], + "heating": [ + 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', + 'addList("switch", p, haName=" Heat on Demand", hiveType="Heating_Heat_On_Demand", category="config")', + 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', + 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', + 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', + 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', + 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', + ], + "trvcontrol": [ + 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', + 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', + 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', + 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', + 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', + 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', + ], + "hotwater": [ + 'addList("water_heater", p,)', + 'addList("sensor", p, haName="Hotwater State", hiveType="Hotwater_State", category="diagnostic")', + 'addList("sensor", p, haName="Hotwater Mode", hiveType="Hotwater_Mode", category="diagnostic")', + 'addList("sensor", p, haName="Hotwater Boost", hiveType="Hotwater_Boost", category="diagnostic")', + ], + "activeplug": [ + 'addList("switch", p)', + 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', + 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", p, haName=" Power", hiveType="Power", category="diagnostic")', + ], + "warmwhitelight": [ + 'addList("light", p)', + 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', + 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], + "tuneablelight": [ + 'addList("light", p)', + 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', + 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], + "colourtuneablelight": [ + 'addList("light", p)', + 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', + 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], + # "hivecamera": [ + # 'addList("camera", p)', + # 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', + # 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + # 'addList("sensor", p, haName=" Temperature", hiveType="Camera_Temp", category="diagnostic")', + # ], + "motionsensor": [ + 'addList("binary_sensor", p)', + 'addList("sensor", p, haName=" Current Temperature", hiveType="Current_Temperature", category="diagnostic")', + ], + "contactsensor": ['addList("binary_sensor", p)'], +} + +DEVICES = { + "contactsensor": [ + 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', + 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], + "hub": [ + 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity", category="diagnostic")', + ], + "motionsensor": [ + 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', + 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], + "sense": [ + 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity")', + ], + "siren": ['addList("alarm_control_panel", d)'], + "thermostatui": [ + 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', + 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], + "trv": [ + 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', + 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + ], +} + +ACTIONS = ( + 'addList("switch", a, hiveName=a["name"], haName=a["name"], hiveType="action")' +) \ No newline at end of file diff --git a/src/apyhiveapi/helper/debugger.py b/src/apyhiveapi/helper/debugger.py index 526d977..5f3060d 100644 --- a/src/apyhiveapi/helper/debugger.py +++ b/src/apyhiveapi/helper/debugger.py @@ -21,9 +21,9 @@ def __enter__(self): print("Entering Debug Decorated func") # Set the trace function to the trace_calls function # So all events are now traced - self.traceCalls + self.trace_calls - def traceCalls(self, frame, event, arg): + def trace_calls(self, frame, event, arg): """Trace calls be made.""" # We want to only trace our call to the decorated function if event != "call": @@ -32,9 +32,9 @@ def traceCalls(self, frame, event, arg): return # return the trace function to use when you go into that # function call - return self.traceLines + return self.trace_lines - def traceLines(self, frame, event, arg): + def trace_lines(self, frame, event, arg): """Print out lines for function.""" # If you want to print local variables each line # keep the check for the event 'line' diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index c007615..72bdd87 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -17,7 +17,7 @@ def __init__(self, session: object = None): """ self.session = session - def getDeviceName(self, n_id: str): + def get_device_name(self, n_id: str): """Resolve a id into a name. Args: @@ -45,17 +45,17 @@ def getDeviceName(self, n_id: str): else: return n_id - def deviceRecovered(self, n_id: str): + def device_recovered(self, n_id: str): """Register that a device has recovered from being offline. Args: n_id (str): ID of the device. """ - # name = HiveHelper.getDeviceName(n_id) + # name = HiveHelper.get_device_name(n_id) if n_id in self.session.config.errorList: self.session.config.errorList.pop(n_id) - def getDeviceFromID(self, n_id: str): + def get_device_from_id(self, n_id: str): """Get product/device data from ID. Args: @@ -72,7 +72,7 @@ def getDeviceFromID(self, n_id: str): return data - def getDeviceData(self, product: dict): + def get_device_data(self, product: dict): """Get device from product data. Args: @@ -105,7 +105,7 @@ def getDeviceData(self, product: dict): return device - def convertMinutesToTime(self, minutes_to_convert: str): + def convert_minutes_to_time(self, minutes_to_convert: str): """Convert minutes string to datetime. Args: @@ -121,7 +121,7 @@ def convertMinutesToTime(self, minutes_to_convert: str): converted_time_string = converted_time.strftime("%H:%M") return converted_time_string - def getScheduleNNL(self, hive_api_schedule: list): + def get_schedule_nnl(self, hive_api_schedule: list): """Get the schedule now, next and later of a given nodes schedule. Args: @@ -160,7 +160,7 @@ def getScheduleNNL(self, hive_api_schedule: list): current_slot_custom = current_day_schedule_sorted[current_slot] slot_date = datetime.datetime.now() + datetime.timedelta(days=day_index) - slot_time = self.convertMinutesToTime(current_slot_custom["start"]) + slot_time = self.convert_minutes_to_time(current_slot_custom["start"]) slot_time_date_s = slot_date.strftime("%d-%m-%Y") + " " + slot_time slot_time_date_dt = datetime.datetime.strptime( slot_time_date_s, "%d-%m-%Y %H:%M" @@ -195,7 +195,7 @@ def getScheduleNNL(self, hive_api_schedule: list): return schedule_now_and_next - def getHeatOnDemandDevice(self, device: dict): + def get_heat_on_demand_device(self, device: dict): """Use TRV device to get the linked thermostat device. Args: @@ -211,11 +211,11 @@ def getHeatOnDemandDevice(self, device: dict): async def call_sensor_function(self, device): """Helper to decide which function to call.""" if device["hiveType"] == "SMOKE_CO": - return await self.session.hub.getSmokeStatus(device) + return await self.session.hub.get_smoke_status(device) if device["hiveType"] == "DOG_BARK": - return await self.session.hub.getDogBarkStatus(device) + return await self.session.hub.get_dog_bark_status(device) if device["hiveType"] == "GLASS_BREAK": - return await self.session.hub.getGlassBreakStatus(device) + return await self.session.hub.get_glass_break_status(device) if device["hiveType"] == "Camera_Temp": return await self.session.camera.getCameraTemperature(device) if device["hiveType"] == "Heating_Current_Temperature": diff --git a/src/apyhiveapi/helper/logger.py b/src/apyhiveapi/helper/logger.py index db8fe21..00bd7e1 100644 --- a/src/apyhiveapi/helper/logger.py +++ b/src/apyhiveapi/helper/logger.py @@ -19,7 +19,7 @@ async def error(self, e="UNKNOWN"): f" with exception {e.__class__} {e}" ) - async def errorCheck(self, n_id, n_type, error_type, **kwargs): + async def error_check(self, n_id, n_type, error_type, **kwargs): """Error has occurred.""" message = None name = self.session.helper.getDeviceName(n_id) diff --git a/src/apyhiveapi/hotwater.py b/src/apyhiveapi/hotwater.py index 48ce873..7e029a5 100644 --- a/src/apyhiveapi/hotwater.py +++ b/src/apyhiveapi/hotwater.py @@ -1,275 +1,275 @@ -"""Hive Hotwater Module.""" -# pylint: skip-file - -from .helper.const import HIVETOHA - - -class HiveHotwater: - """Hive Hotwater Code. - - Returns: - object: Hotwater Object. - """ - - hotwaterType = "Hotwater" - - async def getMode(self, device: dict): - """Get hotwater current mode. - - Args: - device (dict): Device to get the mode for. - - Returns: - str: Return mode. - """ - state = None - final = None - - try: - data = self.session.data.products[device["hiveID"]] - state = data["state"]["mode"] - if state == "BOOST": - state = data["props"]["previous"]["mode"] - final = HIVETOHA[self.hotwaterType].get(state, state) - except KeyError as e: - await self.session.log.error(e) - - return final - - @staticmethod - async def getOperationModes(): - """Get heating list of possible modes. - - Returns: - list: Return list of operation modes. - """ - return ["SCHEDULE", "ON", "OFF"] - - async def getBoost(self, device: dict): - """Get hot water current boost status. - - Args: - device (dict): Device to get boost status for - - Returns: - str: Return boost status. - """ - state = None - final = None - - try: - data = self.session.data.products[device["hiveID"]] - state = data["state"]["boost"] - final = HIVETOHA["Boost"].get(state, "ON") - except KeyError as e: - await self.session.log.error(e) - - return final - - async def getBoostTime(self, device: dict): - """Get hotwater boost time remaining. - - Args: - device (dict): Device to get boost time for. - - Returns: - str: Return time remaining on the boost. - """ - state = None - if await self.getBoost(device) == "ON": - try: - data = self.session.data.products[device["hiveID"]] - state = data["state"]["boost"] - except KeyError as e: - await self.session.log.error(e) - - return state - - async def getState(self, device: dict): - """Get hot water current state. - - Args: - device (dict): Device to get the state for. - - Returns: - str: return state of device. - """ - state = None - final = None - - try: - data = self.session.data.products[device["hiveID"]] - state = data["state"]["status"] - mode_current = await self.getMode(device) - if mode_current == "SCHEDULE": - if await self.getBoost(device) == "ON": - state = "ON" - else: - snan = self.session.helper.getScheduleNNL(data["state"]["schedule"]) - state = snan["now"]["value"]["status"] - - final = HIVETOHA[self.hotwaterType].get(state, state) - except KeyError as e: - await self.session.log.error(e) - - return final - - async def setMode(self, device: dict, new_mode: str): - """Set hot water mode. - - Args: - device (dict): device to update mode. - new_mode (str): Mode to set the device to. - - Returns: - boolean: return True/False if boost was successful. - """ - final = False - - if device["hiveID"] in self.session.data.products: - await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( - data["type"], device["hiveID"], mode=new_mode - ) - if resp["original"] == 200: - final = True - await self.session.get_devices() - - return final - - async def setBoostOn(self, device: dict, mins: int): - """Turn hot water boost on. - - Args: - device (dict): Deice to boost. - mins (int): Number of minutes to boost it for. - - Returns: - boolean: return True/False if boost was successful. - """ - final = False - - if ( - int(mins) > 0 - and device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] - ): - await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( - data["type"], device["hiveID"], mode="BOOST", boost=mins - ) - if resp["original"] == 200: - final = True - await self.session.get_devices() - - return final - - async def setBoostOff(self, device: dict): - """Turn hot water boost off. - - Args: - device (dict): device to set boost off - - Returns: - boolean: return True/False if boost was successful. - """ - final = False - - if ( - device["hiveID"] in self.session.data.products - and await self.getBoost(device) == "ON" - and device["deviceData"]["online"] - ): - await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] - prev_mode = data["props"]["previous"]["mode"] - resp = await self.session.api.setState( - data["type"], device["hiveID"], mode=prev_mode - ) - if resp["original"] == 200: - await self.session.get_devices() - final = True - - return final - - -class WaterHeater(HiveHotwater): - """Water heater class. - - Args: - Hotwater (object): Hotwater class. - """ - - def __init__(self, session: object = None): - """Initialise water heater. - - Args: - session (object, optional): Session to interact with account. Defaults to None. - """ - self.session = session - - async def getWaterHeater(self, device: dict): - """Update water heater device. - - Args: - device (dict): device to update. - - Returns: - dict: Updated device. - """ - device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} - ) - - if device["deviceData"]["online"]: - - dev_data = {} - self.session.helper.deviceRecovered(device["device_id"]) - data = self.session.data.devices[device["device_id"]] - dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], - "device_id": device["device_id"], - "device_name": device["device_name"], - "status": {"current_operation": await self.getMode(device)}, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), - "custom": device.get("custom", None), - "attributes": await self.session.attr.stateAttributes( - device["device_id"], device["hiveType"] - ), - } - - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] - else: - await self.session.log.errorCheck( - device["device_id"], "ERROR", device["deviceData"]["online"] - ) - return device - - async def getScheduleNowNextLater(self, device: dict): - """Hive get hotwater schedule now, next and later. - - Args: - device (dict): device to get schedule for. - - Returns: - dict: return now, next and later schedule. - """ - state = None - - try: - mode_current = await self.getMode(device) - if mode_current == "SCHEDULE": - data = self.session.data.products[device["hiveID"]] - state = self.session.helper.getScheduleNNL(data["state"]["schedule"]) - except KeyError as e: - await self.session.log.error(e) - - return state +"""Hive Hotwater Module.""" +# pylint: skip-file + +from .helper.const import HIVETOHA + + +class HiveHotwater: + """Hive Hotwater Code. + + Returns: + object: Hotwater Object. + """ + + hotwaterType = "Hotwater" + + async def get_mode(self, device: dict): + """Get hotwater current mode. + + Args: + device (dict): Device to get the mode for. + + Returns: + str: Return mode. + """ + state = None + final = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["state"]["mode"] + if state == "BOOST": + state = data["props"]["previous"]["mode"] + final = HIVETOHA[self.hotwaterType].get(state, state) + except KeyError as e: + await self.session.log.error(e) + + return final + + @staticmethod + async def get_operation_modes(): + """Get heating list of possible modes. + + Returns: + list: Return list of operation modes. + """ + return ["SCHEDULE", "ON", "OFF"] + + async def get_boost(self, device: dict): + """Get hot water current boost status. + + Args: + device (dict): Device to get boost status for + + Returns: + str: Return boost status. + """ + state = None + final = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["state"]["boost"] + final = HIVETOHA["Boost"].get(state, "ON") + except KeyError as e: + await self.session.log.error(e) + + return final + + async def get_boost_time(self, device: dict): + """Get hotwater boost time remaining. + + Args: + device (dict): Device to get boost time for. + + Returns: + str: Return time remaining on the boost. + """ + state = None + if await self.get_boost(device) == "ON": + try: + data = self.session.data.products[device["hiveID"]] + state = data["state"]["boost"] + except KeyError as e: + await self.session.log.error(e) + + return state + + async def get_state(self, device: dict): + """Get hot water current state. + + Args: + device (dict): Device to get the state for. + + Returns: + str: return state of device. + """ + state = None + final = None + + try: + data = self.session.data.products[device["hiveID"]] + state = data["state"]["status"] + mode_current = await self.get_mode(device) + if mode_current == "SCHEDULE": + if await self.get_boost(device) == "ON": + state = "ON" + else: + snan = self.session.helper.getScheduleNNL(data["state"]["schedule"]) + state = snan["now"]["value"]["status"] + + final = HIVETOHA[self.hotwaterType].get(state, state) + except KeyError as e: + await self.session.log.error(e) + + return final + + async def set_mode(self, device: dict, new_mode: str): + """Set hot water mode. + + Args: + device (dict): device to update mode. + new_mode (str): Mode to set the device to. + + Returns: + boolean: return True/False if boost was successful. + """ + final = False + + if device["hiveID"] in self.session.data.products: + await self.session.hive_refresh_tokens() + data = self.session.data.products[device["hiveID"]] + resp = await self.session.api.setState( + data["type"], device["hiveID"], mode=new_mode + ) + if resp["original"] == 200: + final = True + await self.session.get_devices() + + return final + + async def set_boost_on(self, device: dict, mins: int): + """Turn hot water boost on. + + Args: + device (dict): Deice to boost. + mins (int): Number of minutes to boost it for. + + Returns: + boolean: return True/False if boost was successful. + """ + final = False + + if ( + int(mins) > 0 + and device["hiveID"] in self.session.data.products + and device["deviceData"]["online"] + ): + await self.session.hive_refresh_tokens() + data = self.session.data.products[device["hiveID"]] + resp = await self.session.api.setState( + data["type"], device["hiveID"], mode="BOOST", boost=mins + ) + if resp["original"] == 200: + final = True + await self.session.get_devices() + + return final + + async def set_boost_off(self, device: dict): + """Turn hot water boost off. + + Args: + device (dict): device to set boost off + + Returns: + boolean: return True/False if boost was successful. + """ + final = False + + if ( + device["hiveID"] in self.session.data.products + and await self.get_boost(device) == "ON" + and device["deviceData"]["online"] + ): + await self.session.hive_refresh_tokens() + data = self.session.data.products[device["hiveID"]] + prev_mode = data["props"]["previous"]["mode"] + resp = await self.session.api.setState( + data["type"], device["hiveID"], mode=prev_mode + ) + if resp["original"] == 200: + await self.session.get_devices() + final = True + + return final + + +class WaterHeater(HiveHotwater): + """Water heater class. + + Args: + Hotwater (object): Hotwater class. + """ + + def __init__(self, session: object = None): + """Initialise water heater. + + Args: + session (object, optional): Session to interact with account. Defaults to None. + """ + self.session = session + + async def get_water_heater(self, device: dict): + """Update water heater device. + + Args: + device (dict): device to update. + + Returns: + dict: Updated device. + """ + device["deviceData"].update( + {"online": await self.session.attr.onlineOffline(device["device_id"])} + ) + + if device["deviceData"]["online"]: + + dev_data = {} + self.session.helper.deviceRecovered(device["device_id"]) + data = self.session.data.devices[device["device_id"]] + dev_data = { + "hiveID": device["hiveID"], + "hiveName": device["hiveName"], + "hiveType": device["hiveType"], + "haName": device["haName"], + "haType": device["haType"], + "device_id": device["device_id"], + "device_name": device["device_name"], + "status": {"current_operation": await self.get_mode(device)}, + "deviceData": data.get("props", None), + "parentDevice": data.get("parent", None), + "custom": device.get("custom", None), + "attributes": await self.session.attr.stateAttributes( + device["device_id"], device["hiveType"] + ), + } + + self.session.devices.update({device["hiveID"]: dev_data}) + return self.session.devices[device["hiveID"]] + else: + await self.session.log.errorCheck( + device["device_id"], "ERROR", device["deviceData"]["online"] + ) + return device + + async def get_schedule_now_next_later(self, device: dict): + """Hive get hotwater schedule now, next and later. + + Args: + device (dict): device to get schedule for. + + Returns: + dict: return now, next and later schedule. + """ + state = None + + try: + mode_current = await self.get_mode(device) + if mode_current == "SCHEDULE": + data = self.session.data.products[device["hiveID"]] + state = self.session.helper.getScheduleNNL(data["state"]["schedule"]) + except KeyError as e: + await self.session.log.error(e) + + return state diff --git a/src/apyhiveapi/hub.py b/src/apyhiveapi/hub.py index ec3bd92..d1e4f3a 100644 --- a/src/apyhiveapi/hub.py +++ b/src/apyhiveapi/hub.py @@ -21,7 +21,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getSmokeStatus(self, device: dict): + async def get_smoke_status(self, device: dict): """Get the hub smoke status. Args: @@ -42,7 +42,7 @@ async def getSmokeStatus(self, device: dict): return final - async def getDogBarkStatus(self, device: dict): + async def get_dog_bark_status(self, device: dict): """Get dog bark status. Args: @@ -63,7 +63,7 @@ async def getDogBarkStatus(self, device: dict): return final - async def getGlassBreakStatus(self, device: dict): + async def get_glass_break_status(self, device: dict): """Get the glass detected status from the Hive hub. Args: diff --git a/src/apyhiveapi/plug.py b/src/apyhiveapi/plug.py index 60d10e5..1bbd18b 100644 --- a/src/apyhiveapi/plug.py +++ b/src/apyhiveapi/plug.py @@ -12,7 +12,7 @@ class HiveSmartPlug: plugType = "Switch" - async def getState(self, device: dict): + async def get_state(self, device: dict): """Get smart plug state. Args: @@ -32,7 +32,7 @@ async def getState(self, device: dict): return state - async def getPowerUsage(self, device: dict): + async def get_power_usage(self, device: dict): """Get smart plug current power usage. Args: @@ -51,7 +51,7 @@ async def getPowerUsage(self, device: dict): return state - async def setStatusOn(self, device: dict): + async def set_status_on(self, device: dict): """Set smart plug to turn on. Args: @@ -77,7 +77,7 @@ async def setStatusOn(self, device: dict): return final - async def setStatusOff(self, device: dict): + async def set_status_off(self, device: dict): """Set smart plug to turn off. Args: @@ -119,7 +119,7 @@ def __init__(self, session: object): """ self.session = session - async def getSwitch(self, device: dict): + async def get_switch(self, device: dict): """Home assistant wrapper to get switch device. Args: @@ -145,7 +145,7 @@ async def getSwitch(self, device: dict): "device_id": device["device_id"], "device_name": device["device_name"], "status": { - "state": await self.getSwitchState(device), + "state": await self.get_switch_state(device), }, "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), @@ -158,7 +158,7 @@ async def getSwitch(self, device: dict): { "status": { "state": dev_data["status"]["state"], - "power_usage": await self.getPowerUsage(device), + "power_usage": await self.get_power_usage(device), }, "attributes": await self.session.attr.stateAttributes( device["device_id"], device["hiveType"] @@ -174,7 +174,7 @@ async def getSwitch(self, device: dict): ) return device - async def getSwitchState(self, device: dict): + async def get_switch_state(self, device: dict): """Home Assistant wrapper to get updated switch state. Args: @@ -186,9 +186,9 @@ async def getSwitchState(self, device: dict): if device["hiveType"] == "Heating_Heat_On_Demand": return await self.session.heating.getHeatOnDemand(device) else: - return await self.getState(device) + return await self.get_state(device) - async def turnOn(self, device: dict): + async def turn_on(self, device: dict): """Home Assisatnt wrapper for turning switch on. Args: @@ -200,9 +200,9 @@ async def turnOn(self, device: dict): if device["hiveType"] == "Heating_Heat_On_Demand": return await self.session.heating.setHeatOnDemand(device, "ENABLED") else: - return await self.setStatusOn(device) + return await self.set_status_on(device) - async def turnOff(self, device: dict): + async def turn_off(self, device: dict): """Home Assisatnt wrapper for turning switch off. Args: @@ -214,4 +214,4 @@ async def turnOff(self, device: dict): if device["hiveType"] == "Heating_Heat_On_Demand": return await self.session.heating.setHeatOnDemand(device, "DISABLED") else: - return await self.setStatusOff(device) + return await self.set_status_off(device) diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index e69de29..608a1d1 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -0,0 +1,579 @@ +"""Hive Session Module.""" +# pylint: skip-file +import asyncio +import copy +import json +import operator +import os +import time +from datetime import datetime, timedelta + +from aiohttp.web import HTTPException +from apyhiveapi import API, Auth + +from .device_attributes import HiveAttributes +from .helper.const import ACTIONS, DEVICES, HIVE_TYPES, PRODUCTS +from .helper.hive_exceptions import ( + HiveApiError, + HiveFailedToRefreshTokens, + HiveInvalid2FACode, + HiveInvalidDeviceAuthentication, + HiveInvalidPassword, + HiveInvalidUsername, + HiveReauthRequired, + HiveUnknownConfiguration, + NoApiToken, +) +from .helper.hive_helper import HiveHelper +from .helper.logger import Logger +from .helper.map import Map + + +class HiveSession: + """Hive Session Code. + + Raises: + HiveUnknownConfiguration: Unknown configuration. + HTTPException: HTTP error has occurred. + HiveApiError: Hive has retuend an error code. + HiveReauthRequired: Tokens have expired and reauthentiction is required. + + Returns: + object: Session object. + """ + + sessionType = "Session" + + def __init__( + self, + username: str = None, + password: str = None, + websession: object = None, + ): + """Initialise the base variable values. + + Args: + username (str, optional): Hive username. Defaults to None. + password (str, optional): Hive Password. Defaults to None. + websession (object, optional): Websession for api calls. Defaults to None. + """ + self.auth = Auth( + username=username, + password=password, + ) + self.api = API(hiveSession=self, websession=websession) + self.helper = HiveHelper(self) + self.attr = HiveAttributes(self) + self.log = Logger(self) + self.updateLock = asyncio.Lock() + self.tokens = Map( + { + "tokenData": {}, + "tokenCreated": datetime.now() - timedelta(seconds=4000), + "tokenExpiry": timedelta(seconds=3600), + } + ) + self.config = Map( + { + "alarm": False, + "battery": [], + "camera": False, + "errorList": {}, + "file": False, + "homeID": None, + "lastUpdated": datetime.now(), + "mode": [], + "scanInterval": timedelta(seconds=120), + "userID": None, + "username": username, + } + ) + self.data = Map( + { + "products": {}, + "devices": {}, + "actions": {}, + "user": {}, + "minMax": {}, + "alarm": {}, + "camera": {}, + } + ) + self.devices = {} + self.device_list = {} + + def open_file(self, file: str): + """Open a file. + + Args: + file (str): File location + + Returns: + dict: Data from the chosen file. + """ + path = os.path.dirname(os.path.realpath(__file__)) + "/data/" + file + path = path.replace("/pyhiveapi/", "/apyhiveapi/") + with open(path) as j: + data = json.loads(j.read()) + + return data + + def add_list(self, entityType: str, data: dict, **kwargs: dict): + """Add entity to the list. + + Args: + type (str): Type of entity + data (dict): Information to create entity. + + Returns: + dict: Entity. + """ + device = self.helper.getDeviceData(data) + device_name = ( + device["state"]["name"] + if device["state"]["name"] != "Receiver" + else "Heating" + ) + formatted_data = {} + + try: + formatted_data = { + "hiveID": data.get("id", ""), + "hiveName": device_name, + "hiveType": data.get("type", ""), + "haType": entityType, + "deviceData": device.get("props", data.get("props", {})), + "parentDevice": data.get("parent", None), + "isGroup": data.get("isGroup", False), + "device_id": device["id"], + "device_name": device_name, + } + + if kwargs.get("haName", "FALSE")[0] == " ": + kwargs["haName"] = device_name + kwargs["haName"] + else: + formatted_data["haName"] = device_name + formatted_data.update(kwargs) + except KeyError as error: + self.logger.error(error) + + self.device_list[entityType].append(formatted_data) + return formatted_data + + async def update_interval(self, new_interval: timedelta): + """Update the scan interval. + + Args: + new_interval (int): New interval for polling. + """ + if isinstance(new_interval, int): + new_interval = timedelta(seconds=new_interval) + + interval = new_interval + if interval < timedelta(seconds=15): + interval = timedelta(seconds=15) + self.config.scanInterval = interval + + async def use_file(self, username: str = None): + """Update to check if file is being used. + + Args: + username (str, optional): Looks for use@file.com. Defaults to None. + """ + using_file = True if username == "use@file.com" else False + if using_file: + self.config.file = True + + async def update_tokens(self, tokens: dict, update_expiry_time: bool = True): + """Update session tokens. + + Args: + tokens (dict): Tokens from API response. + refresh_interval (Boolean): Should the refresh internval be updated + + Returns: + dict: Parsed dictionary of tokens + """ + data = {} + if "AuthenticationResult" in tokens: + data = tokens.get("AuthenticationResult") + self.tokens.tokenData.update({"token": data["IdToken"]}) + if "RefreshToken" in data: + self.tokens.tokenData.update({"refreshToken": data["RefreshToken"]}) + self.tokens.tokenData.update({"accessToken": data["AccessToken"]}) + if update_expiry_time: + self.tokens.tokenCreated = datetime.now() + elif "token" in tokens: + data = tokens + self.tokens.tokenData.update({"token": data["token"]}) + self.tokens.tokenData.update({"refreshToken": data["refreshToken"]}) + self.tokens.tokenData.update({"accessToken": data["accessToken"]}) + + if "ExpiresIn" in data: + self.tokens.tokenExpiry = timedelta(seconds=data["ExpiresIn"]) + + return self.tokens + + async def login(self): + """Login to hive account. + + Raises: + HiveUnknownConfiguration: Login information is unknown. + + Returns: + dict: result of the authentication request. + """ + result = None + if not self.auth: + raise HiveUnknownConfiguration + + try: + result = await self.auth.login() + except HiveInvalidUsername: + print("invalid_username") + except HiveInvalidPassword: + print("invalid_password") + except HiveApiError: + print("no_internet_available") + + if "AuthenticationResult" in result: + await self.update_tokens(result) + return result + + async def sms_2fa(self, code, session): + """Login to hive account with 2 factor authentication. + + Raises: + HiveUnknownConfiguration: Login information is unknown. + + Returns: + dict: result of the authentication request. + """ + result = None + if not self.auth: + raise HiveUnknownConfiguration + + try: + result = await self.auth.sms_2fa(code, session) + except HiveInvalid2FACode: + print("invalid_code") + except HiveApiError: + print("no_internet_available") + + if "AuthenticationResult" in result: + await self.update_tokens(result) + return result + + async def device_login(self): + """Login to hive account using device authentication. + + Raises: + HiveUnknownConfiguration: Login information is unknown. + HiveInvalidDeviceAuthentication: Device information is unknown. + + Returns: + dict: result of the authentication request. + """ + result = None + if not self.auth: + raise HiveUnknownConfiguration + + try: + result = await self.auth.device_login() + except HiveInvalidDeviceAuthentication: + raise HiveInvalidDeviceAuthentication + + if "AuthenticationResult" in result: + await self.update_tokens(result) + self.tokens.tokenExpiry = timedelta(seconds=0) + return result + + async def hive_refresh_tokens(self): + """Refresh Hive tokens. + + Returns: + boolean: True/False if update was successful + """ + result = None + + if self.config.file: + return None + else: + expiry_time = self.tokens.tokenCreated + self.tokens.tokenExpiry + if datetime.now() >= expiry_time: + result = await self.auth.refresh_token( + self.tokens.tokenData["refreshToken"] + ) + + if "AuthenticationResult" in result: + await self.update_tokens(result) + else: + raise HiveFailedToRefreshTokens + + return result + + async def update_data(self, device: dict): + """Get latest data for Hive nodes - rate limiting. + + Args: + device (dict): Device requesting the update. + + Returns: + boolean: True/False if update was successful + """ + updated = False + ep = self.config.lastUpdate + self.config.scanInterval + if datetime.now() >= ep and not self.updateLock.locked(): + try: + await self.updateLock.acquire() + await self.get_devices(device["hiveID"]) + if len(self.device_list["camera"]) > 0: + for camera in self.data.camera: + await self.get_camera(self.devices[camera]) + updated = True + finally: + self.updateLock.release() + + return updated + + async def get_alarm(self): + """Get alarm data. + + Raises: + HTTPException: HTTP error has occurred updating the devices. + HiveApiError: An API error code has been returned. + """ + if self.config.file: + api_resp_d = self.open_file("alarm.json") + elif self.tokens is not None: + api_resp_d = await self.api.getAlarm() + if operator.contains(str(api_resp_d["original"]), "20") is False: + raise HTTPException + elif api_resp_d["parsed"] is None: + raise HiveApiError + + self.data.alarm = api_resp_d["parsed"] + + async def get_camera(self, device): + """Get camera data. + + Raises: + HTTPException: HTTP error has occurred updating the devices. + HiveApiError: An API error code has been returned. + """ + cameraImage = None + cameraRecording = None + hasCameraImage = False + hasCameraRecording = False + + if self.config.file: + cameraImage = self.open_file("camera.json") + cameraRecording = self.open_file("camera.json") + elif self.tokens is not None: + cameraImage = await self.api.getCameraImage(device) + hasCameraRecording = bool( + cameraImage["parsed"]["events"][0]["hasRecording"] + ) + if hasCameraRecording: + cameraRecording = await self.api.getCameraRecording( + device, cameraImage["parsed"]["events"][0]["eventId"] + ) + + if operator.contains(str(cameraImage["original"]), "20") is False: + raise HTTPException + elif cameraImage["parsed"] is None: + raise HiveApiError + else: + raise NoApiToken + + hasCameraImage = bool(cameraImage["parsed"]["events"][0]) + + self.data.camera[device["id"]] = {} + self.data.camera[device["id"]]["cameraImage"] = None + self.data.camera[device["id"]]["cameraRecording"] = None + + if cameraImage is not None and hasCameraImage: + self.data.camera[device["id"]] = {} + self.data.camera[device["id"]]["cameraImage"] = cameraImage["parsed"][ + "events" + ][0] + if cameraRecording is not None and hasCameraRecording: + self.data.camera[device["id"]]["cameraRecording"] = cameraRecording[ + "parsed" + ] + + async def get_devices(self, n_id: str): + """Get latest data for Hive nodes. + + Args: + n_id (str): ID of the device requesting data. + + Raises: + HTTPException: HTTP error has occurred updating the devices. + HiveApiError: An API error code has been returned. + + Returns: + boolean: True/False if update was successful. + """ + get_nodes_successful = False + api_resp_d = None + + try: + if self.config.file: + api_resp_d = self.open_file("data.json") + elif self.tokens is not None: + await self.hive_refresh_tokens() + api_resp_d = await self.api.getAll() + if operator.contains(str(api_resp_d["original"]), "20") is False: + raise HTTPException + elif api_resp_d["parsed"] is None: + raise HiveApiError + + api_resp_p = api_resp_d["parsed"] + tmpProducts = {} + tmpDevices = {} + tmpActions = {} + + for hiveType in api_resp_p: + if hiveType == "user": + self.data.user = api_resp_p[hiveType] + self.config.userID = api_resp_p[hiveType]["id"] + if hiveType == "products": + for aProduct in api_resp_p[hiveType]: + tmpProducts.update({aProduct["id"]: aProduct}) + if hiveType == "devices": + for aDevice in api_resp_p[hiveType]: + tmpDevices.update({aDevice["id"]: aDevice}) + if aDevice["type"] == "siren": + self.config.alarm = True + # if aDevice["type"] == "hivecamera": + # await self.getCamera(aDevice) + if hiveType == "actions": + for aAction in api_resp_p[hiveType]: + tmpActions.update({aAction["id"]: aAction}) + if hiveType == "homes": + self.config.homeID = api_resp_p[hiveType]["homes"][0]["id"] + + if len(tmpProducts) > 0: + self.data.products = copy.deepcopy(tmpProducts) + if len(tmpDevices) > 0: + self.data.devices = copy.deepcopy(tmpDevices) + self.data.actions = copy.deepcopy(tmpActions) + if self.config.alarm: + await self.get_alarm() + self.config.lastUpdate = datetime.now() + get_nodes_successful = True + except (OSError, RuntimeError, HiveApiError, ConnectionError, HTTPException): + get_nodes_successful = False + + return get_nodes_successful + + async def start_session(self, config: dict = {}): + """Setup the Hive platform. + + Args: + config (dict, optional): Configuration for Home Assistant to use. Defaults to {}. + + Raises: + HiveUnknownConfiguration: Unknown configuration identifed. + HiveReauthRequired: Tokens have expired and reauthentication is required. + + Returns: + list: List of devices + """ + await self.use_file(config.get("username", self.config.username)) + await self.update_interval( + config.get("options", {}).get("scan_interval", self.config.scanInterval) + ) + + if config != {}: + if "tokens" in config and not self.config.file: + await self.update_tokens(config["tokens"], False) + + if "device_data" in config and not self.config.file: + self.auth.device_group_key = config["device_data"][0] + self.auth.device_key = config["device_data"][1] + self.auth.device_password = config["device_data"][2] + + if not self.config.file and "tokens" not in config: + raise HiveUnknownConfiguration + + try: + await self.get_devices("No_ID") + except HTTPException: + return HTTPException + + if self.data.devices == {} or self.data.products == {}: + raise HiveReauthRequired + + return await self.create_devices() + + async def create_devices(self): + """Create list of devices. + + Returns: + list: List of devices + """ + self.device_list["alarm_control_panel"] = [] + self.device_list["binary_sensor"] = [] + self.device_list["camera"] = [] + self.device_list["climate"] = [] + self.device_list["light"] = [] + self.device_list["sensor"] = [] + self.device_list["switch"] = [] + self.device_list["water_heater"] = [] + + hive_type = HIVE_TYPES["Heating"] + HIVE_TYPES["Switch"] + HIVE_TYPES["Light"] + for aProduct in self.data.products: + p = self.data.products[aProduct] + if "error" in p: + continue + # Only consider single items or heating groups + if ( + p.get("isGroup", False) + and self.data.products[aProduct]["type"] not in HIVE_TYPES["Heating"] + ): + continue + product_list = PRODUCTS.get(self.data.products[aProduct]["type"], []) + for code in product_list: + eval("self." + code) + + if self.data.products[aProduct]["type"] in hive_type: + self.config.mode.append(p["id"]) + + hive_type = HIVE_TYPES["Thermo"] + HIVE_TYPES["Sensor"] + for aDevice in self.data["devices"]: + d = self.data.devices[aDevice] + device_list = DEVICES.get(self.data.devices[aDevice]["type"], []) + for code in device_list: + eval("self." + code) + + if self.data["devices"][aDevice]["type"] in hive_type: + self.config.battery.append(d["id"]) + + if "action" in HIVE_TYPES["Switch"]: + for action in self.data["actions"]: + a = self.data["actions"][action] # noqa: F841 + eval("self." + ACTIONS) + + return self.device_list + + @staticmethod + def epoch_time(date_time: any, pattern: str, action: str): + """date/time conversion to epoch. + + Args: + date_time (any): epoch time or date and time to use. + pattern (str): Pattern for converting to epoch. + action (str): Convert from/to. + + Returns: + any: Converted time. + """ + if action == "to_epoch": + pattern = "%d.%m.%Y %H:%M:%S" + epochtime = int(time.mktime(time.strptime(str(date_time), pattern))) + return epochtime + elif action == "from_epoch": + date = datetime.fromtimestamp(int(date_time)).strftime(pattern) + return date \ No newline at end of file diff --git a/tests/apyhiveapi/test_hub.py b/tests/apyhiveapi/test_hub.py index e5fd03e..f6e3611 100644 --- a/tests/apyhiveapi/test_hub.py +++ b/tests/apyhiveapi/test_hub.py @@ -15,7 +15,7 @@ async def test_hub_get_smoke_status_detected(): hive_session.session.data.products[smoke_sensor["hiveID"]]["props"]["sensors"][ "SMOKE_CO" ]["active"] = True - state = await hive_session.hub.getSmokeStatus(smoke_sensor) + state = await hive_session.hub.get_smoke_status(smoke_sensor) assert state == 1 @@ -28,7 +28,7 @@ async def test_hub_get_smoke_status_not_detected(): hive_session = hive.async_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] - state = await hive_session.hub.getSmokeStatus(smoke_sensor) + state = await hive_session.hub.get_smoke_status(smoke_sensor) assert state == 0 @@ -41,7 +41,7 @@ async def test_hub_get_smoke_status_with_key_error(): hive_session = hive.async_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] hive_session.session.data.products.pop(smoke_sensor["hiveID"]) - state = await hive_session.hub.getSmokeStatus(smoke_sensor) + state = await hive_session.hub.get_smoke_status(smoke_sensor) assert state is None @@ -53,7 +53,7 @@ async def test_hub_get_glass_break_detected(): await hive.async_start_session() hive_session = hive.async_hive glass_sensor = hive_session.session.device_list["binary_sensor"][0] - state = await hive_session.hub.getGlassBreakStatus(glass_sensor) + state = await hive_session.hub.get_glass_break_status(glass_sensor) assert state == 1 @@ -68,7 +68,7 @@ async def test_hub_get_glass_break_not_detected(): hive_session.session.data.products[glass_sensor["hiveID"]]["props"]["sensors"][ "GLASS_BREAK" ]["active"] = False - state = await hive_session.hub.getGlassBreakStatus(glass_sensor) + state = await hive_session.hub.get_glass_break_status(glass_sensor) assert state == 0 @@ -81,7 +81,7 @@ async def test_hub_get_glass_break_detection_with_key_error(): hive_session = hive.async_hive glass_sensor = hive_session.session.device_list["binary_sensor"][0] hive_session.session.data.products.pop(glass_sensor["hiveID"]) - state = await hive_session.hub.getGlassBreakStatus(glass_sensor) + state = await hive_session.hub.get_glass_break_status(glass_sensor) assert state is None @@ -96,7 +96,7 @@ async def test_hub_get_dog_bark_detected(): hive_session.session.data.products[dog_sensor["hiveID"]]["props"]["sensors"][ "DOG_BARK" ]["active"] = True - state = await hive_session.hub.getDogBarkStatus(dog_sensor) + state = await hive_session.hub.get_dog_bark_status(dog_sensor) assert state == 1 @@ -108,7 +108,7 @@ async def test_hub_get_dog_bark_not_detected(): await hive.async_start_session() hive_session = hive.async_hive dog_sensor = hive_session.session.device_list["binary_sensor"][2] - state = await hive_session.hub.getDogBarkStatus(dog_sensor) + state = await hive_session.hub.get_dog_bark_status(dog_sensor) assert state == 0 @@ -121,6 +121,6 @@ async def test_hub_get_dog_bark_detection_status_with_key_error(): hive_session = hive.async_hive dog_sensor = hive_session.session.device_list["binary_sensor"][2] hive_session.session.data.products.pop(dog_sensor["hiveID"]) - state = await hive_session.hub.getDogBarkStatus(dog_sensor) + state = await hive_session.hub.get_dog_bark_status(dog_sensor) assert state is None diff --git a/tests/apyhiveapi/test_session.py b/tests/apyhiveapi/test_session.py index 5a2be39..a69d772 100644 --- a/tests/apyhiveapi/test_session.py +++ b/tests/apyhiveapi/test_session.py @@ -6,7 +6,7 @@ @pytest.mark.asyncio -async def test_start_session(): +async def test_startSession(): """Test a session can be started.""" hive = MockSession() device_list = await hive.async_start_session() diff --git a/tests/common.py b/tests/common.py index 10a5e35..0d56566 100644 --- a/tests/common.py +++ b/tests/common.py @@ -49,9 +49,9 @@ def __init__(self): def sync_start_session(self): """Start a sync session.""" self.sync_hive = HiveSync(username=USERNAME, password=PASSWORD) - return self.sync_hive.start_session(TEMP_CONFIG) + return self.sync_hive.startSession(TEMP_CONFIG) async def async_start_session(self): """Start a async session.""" self.async_hive = HiveAsync(username=USERNAME, password=PASSWORD) - return await self.async_hive.start_session(TEMP_CONFIG) + return await self.async_hive.startSession(TEMP_CONFIG) diff --git a/tests/pyhiveapi/test_hub.py b/tests/pyhiveapi/test_hub.py index 46d3c69..94ca927 100644 --- a/tests/pyhiveapi/test_hub.py +++ b/tests/pyhiveapi/test_hub.py @@ -12,7 +12,7 @@ def test_hub_get_smoke_status_detected(): hive_session.session.data.products[smoke_sensor["hiveID"]]["props"]["sensors"][ "SMOKE_CO" ]["active"] = True - state = hive_session.hub.getSmokeStatus(smoke_sensor) + state = hive_session.hub.get_smoke_status(smoke_sensor) assert state == 1 @@ -24,7 +24,7 @@ def test_hub_get_smoke_status_not_detected(): hive_session = hive.sync_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] - state = hive_session.hub.getSmokeStatus(smoke_sensor) + state = hive_session.hub.get_smoke_status(smoke_sensor) assert state == 0 @@ -36,7 +36,7 @@ def test_hub_get_smoke_status_with_key_error(): hive_session = hive.sync_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] hive_session.session.data.products.pop(smoke_sensor["hiveID"]) - state = hive_session.hub.getSmokeStatus(smoke_sensor) + state = hive_session.hub.get_smoke_status(smoke_sensor) assert state is None @@ -47,7 +47,7 @@ def test_hub_get_glass_break_detected(): hive.sync_start_session() hive_session = hive.sync_hive glass_sensor = hive_session.session.device_list["binary_sensor"][0] - state = hive_session.hub.getGlassBreakStatus(glass_sensor) + state = hive_session.hub.get_glass_break_status(glass_sensor) assert state == 1 @@ -61,7 +61,7 @@ def test_hub_get_glass_break_not_detected(): hive_session.session.data.products[glass_sensor["hiveID"]]["props"]["sensors"][ "GLASS_BREAK" ]["active"] = False - state = hive_session.hub.getGlassBreakStatus(glass_sensor) + state = hive_session.hub.get_glass_break_status(glass_sensor) assert state == 0 @@ -73,7 +73,7 @@ def test_hub_get_glass_break_detection_with_key_error(): hive_session = hive.sync_hive glass_sensor = hive_session.session.device_list["binary_sensor"][0] hive_session.session.data.products.pop(glass_sensor["hiveID"]) - state = hive_session.hub.getGlassBreakStatus(glass_sensor) + state = hive_session.hub.get_glass_break_status(glass_sensor) assert state is None @@ -87,7 +87,7 @@ def test_hub_get_dog_bark_detected(): hive_session.session.data.products[dog_sensor["hiveID"]]["props"]["sensors"][ "DOG_BARK" ]["active"] = True - state = hive_session.hub.getDogBarkStatus(dog_sensor) + state = hive_session.hub.get_dog_bark_status(dog_sensor) assert state == 1 @@ -98,7 +98,7 @@ def test_hub_get_dog_bark_not_detected(): hive.sync_start_session() hive_session = hive.sync_hive dog_sensor = hive_session.session.device_list["binary_sensor"][2] - state = hive_session.hub.getDogBarkStatus(dog_sensor) + state = hive_session.hub.get_dog_bark_status(dog_sensor) assert state == 0 @@ -108,8 +108,8 @@ def test_hub_get_dog_bark_detection_status_with_key_error(): hive = MockSession() hive.sync_start_session() hive_session = hive.sync_hive - dog_sensor = hive_session.session.device_list["binary_sensor"][2] + dog_sensor = hive_session.session.device_list["binary_sensor"][1] hive_session.session.data.products.pop(dog_sensor["hiveID"]) - state = hive_session.hub.getDogBarkStatus(dog_sensor) + state = hive_session.hub.get_dog_bark_status(dog_sensor) assert state is None diff --git a/tests/pyhiveapi/test_session.py b/tests/pyhiveapi/test_session.py index d6e1aad..3f55e05 100644 --- a/tests/pyhiveapi/test_session.py +++ b/tests/pyhiveapi/test_session.py @@ -6,6 +6,6 @@ def test_start_session(): """Test a session can be started.""" hive = MockSession() - device_list = hive.sync_start_session() + hive.sync_start_session() - assert len(device_list) > 0 + assert len(hive.sync_start_session()) > 0 From a2e6b9b7fe07a6f3483d0288d5e5c46b2672eab9 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 9 Dec 2024 23:17:15 +0000 Subject: [PATCH 17/26] 2nd round of change for pylint formatting --- pyhiveapi/apyhiveapi/helper/const.py | 14 +-- src/apyhiveapi/alarm.py | 10 +- src/apyhiveapi/api/hive_api.py | 8 +- src/apyhiveapi/api/hive_async_api.py | 12 +- src/apyhiveapi/camera.py | 12 +- src/apyhiveapi/device_attributes.py | 2 +- src/apyhiveapi/heating.py | 138 ++++++++++----------- src/apyhiveapi/helper/const.py | 15 +-- src/apyhiveapi/helper/hive_helper.py | 8 +- src/apyhiveapi/hive.py | 6 +- src/apyhiveapi/hotwater.py | 18 +-- src/apyhiveapi/light.py | 20 ++-- src/apyhiveapi/plug.py | 18 +-- src/apyhiveapi/sensor.py | 8 +- src/apyhiveapi/session.py | 172 +++++++++++++-------------- tests/apyhiveapi/test_plug.py | 12 +- tests/pyhiveapi/test_plug.py | 12 +- 17 files changed, 243 insertions(+), 242 deletions(-) diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py index 64e6aaf..29c65e1 100644 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ b/pyhiveapi/apyhiveapi/helper/const.py @@ -60,17 +60,17 @@ "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", "Camera_Temp": "self.session.camera.getCameraTemperature(device)", - "Current_Temperature": "self.session.heating.getCurrentTemperature(device)", - "Heating_Current_Temperature": "self.session.heating.getCurrentTemperature(device)", - "Heating_Target_Temperature": "self.session.heating.getTargetTemperature(device)", + "Current_Temperature": "self.session.heating.get_current_temperature(device)", + "Heating_Current_Temperature": "self.session.heating.get_current_temperature(device)", + "Heating_Target_Temperature": "self.session.heating.get_target_temperature(device)", "Heating_State": "self.session.heating.getState(device)", - "Heating_Mode": "self.session.heating.getMode(device)", - "Heating_Boost": "self.session.heating.getBoostStatus(device)", + "Heating_Mode": "self.session.heating.get_mode(device)", + "Heating_Boost": "self.session.heating.get_boost_status(device)", "Hotwater_State": "self.session.hotwater.getState(device)", - "Hotwater_Mode": "self.session.hotwater.getMode(device)", + "Hotwater_Mode": "self.session.hotwater.get_mode(device)", "Hotwater_Boost": "self.session.hotwater.getBoost(device)", "Battery": 'self.session.attr.getBattery(device["device_id"])', - "Mode": 'self.session.attr.getMode(device["hiveID"])', + "Mode": 'self.session.attr.get_mode(device["hiveID"])', "Availability": "self.online(device)", "Connectivity": "self.online(device)", "Power": "self.session.switch.getPowerUsage(device)", diff --git a/src/apyhiveapi/alarm.py b/src/apyhiveapi/alarm.py index 177dd31..d125c49 100644 --- a/src/apyhiveapi/alarm.py +++ b/src/apyhiveapi/alarm.py @@ -62,7 +62,7 @@ async def set_mode(self, device: dict, mode: str): resp = await self.session.api.set_alarm(mode=mode) if resp["original"] == 200: final = True - await self.session.getAlarm() + await self.session.get_alarm() return final @@ -92,12 +92,12 @@ async def get_alarm(self, device: dict): dict: Updated device. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} if device["deviceData"]["online"]: - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { "hiveID": device["hiveID"], @@ -114,7 +114,7 @@ async def get_alarm(self, device: dict): "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), "custom": device.get("custom", None), - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } @@ -122,7 +122,7 @@ async def get_alarm(self, device: dict): self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device diff --git a/src/apyhiveapi/api/hive_api.py b/src/apyhiveapi/api/hive_api.py index 1e957bd..ab19700 100644 --- a/src/apyhiveapi/api/hive_api.py +++ b/src/apyhiveapi/api/hive_api.py @@ -49,14 +49,14 @@ def request(self, type, url, jsc=None, camera=False): self.headers = { "content-type": "application/json", "Accept": "*/*", - "Authorization": f"Bearer {self.session.tokens.tokenData['token']}", - "x-jwt-token": self.session.tokens.tokenData["token"], + "Authorization": f"Bearer {self.session.tokens.token_data['token']}", + "x-jwt-token": self.session.tokens.token_data["token"], } else: self.headers = { "content-type": "application/json", "Accept": "*/*", - "authorization": self.session.tokens.tokenData["token"], + "authorization": self.session.tokens.token_data["token"], } else: if camera: @@ -86,7 +86,7 @@ def refresh_tokens(self, tokens={}): """Get new session tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" url = self.urls["refresh"] if self.session is not None: - tokens = self.session.tokens.tokenData + tokens = self.session.tokens.token_data jsc = ( "{" + ",".join( diff --git a/src/apyhiveapi/api/hive_async_api.py b/src/apyhiveapi/api/hive_async_api.py index 5952297..7506182 100644 --- a/src/apyhiveapi/api/hive_async_api.py +++ b/src/apyhiveapi/api/hive_async_api.py @@ -17,7 +17,7 @@ class HiveApiAsync: """Hive API Code.""" - def __init__(self, hiveSession=None, websession: Optional[ClientSession] = None): + def __init__(self, hive_session=None, websession: Optional[ClientSession] = None): """Hive API initialisation.""" self.baseUrl = "https://beekeeper.hivehome.com/1.0" self.cameraBaseUrl = "prod.hcam.bgchtest.info" @@ -42,7 +42,7 @@ def __init__(self, hiveSession=None, websession: Optional[ClientSession] = None) "original": "No response to Hive API request", "parsed": "No response to Hive API request", } - self.session = hiveSession + self.session = hive_session self.websession = ClientSession() if websession is None else websession async def request( @@ -56,14 +56,14 @@ async def request( headers = { "content-type": "application/json", "Accept": "*/*", - "Authorization": f"Bearer {self.session.tokens.tokenData['token']}", - "x-jwt-token": self.session.tokens.tokenData["token"], + "Authorization": f"Bearer {self.session.tokens.token_data['token']}", + "x-jwt-token": self.session.tokens.token_data["token"], } else: headers = { "content-type": "application/json", "Accept": "*/*", - "authorization": self.session.tokens.tokenData["token"], + "authorization": self.session.tokens.token_data["token"], } except KeyError: if "sso" in url: @@ -116,7 +116,7 @@ async def refresh_tokens(self): """Refresh tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" url = self.urls["refresh"] if self.session is not None: - tokens = self.session.tokens.tokenData + tokens = self.session.tokens.token_data jsc = ( "{" + ",".join( diff --git a/src/apyhiveapi/camera.py b/src/apyhiveapi/camera.py index 6bf1694..be6f20b 100644 --- a/src/apyhiveapi/camera.py +++ b/src/apyhiveapi/camera.py @@ -91,7 +91,7 @@ async def set_camera_on(self, device: dict, mode: str): and device["deviceData"]["online"] ): await self.session.hive_refresh_tokens() - resp = await self.session.api.setState(mode=mode) + resp = await self.session.api.set_state(mode=mode) if resp["original"] == 200: final = True await self.session.get_camera() @@ -114,7 +114,7 @@ async def set_camera_off(self, device: dict, mode: str): and device["deviceData"]["online"] ): await self.session.hive_refresh_tokens() - resp = await self.session.api.setState(mode=mode) + resp = await self.session.api.set_state(mode=mode) if resp["original"] == 200: final = True await self.session.get_camera() @@ -147,12 +147,12 @@ async def get_camera(self, device: dict): dict: Updated device. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} if device["deviceData"]["online"]: - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { "hiveID": device["hiveID"], @@ -171,7 +171,7 @@ async def get_camera(self, device: dict): "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), "custom": device.get("custom", None), - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } @@ -179,7 +179,7 @@ async def get_camera(self, device: dict): self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device diff --git a/src/apyhiveapi/device_attributes.py b/src/apyhiveapi/device_attributes.py index 2477ef2..3ef3397 100644 --- a/src/apyhiveapi/device_attributes.py +++ b/src/apyhiveapi/device_attributes.py @@ -95,7 +95,7 @@ async def get_battery(self, n_id: str): data = self.session.data.devices[n_id] state = data["props"]["battery"] final = state - await self.session.log.errorCheck(n_id, self.type, state) + await self.session.log.error_check(n_id, self.type, state) except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/heating.py b/src/apyhiveapi/heating.py index a2e29e1..5832028 100644 --- a/src/apyhiveapi/heating.py +++ b/src/apyhiveapi/heating.py @@ -12,7 +12,7 @@ class HiveHeating: heatingType = "Heating" - async def getMinTemperature(self, device: dict): + async def get_min_temperature(self, device: dict): """Get heating minimum target temperature. Args: @@ -25,7 +25,7 @@ async def getMinTemperature(self, device: dict): return self.session.data.products[device["hiveID"]]["props"]["minHeat"] return 5 - async def getMaxTemperature(self, device: dict): + async def get_max_temperature(self, device: dict): """Get heating maximum target temperature. Args: @@ -38,7 +38,7 @@ async def getMaxTemperature(self, device: dict): return self.session.data.products[device["hiveID"]]["props"]["maxHeat"] return 32 - async def getCurrentTemperature(self, device: dict): + async def get_current_temperature(self, device: dict): """Get heating current temperature. Args: @@ -57,28 +57,28 @@ async def getCurrentTemperature(self, device: dict): data = self.session.data.products[device["hiveID"]] state = data["props"]["temperature"] - if device["hiveID"] in self.session.data.minMax: - if self.session.data.minMax[device["hiveID"]]["TodayDate"] == str( + if device["hiveID"] in self.session.data.min_max: + if self.session.data.min_max[device["hiveID"]]["TodayDate"] == str( datetime.date(datetime.now()) ): - if state < self.session.data.minMax[device["hiveID"]]["TodayMin"]: - self.session.data.minMax[device["hiveID"]]["TodayMin"] = state + if state < self.session.data.min_max[device["hiveID"]]["TodayMin"]: + self.session.data.min_max[device["hiveID"]]["TodayMin"] = state - if state > self.session.data.minMax[device["hiveID"]]["TodayMax"]: - self.session.data.minMax[device["hiveID"]]["TodayMax"] = state + if state > self.session.data.min_max[device["hiveID"]]["TodayMax"]: + self.session.data.min_max[device["hiveID"]]["TodayMax"] = state else: data = { "TodayMin": state, "TodayMax": state, "TodayDate": str(datetime.date(datetime.now())), } - self.session.data.minMax[device["hiveID"]].update(data) + self.session.data.min_max[device["hiveID"]].update(data) - if state < self.session.data.minMax[device["hiveID"]]["RestartMin"]: - self.session.data.minMax[device["hiveID"]]["RestartMin"] = state + if state < self.session.data.min_max[device["hiveID"]]["RestartMin"]: + self.session.data.min_max[device["hiveID"]]["RestartMin"] = state - if state > self.session.data.minMax[device["hiveID"]]["RestartMax"]: - self.session.data.minMax[device["hiveID"]]["RestartMax"] = state + if state > self.session.data.min_max[device["hiveID"]]["RestartMax"]: + self.session.data.min_max[device["hiveID"]]["RestartMax"] = state else: data = { "TodayMin": state, @@ -87,7 +87,7 @@ async def getCurrentTemperature(self, device: dict): "RestartMin": state, "RestartMax": state, } - self.session.data.minMax[device["hiveID"]] = data + self.session.data.min_max[device["hiveID"]] = data f_state = round(float(state), 1) final = f_state @@ -96,7 +96,7 @@ async def getCurrentTemperature(self, device: dict): return final - async def getTargetTemperature(self, device: dict): + async def get_target_temperature(self, device: dict): """Get heating target temperature. Args: @@ -116,7 +116,7 @@ async def getTargetTemperature(self, device: dict): return state - async def getMode(self, device: dict): + async def get_mode(self, device: dict): """Get heating current mode. Args: @@ -152,8 +152,8 @@ async def getState(self, device: dict): final = None try: - current_temp = await self.getCurrentTemperature(device) - target_temp = await self.getTargetTemperature(device) + current_temp = await self.get_current_temperature(device) + target_temp = await self.get_target_temperature(device) if current_temp < target_temp: state = "ON" else: @@ -164,7 +164,7 @@ async def getState(self, device: dict): return final - async def getCurrentOperation(self, device: dict): + async def get_current_operation(self, device: dict): """Get heating current operation. Args: @@ -183,7 +183,7 @@ async def getCurrentOperation(self, device: dict): return state - async def getBoostStatus(self, device: dict): + async def get_boost_status(self, device: dict): """Get heating boost current status. Args: @@ -202,7 +202,7 @@ async def getBoostStatus(self, device: dict): return state - async def getBoostTime(self, device: dict): + async def get_boost_time(self, device: dict): """Get heating boost time remaining. Args: @@ -211,7 +211,7 @@ async def getBoostTime(self, device: dict): Returns: str: Boost time. """ - if await self.getBoostStatus(device) == "ON": + if await self.get_boost_status(device) == "ON": state = None try: @@ -223,7 +223,7 @@ async def getBoostTime(self, device: dict): return state return None - async def getHeatOnDemand(self, device): + async def get_heat_on_demand(self, device): """Get heat on demand status. Args: @@ -243,7 +243,7 @@ async def getHeatOnDemand(self, device): return state @staticmethod - async def getOperationModes(): + async def get_operation_modes(): """Get heating list of possible modes. Returns: @@ -251,7 +251,7 @@ async def getOperationModes(): """ return ["SCHEDULE", "MANUAL", "OFF"] - async def setTargetTemperature(self, device: dict, new_temp: str): + async def set_target_temperature(self, device: dict, new_temp: str): """Set heating target temperature. Args: @@ -261,26 +261,26 @@ async def setTargetTemperature(self, device: dict, new_temp: str): Returns: boolean: True/False if successful """ - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() final = False if ( device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], target=new_temp ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices(device["hiveID"]) final = True return final - async def setMode(self, device: dict, new_mode: str): + async def set_mode(self, device: dict, new_mode: str): """Set heating mode. Args: @@ -290,7 +290,7 @@ async def setMode(self, device: dict, new_mode: str): Returns: boolean: True/False if successful """ - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() final = False if ( @@ -298,17 +298,17 @@ async def setMode(self, device: dict, new_mode: str): and device["deviceData"]["online"] ): data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode=new_mode ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices(device["hiveID"]) final = True return final - async def setBoostOn(self, device: dict, mins: str, temp: float): + async def set_boost_on(self, device: dict, mins: str, temp: float): """Turn heating boost on. Args: @@ -319,9 +319,9 @@ async def setBoostOn(self, device: dict, mins: str, temp: float): Returns: boolean: True/False if successful """ - if int(mins) > 0 and int(temp) >= await self.getMinTemperature(device): - if int(temp) <= await self.getMaxTemperature(device): - await self.session.hiveRefreshTokens() + if int(mins) > 0 and int(temp) >= await self.get_min_temperature(device): + if int(temp) <= await self.get_max_temperature(device): + await self.session.hive_refresh_tokens() final = False if ( @@ -329,7 +329,7 @@ async def setBoostOn(self, device: dict, mins: str, temp: float): and device["deviceData"]["online"] ): data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode="BOOST", @@ -338,13 +338,13 @@ async def setBoostOn(self, device: dict, mins: str, temp: float): ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices(device["hiveID"]) final = True return final return None - async def setBoostOff(self, device: dict): + async def set_boost_off(self, device: dict): """Turn heating boost off. Args: @@ -359,30 +359,30 @@ async def setBoostOff(self, device: dict): device["hiveID"] in self.session.data.products and device["deviceData"]["online"] ): - await self.session.hiveRefreshTokens() + await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - await self.session.getDevices(device["hiveID"]) - if await self.getBoostStatus(device) == "ON": + await self.session.get_devices(device["hiveID"]) + if await self.get_boost_status(device) == "ON": prev_mode = data["props"]["previous"]["mode"] if prev_mode == "MANUAL" or prev_mode == "OFF": pre_temp = data["props"]["previous"].get("target", 7) - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode=prev_mode, target=pre_temp, ) else: - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode=prev_mode ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices(device["hiveID"]) final = True return final - async def setHeatOnDemand(self, device: dict, state: str): + async def set_heat_on_demand(self, device: dict, state: str): """Enable or disable Heat on Demand for a Thermostat. Args: @@ -399,13 +399,13 @@ async def setHeatOnDemand(self, device: dict, state: str): and device["deviceData"]["online"] ): data = self.session.data.products[device["hiveID"]] - await self.session.hiveRefreshTokens() - resp = await self.session.api.setState( + await self.session.hive_refresh_tokens() + resp = await self.session.api.set_state( data["type"], device["hiveID"], autoBoost=state ) if resp["original"] == 200: - await self.session.getDevices(device["hiveID"]) + await self.session.get_devices(device["hiveID"]) final = True return final @@ -426,7 +426,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getClimate(self, device: dict): + async def get_climate(self, device: dict): """Get heating data. Args: @@ -436,12 +436,12 @@ async def getClimate(self, device: dict): dict: Updated device. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) if device["deviceData"]["online"]: dev_data = {} - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { "hiveID": device["hiveID"], @@ -452,31 +452,31 @@ async def getClimate(self, device: dict): "device_id": device["device_id"], "device_name": device["device_name"], "temperatureunit": device["temperatureunit"], - "min_temp": await self.getMinTemperature(device), - "max_temp": await self.getMaxTemperature(device), + "min_temp": await self.get_min_temperature(device), + "max_temp": await self.get_max_temperature(device), "status": { - "current_temperature": await self.getCurrentTemperature(device), - "target_temperature": await self.getTargetTemperature(device), - "action": await self.getCurrentOperation(device), - "mode": await self.getMode(device), - "boost": await self.getBoostStatus(device), + "current_temperature": await self.get_current_temperature(device), + "target_temperature": await self.get_target_temperature(device), + "action": await self.get_current_operation(device), + "mode": await self.get_mode(device), + "boost": await self.get_boost_status(device), }, "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), "custom": device.get("custom", None), - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device - async def getScheduleNowNextLater(self, device: dict): + async def get_schedule_now_next_later(self, device: dict): """Hive get heating schedule now, next and later. Args: @@ -485,20 +485,20 @@ async def getScheduleNowNextLater(self, device: dict): Returns: dict: Schedule now, next and later """ - online = await self.session.attr.onlineOffline(device["device_id"]) - current_mode = await self.getMode(device) + online = await self.session.attr.online_offline(device["device_id"]) + current_mode = await self.get_mode(device) state = None try: if online and current_mode == "SCHEDULE": data = self.session.data.products[device["hiveID"]] - state = self.session.helper.getScheduleNNL(data["state"]["schedule"]) + state = self.session.helper.get_schedule_nnl(data["state"]["schedule"]) except KeyError as e: await self.session.log.error(e) return state - async def minmaxTemperature(self, device: dict): + async def min_max_temperature(self, device: dict): """Min/Max Temp. Args: @@ -511,7 +511,7 @@ async def minmaxTemperature(self, device: dict): final = None try: - state = self.session.data.minMax[device["hiveID"]] + state = self.session.data.min_max[device["hiveID"]] final = state except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/helper/const.py b/src/apyhiveapi/helper/const.py index 49c7456..03d56f6 100644 --- a/src/apyhiveapi/helper/const.py +++ b/src/apyhiveapi/helper/const.py @@ -60,17 +60,17 @@ "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", "Camera_Temp": "self.session.camera.getCameraTemperature(device)", - "Current_Temperature": "self.session.heating.getCurrentTemperature(device)", - "Heating_Current_Temperature": "self.session.heating.getCurrentTemperature(device)", - "Heating_Target_Temperature": "self.session.heating.getTargetTemperature(device)", + "Current_Temperature": "self.session.heating.get_current_temperature(device)", + "Heating_Current_Temperature": "self.session.heating.get_current_temperature(device)", + "Heating_Target_Temperature": "self.session.heating.get_target_temperature(device)", "Heating_State": "self.session.heating.getState(device)", - "Heating_Mode": "self.session.heating.getMode(device)", - "Heating_Boost": "self.session.heating.getBoostStatus(device)", + "Heating_Mode": "self.session.heating.get_mode(device)", + "Heating_Boost": "self.session.heating.get_boost_status(device)", "Hotwater_State": "self.session.hotwater.getState(device)", - "Hotwater_Mode": "self.session.hotwater.getMode(device)", + "Hotwater_Mode": "self.session.hotwater.get_mode(device)", "Hotwater_Boost": "self.session.hotwater.getBoost(device)", "Battery": 'self.session.attr.getBattery(device["device_id"])', - "Mode": 'self.session.attr.getMode(device["hiveID"])', + "Mode": 'self.session.attr.get_mode(device["hiveID"])', "Availability": "self.online(device)", "Connectivity": "self.online(device)", "Power": "self.session.switch.getPowerUsage(device)", @@ -110,6 +110,7 @@ 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', 'addList("sensor", p, haName=" Power", hiveType="Power", category="diagnostic")', + 'addList("sensor", p, haName=" Energy", hiveType="Energy", category="diagnostic")', ], "warmwhitelight": [ 'addList("light", p)', diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index 72bdd87..d008aec 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -219,15 +219,15 @@ async def call_sensor_function(self, device): if device["hiveType"] == "Camera_Temp": return await self.session.camera.getCameraTemperature(device) if device["hiveType"] == "Heating_Current_Temperature": - return await self.session.heating.getCurrentTemperature(device) + return await self.session.heating.get_current_temperature(device) if device["hiveType"] == "Heating_Target_Temperature": - return await self.session.heating.getTargetTemperature(device) + return await self.session.heating.get_target_temperature(device) if device["hiveType"] == "Heating_State": return await self.session.heating.getState(device) if device["hiveType"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): - return await self.session.heating.getMode(device) + return await self.session.heating.get_mode(device) if device["hiveType"] == "Heating_Boost": - return await self.session.heating.getBoostStatus(device) + return await self.session.heating.get_boost_status(device) if device["hiveType"] == "Hotwater_State": return await self.session.hotwater.getState(device) if device["hiveType"] == "Hotwater_Boost": diff --git a/src/apyhiveapi/hive.py b/src/apyhiveapi/hive.py index eb7c560..222a69f 100644 --- a/src/apyhiveapi/hive.py +++ b/src/apyhiveapi/hive.py @@ -17,7 +17,7 @@ from .light import Light from .plug import Switch from .sensor import Sensor -from .session import HiveSession +from .session import hive_session debug = [] home = expanduser("~") @@ -88,11 +88,11 @@ def trace_debug(frame, event, arg): return trace_debug -class Hive(HiveSession): +class Hive(hive_session): """Hive Class. Args: - HiveSession (object): Interact with Hive Account + hive_session (object): Interact with Hive Account """ def __init__( diff --git a/src/apyhiveapi/hotwater.py b/src/apyhiveapi/hotwater.py index 7e029a5..50bb25b 100644 --- a/src/apyhiveapi/hotwater.py +++ b/src/apyhiveapi/hotwater.py @@ -105,7 +105,7 @@ async def get_state(self, device: dict): if await self.get_boost(device) == "ON": state = "ON" else: - snan = self.session.helper.getScheduleNNL(data["state"]["schedule"]) + snan = self.session.helper.get_schedule_nnl(data["state"]["schedule"]) state = snan["now"]["value"]["status"] final = HIVETOHA[self.hotwaterType].get(state, state) @@ -129,7 +129,7 @@ async def set_mode(self, device: dict, new_mode: str): if device["hiveID"] in self.session.data.products: await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode=new_mode ) if resp["original"] == 200: @@ -157,7 +157,7 @@ async def set_boost_on(self, device: dict, mins: int): ): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode="BOOST", boost=mins ) if resp["original"] == 200: @@ -185,7 +185,7 @@ async def set_boost_off(self, device: dict): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] prev_mode = data["props"]["previous"]["mode"] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], mode=prev_mode ) if resp["original"] == 200: @@ -220,13 +220,13 @@ async def get_water_heater(self, device: dict): dict: Updated device. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) if device["deviceData"]["online"]: dev_data = {} - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { "hiveID": device["hiveID"], @@ -240,7 +240,7 @@ async def get_water_heater(self, device: dict): "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), "custom": device.get("custom", None), - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } @@ -248,7 +248,7 @@ async def get_water_heater(self, device: dict): self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device @@ -268,7 +268,7 @@ async def get_schedule_now_next_later(self, device: dict): mode_current = await self.get_mode(device) if mode_current == "SCHEDULE": data = self.session.data.products[device["hiveID"]] - state = self.session.helper.getScheduleNNL(data["state"]["schedule"]) + state = self.session.helper.get_schedule_nnl(data["state"]["schedule"]) except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/light.py b/src/apyhiveapi/light.py index ce9c416..e89c4b9 100644 --- a/src/apyhiveapi/light.py +++ b/src/apyhiveapi/light.py @@ -182,7 +182,7 @@ async def setStatusOff(self, device: dict): ): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], status="OFF" ) @@ -210,7 +210,7 @@ async def setStatusOn(self, device: dict): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], status="ON" ) if resp["original"] == 200: @@ -237,7 +237,7 @@ async def setBrightness(self, device: dict, n_brightness: int): ): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], status="ON", @@ -269,13 +269,13 @@ async def setColorTemp(self, device: dict, color_temp: int): data = self.session.data.products[device["hiveID"]] if data["type"] == "tuneablelight": - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], colourTemperature=color_temp, ) else: - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], colourMode="WHITE", @@ -307,7 +307,7 @@ async def setColor(self, device: dict, new_color: list): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], device["hiveID"], colourMode="COLOUR", @@ -347,12 +347,12 @@ async def getLight(self, device: dict): dict: Updated device. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} if device["deviceData"]["online"]: - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { "hiveID": device["hiveID"], @@ -369,7 +369,7 @@ async def getLight(self, device: dict): "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), "custom": device.get("custom", None), - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } @@ -403,7 +403,7 @@ async def getLight(self, device: dict): self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device diff --git a/src/apyhiveapi/plug.py b/src/apyhiveapi/plug.py index 1bbd18b..2af29bc 100644 --- a/src/apyhiveapi/plug.py +++ b/src/apyhiveapi/plug.py @@ -68,7 +68,7 @@ async def set_status_on(self, device: dict): ): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], data["id"], status="ON" ) if resp["original"] == 200: @@ -94,7 +94,7 @@ async def set_status_off(self, device: dict): ): await self.session.hive_refresh_tokens() data = self.session.data.products[device["hiveID"]] - resp = await self.session.api.setState( + resp = await self.session.api.set_state( data["type"], data["id"], status="OFF" ) if resp["original"] == 200: @@ -129,12 +129,12 @@ async def get_switch(self, device: dict): dict: Return device after update is complete. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} if device["deviceData"]["online"]: - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { "hiveID": device["hiveID"], @@ -160,7 +160,7 @@ async def get_switch(self, device: dict): "state": dev_data["status"]["state"], "power_usage": await self.get_power_usage(device), }, - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } @@ -169,7 +169,7 @@ async def get_switch(self, device: dict): self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device @@ -184,7 +184,7 @@ async def get_switch_state(self, device: dict): boolean: Return True or False for the state. """ if device["hiveType"] == "Heating_Heat_On_Demand": - return await self.session.heating.getHeatOnDemand(device) + return await self.session.heating.get_heat_on_demand(device) else: return await self.get_state(device) @@ -198,7 +198,7 @@ async def turn_on(self, device: dict): function: Calls relevant function. """ if device["hiveType"] == "Heating_Heat_On_Demand": - return await self.session.heating.setHeatOnDemand(device, "ENABLED") + return await self.session.heating.set_heat_on_demand(device, "ENABLED") else: return await self.set_status_on(device) @@ -212,6 +212,6 @@ async def turn_off(self, device: dict): function: Calls relevant function. """ if device["hiveType"] == "Heating_Heat_On_Demand": - return await self.session.heating.setHeatOnDemand(device, "DISABLED") + return await self.session.heating.set_heat_on_demand(device, "DISABLED") else: return await self.set_status_off(device) diff --git a/src/apyhiveapi/sensor.py b/src/apyhiveapi/sensor.py index 2c1c323..8589d7c 100644 --- a/src/apyhiveapi/sensor.py +++ b/src/apyhiveapi/sensor.py @@ -79,7 +79,7 @@ async def getSensor(self, device: dict): dict: Updated device. """ device["deviceData"].update( - {"online": await self.session.attr.onlineOffline(device["device_id"])} + {"online": await self.session.attr.online_offline(device["device_id"])} ) data = {} @@ -88,7 +88,7 @@ async def getSensor(self, device: dict): "Connectivity", ): if device["hiveType"] not in ("Availability", "Connectivity"): - self.session.helper.deviceRecovered(device["device_id"]) + self.session.helper.device_recovered(device["device_id"]) dev_data = {} dev_data = { @@ -124,7 +124,7 @@ async def getSensor(self, device: dict): "status": {"state": await self.getState(device)}, "deviceData": data.get("props", None), "parentDevice": data.get("parent", None), - "attributes": await self.session.attr.stateAttributes( + "attributes": await self.session.attr.state_attributes( device["device_id"], device["hiveType"] ), } @@ -133,7 +133,7 @@ async def getSensor(self, device: dict): self.session.devices.update({device["hiveID"]: dev_data}) return self.session.devices[device["hiveID"]] else: - await self.session.log.errorCheck( + await self.session.log.error_check( device["device_id"], "ERROR", device["deviceData"]["online"] ) return device diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index 608a1d1..b1ddb8c 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -29,7 +29,7 @@ from .helper.map import Map -class HiveSession: +class hive_session: """Hive Session Code. Raises: @@ -61,16 +61,16 @@ def __init__( username=username, password=password, ) - self.api = API(hiveSession=self, websession=websession) + self.api = API(hive_session=self, websession=websession) self.helper = HiveHelper(self) self.attr = HiveAttributes(self) self.log = Logger(self) - self.updateLock = asyncio.Lock() + self.update_lock = asyncio.Lock() self.tokens = Map( { - "tokenData": {}, - "tokenCreated": datetime.now() - timedelta(seconds=4000), - "tokenExpiry": timedelta(seconds=3600), + "token_data": {}, + "token_created": datetime.now() - timedelta(seconds=4000), + "token_expiry": timedelta(seconds=3600), } ) self.config = Map( @@ -81,9 +81,9 @@ def __init__( "errorList": {}, "file": False, "homeID": None, - "lastUpdated": datetime.now(), + "last_updated": datetime.now(), "mode": [], - "scanInterval": timedelta(seconds=120), + "scan_interval": timedelta(seconds=120), "userID": None, "username": username, } @@ -94,7 +94,7 @@ def __init__( "devices": {}, "actions": {}, "user": {}, - "minMax": {}, + "min_max": {}, "alarm": {}, "camera": {}, } @@ -128,7 +128,7 @@ def add_list(self, entityType: str, data: dict, **kwargs: dict): Returns: dict: Entity. """ - device = self.helper.getDeviceData(data) + device = self.helper.get_device_data(data) device_name = ( device["state"]["name"] if device["state"]["name"] != "Receiver" @@ -172,7 +172,7 @@ async def update_interval(self, new_interval: timedelta): interval = new_interval if interval < timedelta(seconds=15): interval = timedelta(seconds=15) - self.config.scanInterval = interval + self.config.scan_interval = interval async def use_file(self, username: str = None): """Update to check if file is being used. @@ -197,20 +197,20 @@ async def update_tokens(self, tokens: dict, update_expiry_time: bool = True): data = {} if "AuthenticationResult" in tokens: data = tokens.get("AuthenticationResult") - self.tokens.tokenData.update({"token": data["IdToken"]}) + self.tokens.token_data.update({"token": data["IdToken"]}) if "RefreshToken" in data: - self.tokens.tokenData.update({"refreshToken": data["RefreshToken"]}) - self.tokens.tokenData.update({"accessToken": data["AccessToken"]}) + self.tokens.token_data.update({"refreshToken": data["RefreshToken"]}) + self.tokens.token_data.update({"accessToken": data["AccessToken"]}) if update_expiry_time: - self.tokens.tokenCreated = datetime.now() + self.tokens.token_created = datetime.now() elif "token" in tokens: data = tokens - self.tokens.tokenData.update({"token": data["token"]}) - self.tokens.tokenData.update({"refreshToken": data["refreshToken"]}) - self.tokens.tokenData.update({"accessToken": data["accessToken"]}) + self.tokens.token_data.update({"token": data["token"]}) + self.tokens.token_data.update({"refreshToken": data["refreshToken"]}) + self.tokens.token_data.update({"accessToken": data["accessToken"]}) if "ExpiresIn" in data: - self.tokens.tokenExpiry = timedelta(seconds=data["ExpiresIn"]) + self.tokens.token_expiry = timedelta(seconds=data["ExpiresIn"]) return self.tokens @@ -285,7 +285,7 @@ async def device_login(self): if "AuthenticationResult" in result: await self.update_tokens(result) - self.tokens.tokenExpiry = timedelta(seconds=0) + self.tokens.token_expiry = timedelta(seconds=0) return result async def hive_refresh_tokens(self): @@ -299,10 +299,10 @@ async def hive_refresh_tokens(self): if self.config.file: return None else: - expiry_time = self.tokens.tokenCreated + self.tokens.tokenExpiry + expiry_time = self.tokens.token_created + self.tokens.token_expiry if datetime.now() >= expiry_time: result = await self.auth.refresh_token( - self.tokens.tokenData["refreshToken"] + self.tokens.token_data["refreshToken"] ) if "AuthenticationResult" in result: @@ -322,17 +322,17 @@ async def update_data(self, device: dict): boolean: True/False if update was successful """ updated = False - ep = self.config.lastUpdate + self.config.scanInterval - if datetime.now() >= ep and not self.updateLock.locked(): + ep = self.config.last_update + self.config.scan_interval + if datetime.now() >= ep and not self.update_lock.locked(): try: - await self.updateLock.acquire() + await self.update_lock.acquire() await self.get_devices(device["hiveID"]) if len(self.device_list["camera"]) > 0: for camera in self.data.camera: await self.get_camera(self.devices[camera]) updated = True finally: - self.updateLock.release() + self.update_lock.release() return updated @@ -346,7 +346,7 @@ async def get_alarm(self): if self.config.file: api_resp_d = self.open_file("alarm.json") elif self.tokens is not None: - api_resp_d = await self.api.getAlarm() + api_resp_d = await self.api.get_alarm() if operator.contains(str(api_resp_d["original"]), "20") is False: raise HTTPException elif api_resp_d["parsed"] is None: @@ -361,44 +361,44 @@ async def get_camera(self, device): HTTPException: HTTP error has occurred updating the devices. HiveApiError: An API error code has been returned. """ - cameraImage = None - cameraRecording = None - hasCameraImage = False - hasCameraRecording = False + camera_image = None + camera_recording = None + has_camera_image = False + has_camera_recording = False if self.config.file: - cameraImage = self.open_file("camera.json") - cameraRecording = self.open_file("camera.json") + camera_image = self.open_file("camera.json") + camera_recording = self.open_file("camera.json") elif self.tokens is not None: - cameraImage = await self.api.getCameraImage(device) - hasCameraRecording = bool( - cameraImage["parsed"]["events"][0]["hasRecording"] + camera_image = await self.api.get_camera_image(device) + has_camera_recording = bool( + camera_image["parsed"]["events"][0]["hasRecording"] ) - if hasCameraRecording: - cameraRecording = await self.api.getCameraRecording( - device, cameraImage["parsed"]["events"][0]["eventId"] + if has_camera_recording: + camera_recording = await self.api.get_camera_recording( + device, camera_image["parsed"]["events"][0]["eventId"] ) - if operator.contains(str(cameraImage["original"]), "20") is False: + if operator.contains(str(camera_image["original"]), "20") is False: raise HTTPException - elif cameraImage["parsed"] is None: + elif camera_image["parsed"] is None: raise HiveApiError else: raise NoApiToken - hasCameraImage = bool(cameraImage["parsed"]["events"][0]) + has_camera_image = bool(camera_image["parsed"]["events"][0]) self.data.camera[device["id"]] = {} self.data.camera[device["id"]]["cameraImage"] = None self.data.camera[device["id"]]["cameraRecording"] = None - if cameraImage is not None and hasCameraImage: + if camera_image is not None and has_camera_image: self.data.camera[device["id"]] = {} - self.data.camera[device["id"]]["cameraImage"] = cameraImage["parsed"][ + self.data.camera[device["id"]]["cameraImage"] = camera_image["parsed"][ "events" ][0] - if cameraRecording is not None and hasCameraRecording: - self.data.camera[device["id"]]["cameraRecording"] = cameraRecording[ + if camera_recording is not None and has_camera_recording: + self.data.camera[device["id"]]["cameraRecording"] = camera_recording[ "parsed" ] @@ -423,45 +423,45 @@ async def get_devices(self, n_id: str): api_resp_d = self.open_file("data.json") elif self.tokens is not None: await self.hive_refresh_tokens() - api_resp_d = await self.api.getAll() + api_resp_d = await self.api.get_all() if operator.contains(str(api_resp_d["original"]), "20") is False: raise HTTPException elif api_resp_d["parsed"] is None: raise HiveApiError api_resp_p = api_resp_d["parsed"] - tmpProducts = {} - tmpDevices = {} - tmpActions = {} - - for hiveType in api_resp_p: - if hiveType == "user": - self.data.user = api_resp_p[hiveType] - self.config.userID = api_resp_p[hiveType]["id"] - if hiveType == "products": - for aProduct in api_resp_p[hiveType]: - tmpProducts.update({aProduct["id"]: aProduct}) - if hiveType == "devices": - for aDevice in api_resp_p[hiveType]: - tmpDevices.update({aDevice["id"]: aDevice}) - if aDevice["type"] == "siren": + temp_products = {} + temp_devices = {} + temp_actions = {} + + for hive_type in api_resp_p: + if hive_type == "user": + self.data.user = api_resp_p[hive_type] + self.config.userID = api_resp_p[hive_type]["id"] + if hive_type == "products": + for a_product in api_resp_p[hive_type]: + temp_products.update({a_product["id"]: a_product}) + if hive_type == "devices": + for a_device in api_resp_p[hive_type]: + temp_devices.update({a_device["id"]: a_device}) + if a_device["type"] == "siren": self.config.alarm = True # if aDevice["type"] == "hivecamera": # await self.getCamera(aDevice) - if hiveType == "actions": - for aAction in api_resp_p[hiveType]: - tmpActions.update({aAction["id"]: aAction}) - if hiveType == "homes": - self.config.homeID = api_resp_p[hiveType]["homes"][0]["id"] - - if len(tmpProducts) > 0: - self.data.products = copy.deepcopy(tmpProducts) - if len(tmpDevices) > 0: - self.data.devices = copy.deepcopy(tmpDevices) - self.data.actions = copy.deepcopy(tmpActions) + if hive_type == "actions": + for a_action in api_resp_p[hive_type]: + temp_actions.update({a_action["id"]: a_action}) + if hive_type == "homes": + self.config.homeID = api_resp_p[hive_type]["homes"][0]["id"] + + if len(temp_products) > 0: + self.data.products = copy.deepcopy(temp_products) + if len(temp_devices) > 0: + self.data.devices = copy.deepcopy(temp_devices) + self.data.actions = copy.deepcopy(temp_actions) if self.config.alarm: await self.get_alarm() - self.config.lastUpdate = datetime.now() + self.config.last_update = datetime.now() get_nodes_successful = True except (OSError, RuntimeError, HiveApiError, ConnectionError, HTTPException): get_nodes_successful = False @@ -483,7 +483,7 @@ async def start_session(self, config: dict = {}): """ await self.use_file(config.get("username", self.config.username)) await self.update_interval( - config.get("options", {}).get("scan_interval", self.config.scanInterval) + config.get("options", {}).get("scan_interval", self.config.scan_interval) ) if config != {}: @@ -524,31 +524,31 @@ async def create_devices(self): self.device_list["water_heater"] = [] hive_type = HIVE_TYPES["Heating"] + HIVE_TYPES["Switch"] + HIVE_TYPES["Light"] - for aProduct in self.data.products: - p = self.data.products[aProduct] + for a_product in self.data.products: + p = self.data.products[a_product] if "error" in p: continue # Only consider single items or heating groups if ( p.get("isGroup", False) - and self.data.products[aProduct]["type"] not in HIVE_TYPES["Heating"] + and self.data.products[a_product]["type"] not in HIVE_TYPES["Heating"] ): continue - product_list = PRODUCTS.get(self.data.products[aProduct]["type"], []) + product_list = PRODUCTS.get(self.data.products[a_product]["type"], []) for code in product_list: eval("self." + code) - if self.data.products[aProduct]["type"] in hive_type: + if self.data.products[a_product]["type"] in hive_type: self.config.mode.append(p["id"]) hive_type = HIVE_TYPES["Thermo"] + HIVE_TYPES["Sensor"] - for aDevice in self.data["devices"]: - d = self.data.devices[aDevice] - device_list = DEVICES.get(self.data.devices[aDevice]["type"], []) + for a_device in self.data["devices"]: + d = self.data.devices[a_device] + device_list = DEVICES.get(self.data.devices[a_device]["type"], []) for code in device_list: eval("self." + code) - if self.data["devices"][aDevice]["type"] in hive_type: + if self.data["devices"][a_device]["type"] in hive_type: self.config.battery.append(d["id"]) if "action" in HIVE_TYPES["Switch"]: @@ -572,8 +572,8 @@ def epoch_time(date_time: any, pattern: str, action: str): """ if action == "to_epoch": pattern = "%d.%m.%Y %H:%M:%S" - epochtime = int(time.mktime(time.strptime(str(date_time), pattern))) - return epochtime + epoch_time = int(time.mktime(time.strptime(str(date_time), pattern))) + return epoch_time elif action == "from_epoch": date = datetime.fromtimestamp(int(date_time)).strftime(pattern) return date \ No newline at end of file diff --git a/tests/apyhiveapi/test_plug.py b/tests/apyhiveapi/test_plug.py index 8238124..2199795 100644 --- a/tests/apyhiveapi/test_plug.py +++ b/tests/apyhiveapi/test_plug.py @@ -78,7 +78,7 @@ async def test_switch_turn_on_successfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: result = await hive_session.switch.turnOn(switch) @@ -96,7 +96,7 @@ async def test_switch_turn_on_unsuccessfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: result = await hive_session.switch.turnOn(switch) @@ -114,7 +114,7 @@ async def test_switch_turn_off_successfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: result = await hive_session.switch.turnOff(switch) @@ -132,7 +132,7 @@ async def test_switch_turn_off_unsuccessfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: result = await hive_session.switch.turnOff(switch) @@ -150,7 +150,7 @@ async def test_switch_heat_on_demand_turn_on_successfully(): switch = hive_session.session.device_list["switch"][0] with patch( - "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: result = await hive_session.switch.turnOn(switch) @@ -168,7 +168,7 @@ async def test_switch_heat_on_demand_turn_on_unsuccessfully(): switch = hive_session.session.device_list["switch"][0] with patch( - "apyhiveapi.api.hive_async_api.HiveApiAsync.setState", + "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: result = await hive_session.switch.turnOff(switch) diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py index 50b81a8..118e755 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_plug.py @@ -70,7 +70,7 @@ def test_switch_turn_on_successfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "pyhiveapi.api.hive_api.HiveApi.setState", + "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: result = hive_session.switch.turnOn(switch) @@ -87,7 +87,7 @@ def test_switch_turn_on_unsuccessfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "pyhiveapi.api.hive_api.HiveApi.setState", + "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: result = hive_session.switch.turnOn(switch) @@ -104,7 +104,7 @@ def test_switch_turn_off_successfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "pyhiveapi.api.hive_api.HiveApi.setState", + "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: result = hive_session.switch.turnOff(switch) @@ -121,7 +121,7 @@ def test_switch_turn_off_unsuccessfully(): switch = hive_session.session.device_list["switch"][1] with patch( - "pyhiveapi.api.hive_api.HiveApi.setState", + "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: result = hive_session.switch.turnOff(switch) @@ -138,7 +138,7 @@ def test_switch_heat_on_demand_turn_on_successfully(): switch = hive_session.session.device_list["switch"][0] with patch( - "pyhiveapi.api.hive_api.HiveApi.setState", + "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: result = hive_session.switch.turnOn(switch) @@ -155,7 +155,7 @@ def test_switch_heat_on_demand_turn_on_unsuccessfully(): switch = hive_session.session.device_list["switch"][0] with patch( - "pyhiveapi.api.hive_api.HiveApi.setState", + "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: result = hive_session.switch.turnOff(switch) From 3108601e07379be22423724a002352b21d9ae8d9 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 9 Dec 2024 23:54:46 +0000 Subject: [PATCH 18/26] 3 round of converting to snake case --- pyhiveapi/apyhiveapi/helper/const.py | 96 +++++----- src/apyhiveapi/action.py | 36 ++-- src/apyhiveapi/alarm.py | 34 ++-- src/apyhiveapi/api/hive_api.py | 24 ++- src/apyhiveapi/api/hive_async_api.py | 44 ++--- src/apyhiveapi/camera.py | 48 ++--- src/apyhiveapi/heating.py | 132 +++++++------- src/apyhiveapi/helper/const.py | 142 +++++++-------- src/apyhiveapi/helper/debugger.py | 10 +- src/apyhiveapi/helper/hive_helper.py | 214 +++++++++++------------ src/apyhiveapi/helper/hivedataclasses.py | 14 +- src/apyhiveapi/helper/logger.py | 10 +- src/apyhiveapi/hive.py | 2 +- src/apyhiveapi/hotwater.py | 64 +++---- src/apyhiveapi/hub.py | 16 +- src/apyhiveapi/light.py | 148 ++++++++-------- src/apyhiveapi/plug.py | 52 +++--- src/apyhiveapi/sensor.py | 56 +++--- src/apyhiveapi/session.py | 64 +++---- tests/apyhiveapi/test_hub.py | 12 +- tests/apyhiveapi/test_plug.py | 34 ++-- tests/apyhiveapi/test_session.py | 2 +- tests/common.py | 4 +- tests/pyhiveapi/test_hub.py | 12 +- tests/pyhiveapi/test_plug.py | 34 ++-- 25 files changed, 647 insertions(+), 657 deletions(-) diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py index 29c65e1..9e78b9c 100644 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ b/pyhiveapi/apyhiveapi/helper/const.py @@ -59,112 +59,112 @@ "SMOKE_CO": "self.session.hub.get_smoke_status(device)", "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", - "Camera_Temp": "self.session.camera.getCameraTemperature(device)", + "Camera_Temp": "self.session.camera.get_camera_temperature(device)", "Current_Temperature": "self.session.heating.get_current_temperature(device)", "Heating_Current_Temperature": "self.session.heating.get_current_temperature(device)", "Heating_Target_Temperature": "self.session.heating.get_target_temperature(device)", - "Heating_State": "self.session.heating.getState(device)", + "Heating_State": "self.session.heating.get_state(device)", "Heating_Mode": "self.session.heating.get_mode(device)", "Heating_Boost": "self.session.heating.get_boost_status(device)", - "Hotwater_State": "self.session.hotwater.getState(device)", + "Hotwater_State": "self.session.hotwater.get_state(device)", "Hotwater_Mode": "self.session.hotwater.get_mode(device)", - "Hotwater_Boost": "self.session.hotwater.getBoost(device)", - "Battery": 'self.session.attr.getBattery(device["device_id"])', - "Mode": 'self.session.attr.get_mode(device["hiveID"])', + "Hotwater_Boost": "self.session.hotwater.get_boost(device)", + "Battery": 'self.session.attr.get_battery(device["device_id"])', + "Mode": 'self.session.attr.get_mode(device["hive_id"])', "Availability": "self.online(device)", "Connectivity": "self.online(device)", - "Power": "self.session.switch.getPowerUsage(device)", + "Power": "self.session.switch.get_power_usage(device)", } PRODUCTS = { "sense": [ - 'addList("binary_sensor", p, haName="Glass Detection", hiveType="GLASS_BREAK")', - 'addList("binary_sensor", p, haName="Smoke Detection", hiveType="SMOKE_CO")', - 'addList("binary_sensor", p, haName="Dog Bark Detection", hiveType="DOG_BARK")', + 'addList("binary_sensor", p, ha_name="Glass Detection", hive_type="GLASS_BREAK")', + 'addList("binary_sensor", p, ha_name="Smoke Detection", hive_type="SMOKE_CO")', + 'addList("binary_sensor", p, ha_name="Dog Bark Detection", hive_type="DOG_BARK")', ], "heating": [ 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("switch", p, haName=" Heat on Demand", hiveType="Heating_Heat_On_Demand", category="config")', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', - 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', + 'addList("switch", p, ha_name=" Heat on Demand", hive_type="Heating_Heat_On_Demand", category="config")', + 'addList("sensor", p, ha_name=" Current Temperature", hive_type="Heating_Current_Temperature", category="diagnostic")', + 'addList("sensor", p, ha_name=" Target Temperature", hive_type="Heating_Target_Temperature", category="diagnostic")', + 'addList("sensor", p, ha_name=" State", hive_type="Heating_State", category="diagnostic")', + 'addList("sensor", p, ha_name=" Mode", hive_type="Heating_Mode", category="diagnostic")', + 'addList("sensor", p, ha_name=" Boost", hive_type="Heating_Boost", category="diagnostic")', ], "trvcontrol": [ 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', - 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', + 'addList("sensor", p, ha_name=" Current Temperature", hive_type="Heating_Current_Temperature", category="diagnostic")', + 'addList("sensor", p, ha_name=" Target Temperature", hive_type="Heating_Target_Temperature", category="diagnostic")', + 'addList("sensor", p, ha_name=" State", hive_type="Heating_State", category="diagnostic")', + 'addList("sensor", p, ha_name=" Mode", hive_type="Heating_Mode", category="diagnostic")', + 'addList("sensor", p, ha_name=" Boost", hive_type="Heating_Boost", category="diagnostic")', ], "hotwater": [ 'addList("water_heater", p,)', - 'addList("sensor", p, haName="Hot Water State", hiveType="Hotwater_State", category="diagnostic")', - 'addList("sensor", p, haName="Hot Water Mode", hiveType="Hotwater_Mode", category="diagnostic")', - 'addList("sensor", p, haName="Hot Water Boost", hiveType="Hotwater_Boost", category="diagnostic")', + 'addList("sensor", p, ha_name="Hot Water State", hive_type="Hotwater_State", category="diagnostic")', + 'addList("sensor", p, ha_name="Hot Water Mode", hive_type="Hotwater_Mode", category="diagnostic")', + 'addList("sensor", p, ha_name="Hot Water Boost", hive_type="Hotwater_Boost", category="diagnostic")', ], "activeplug": [ 'addList("switch", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - 'addList("sensor", p, haName=" Power", hiveType="Power", category="diagnostic")', + 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', + 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', + 'addList("sensor", p, ha_name=" Power", hive_type="Power", category="diagnostic")', ], "warmwhitelight": [ 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', + 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], "tuneablelight": [ 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', + 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], "colourtuneablelight": [ 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', + 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], # "hivecamera": [ # 'addList("camera", p)', - # 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - # 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - # 'addList("sensor", p, haName=" Temperature", hiveType="Camera_Temp", category="diagnostic")', + # 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', + # 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', + # 'addList("sensor", p, ha_name=" Temperature", hive_type="Camera_Temp", category="diagnostic")', # ], "motionsensor": [ 'addList("binary_sensor", p)', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Current_Temperature", category="diagnostic")', + 'addList("sensor", p, ha_name=" Current Temperature", hive_type="Current_Temperature", category="diagnostic")', ], "contactsensor": ['addList("binary_sensor", p)'], } DEVICES = { "contactsensor": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', + 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], "hub": [ - 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity", category="diagnostic")', + 'addList("binary_sensor", d, ha_name="Hive Hub Status", hive_type="Connectivity", category="diagnostic")', ], "motionsensor": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', + 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], "sense": [ - 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity")', + 'addList("binary_sensor", d, ha_name="Hive Hub Status", hive_type="Connectivity")', ], "siren": ['addList("alarm_control_panel", d)'], "thermostatui": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', + 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], "trv": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', + 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', ], } ACTIONS = ( - 'addList("switch", a, hiveName=a["name"], haName=a["name"], hiveType="action")' + 'addList("switch", a, hive_name=a["name"], ha_name=a["name"], hive_type="action")' ) diff --git a/src/apyhiveapi/action.py b/src/apyhiveapi/action.py index 04834a9..189b546 100644 --- a/src/apyhiveapi/action.py +++ b/src/apyhiveapi/action.py @@ -9,7 +9,7 @@ class HiveAction: object: Return hive action object. """ - actionType = "Actions" + action_type = "Actions" def __init__(self, session: object = None): """Initialise Action. @@ -30,23 +30,23 @@ async def get_action(self, device: dict): """ dev_data = {} - if device["hiveID"] in self.data["action"]: + if device["hive_id"] in self.data["action"]: dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "status": {"state": await self.get_state(device)}, "power_usage": None, - "deviceData": {}, + "device_data": {}, "custom": device.get("custom", None), } - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: - exists = self.session.data.actions.get("hiveID", False) + exists = self.session.data.actions.get("hive_id", False) if exists is False: return "REMOVE" return device @@ -63,7 +63,7 @@ async def get_state(self, device: dict): final = None try: - data = self.session.data.actions[device["hiveID"]] + data = self.session.data.actions[device["hive_id"]] final = data["enabled"] except KeyError as e: await self.session.log.error(e) @@ -83,12 +83,12 @@ async def set_status_on(self, device: dict): final = False - if device["hiveID"] in self.session.data.actions: + if device["hive_id"] in self.session.data.actions: await self.session.hive_refresh_tokens() - data = self.session.data.actions[device["hiveID"]] + data = self.session.data.actions[device["hive_id"]] data.update({"enabled": True}) send = json.dumps(data) - resp = await self.session.api.setAction(device["hiveID"], send) + resp = await self.session.api.set_action(device["hive_id"], send) if resp["original"] == 200: final = True await self.session.get_devices() @@ -108,12 +108,12 @@ async def set_status_off(self, device: dict): final = False - if device["hiveID"] in self.session.data.actions: + if device["hive_id"] in self.session.data.actions: await self.session.hive_refresh_tokens() - data = self.session.data.actions[device["hiveID"]] + data = self.session.data.actions[device["hive_id"]] data.update({"enabled": False}) send = json.dumps(data) - resp = await self.session.api.setAction(device["hiveID"], send) + resp = await self.session.api.set_action(device["hive_id"], send) if resp["original"] == 200: final = True await self.session.get_devices() diff --git a/src/apyhiveapi/alarm.py b/src/apyhiveapi/alarm.py index d125c49..f4912d9 100644 --- a/src/apyhiveapi/alarm.py +++ b/src/apyhiveapi/alarm.py @@ -9,7 +9,7 @@ class HiveHomeShield: object: Hive homeshield """ - alarmType = "Alarm" + alarm_type = "Alarm" async def get_mode(self): """Get current mode of the alarm. @@ -36,7 +36,7 @@ async def get_state(self, device: dict): state = None try: - data = self.session.data.devices[device["hiveID"]] + data = self.session.data.devices[device["hive_id"]] state = data["state"]["alarmActive"] except KeyError as e: await self.session.log.error(e) @@ -55,8 +55,8 @@ async def set_mode(self, device: dict, mode: str): final = False if ( - device["hiveID"] in self.session.data.devices - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.devices + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() resp = await self.session.api.set_alarm(mode=mode) @@ -91,38 +91,38 @@ async def get_alarm(self, device: dict): Returns: dict: Updated device. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} - if device["deviceData"]["online"]: + if device["device_data"]["online"]: self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device["device_id"], "device_name": device["device_name"], "status": { "state": await self.get_state(device), "mode": await self.get_mode(), }, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "custom": device.get("custom", None), "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device diff --git a/src/apyhiveapi/api/hive_api.py b/src/apyhiveapi/api/hive_api.py index ab19700..7d86237 100644 --- a/src/apyhiveapi/api/hive_api.py +++ b/src/apyhiveapi/api/hive_api.py @@ -25,10 +25,8 @@ def __init__(self, hive_session=None, websession=None, token=None): "holiday_mode": "/holiday-mode", "all": "/nodes/all?products=true&devices=true&actions=true", "alarm": "/security-lite?homeId=", - "cameraImages": f"https://event-history-service.{self.camera_base_u -rl}/v1/events/cameras?latest=true&cameraId={{0}}", - "cameraRecordings": f"https://event-history-service.{self.camera_base_u -rl}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", + "cameraImages": f"https://event-history-service.{self.camera_base_url}/v1/events/cameras?latest=true&cameraId={{0}}", + "cameraRecordings": f"https://event-history-service.{self.camera_base_url}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", "devices": "/devices", "products": "/products", "actions": "/actions", @@ -123,11 +121,11 @@ def get_login_info(self): + "}" ) - loginData = {} - loginData.update({"UPID": json_data["HiveSSOPoolId"]}) - loginData.update({"CLIID": json_data["HiveSSOPublicCognitoClientId"]}) - loginData.update({"REGION": json_data["HiveSSOPoolId"]}) - return loginData + login_data = {} + login_data.update({"UPID": json_data["HiveSSOPoolId"]}) + login_data.update({"CLIID": json_data["HiveSSOPublicCognitoClientId"]}) + login_data.update({"REGION": json_data["HiveSSOPoolId"]}) + return login_data except (OSError, RuntimeError, ZeroDivisionError): self.error() @@ -158,7 +156,7 @@ def get_alarm(self, home_id=None): return self.json_return - def get_camera_image(self, device=None, accessToken=None): + def get_camera_image(self, device=None, access_token=None): """Build and query camera endpoint.""" json_return = {} url = self.urls["cameraImages"].format(device["props"]["hardwareIdentifier"]) @@ -171,11 +169,11 @@ def get_camera_image(self, device=None, accessToken=None): return json_return - def get_camera_recording(self, device=None, eventId=None): + def get_camera_recording(self, device=None, event_id=None): """Build and query camera endpoint.""" json_return = {} - url = self.urls["cameraRecordings"].format( - device["props"]["hardwareIdentifier"], eventId + url = self.urls["camera_recordings"].format( + device["props"]["hardwareIdentifier"], event_id ) try: info = self.request("GET", url, camera=True) diff --git a/src/apyhiveapi/api/hive_async_api.py b/src/apyhiveapi/api/hive_async_api.py index 7506182..7b9f016 100644 --- a/src/apyhiveapi/api/hive_async_api.py +++ b/src/apyhiveapi/api/hive_async_api.py @@ -19,21 +19,21 @@ class HiveApiAsync: def __init__(self, hive_session=None, websession: Optional[ClientSession] = None): """Hive API initialisation.""" - self.baseUrl = "https://beekeeper.hivehome.com/1.0" - self.cameraBaseUrl = "prod.hcam.bgchtest.info" + self.base_url = "https://beekeeper.hivehome.com/1.0" + self.camera_base_url = "prod.hcam.bgchtest.info" self.urls = { "properties": "https://sso.hivehome.com/", - "login": f"{self.baseUrl}/cognito/login", - "refresh": f"{self.baseUrl}/cognito/refresh-token", - "holiday_mode": f"{self.baseUrl}/holiday-mode", - "all": f"{self.baseUrl}/nodes/all?products=true&devices=true&actions=true", - "alarm": f"{self.baseUrl}/security-lite?homeId=", - "cameraImages": f"https://event-history-service.{self.cameraBaseUrl}/v1/events/cameras?latest=true&cameraId={{0}}", - "cameraRecordings": f"https://event-history-service.{self.cameraBaseUrl}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", - "devices": f"{self.baseUrl}/devices", - "products": f"{self.baseUrl}/products", - "actions": f"{self.baseUrl}/actions", - "nodes": f"{self.baseUrl}/nodes/{{0}}/{{1}}", + "login": f"{self.base_url}/cognito/login", + "refresh": f"{self.base_url}/cognito/refresh-token", + "holiday_mode": f"{self.base_url}/holiday-mode", + "all": f"{self.base_url}/nodes/all?products=true&devices=true&actions=true", + "alarm": f"{self.base_url}/security-lite?homeId=", + "camera_images": f"https://event-history-service.{self.camera_base_url}/v1/events/cameras?latest=true&cameraId={{0}}", + "camera_recordings": f"https://event-history-service.{self.camera_base_url}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", + "devices": f"{self.base_url}/devices", + "products": f"{self.base_url}/products", + "actions": f"{self.base_url}/actions", + "nodes": f"{self.base_url}/nodes/{{0}}/{{1}}", "long_lived": "https://api.prod.bgchprod.info/omnia/accessTokens", "weather": "https://weather.prod.bgchprod.info/weather", } @@ -106,11 +106,11 @@ def get_login_info(self): + "}" ) - loginData = {} - loginData.update({"UPID": json_data["HiveSSOPoolId"]}) - loginData.update({"CLIID": json_data["HiveSSOPublicCognitoClientId"]}) - loginData.update({"REGION": json_data["HiveSSOPoolId"]}) - return loginData + login_data = {} + login_data.update({"UPID": json_data["HiveSSOPoolId"]}) + login_data.update({"CLIID": json_data["HiveSSOPublicCognitoClientId"]}) + login_data.update({"REGION": json_data["HiveSSOPoolId"]}) + return login_data async def refresh_tokens(self): """Refresh tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" @@ -131,8 +131,8 @@ async def refresh_tokens(self): info = self.json_return["parsed"] if "token" in info: await self.session.update_tokens(info) - self.baseUrl = info["platform"]["endpoint"] - self.cameraBaseUrl = info["platform"]["cameraPlatform"] + self.base_url = info["platform"]["endpoint"] + self.camera_base_url = info["platform"]["cameraPlatform"] return True except (ConnectionError, OSError, RuntimeError, ZeroDivisionError): await self.error() @@ -168,7 +168,7 @@ async def get_alarm(self): async def get_camera_image(self, device): """Build and query alarm endpoint.""" json_return = {} - url = self.urls["cameraImages"].format(device["props"]["hardwareIdentifier"]) + url = self.urls["camera_images"].format(device["props"]["hardwareIdentifier"]) try: resp = await self.request("get", url, True) json_return.update({"original": resp.status}) @@ -181,7 +181,7 @@ async def get_camera_image(self, device): async def get_camera_recording(self, device, eventId): """Build and query alarm endpoint.""" json_return = {} - url = self.urls["cameraRecordings"].format( + url = self.urls["camera_recordings"].format( device["props"]["hardwareIdentifier"], eventId ) try: diff --git a/src/apyhiveapi/camera.py b/src/apyhiveapi/camera.py index be6f20b..5fd1938 100644 --- a/src/apyhiveapi/camera.py +++ b/src/apyhiveapi/camera.py @@ -9,7 +9,7 @@ class HiveCamera: object: Hive camera """ - cameraType = "Camera" + camera_type = "Camera" async def get_camera_temperature(self, device: dict): """Get the camera state. @@ -20,7 +20,7 @@ async def get_camera_temperature(self, device: dict): state = None try: - data = self.session.data.devices[device["hiveID"]] + data = self.session.data.devices[device["hive_id"]] state = data["props"]["temperature"] except KeyError as e: await self.session.log.error(e) @@ -36,7 +36,7 @@ async def get_camera_state(self, device: dict): state = None try: - data = self.session.data.devices[device["hiveID"]] + data = self.session.data.devices[device["hive_id"]] state = True if data["state"]["mode"] == "ARMED" else False except KeyError as e: await self.session.log.error(e) @@ -52,7 +52,7 @@ async def get_camera_image_url(self, device: dict): state = None try: - state = self.session.data.camera[device["hiveID"]]["cameraImage"][ + state = self.session.data.camera[device["hive_id"]]["camera_image"][ "thumbnailUrls" ][0] except KeyError as e: @@ -69,7 +69,7 @@ async def get_camera_recording_url(self, device: dict): state = None try: - state = self.session.data.camera[device["hiveID"]]["cameraRecording"] + state = self.session.data.camera[device["hive_id"]]["camera_recording"] except KeyError as e: await self.session.log.error(e) @@ -87,8 +87,8 @@ async def set_camera_on(self, device: dict, mode: str): final = False if ( - device["hiveID"] in self.session.data.devices - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.devices + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() resp = await self.session.api.set_state(mode=mode) @@ -110,8 +110,8 @@ async def set_camera_off(self, device: dict, mode: str): final = False if ( - device["hiveID"] in self.session.data.devices - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.devices + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() resp = await self.session.api.set_state(mode=mode) @@ -146,40 +146,40 @@ async def get_camera(self, device: dict): Returns: dict: Updated device. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} - if device["deviceData"]["online"]: + if device["device_data"]["online"]: self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device["device_id"], "device_name": device["device_name"], "status": { "temperature": await self.get_camera_temperature(device), "state": await self.get_camera_state(device), - "imageURL": await self.get_camera_image_url(device), - "recordingURL": await self.get_camera_recording_url(device), + "image_url": await self.get_camera_image_url(device), + "recording_url": await self.get_camera_recording_url(device), }, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "custom": device.get("custom", None), "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device diff --git a/src/apyhiveapi/heating.py b/src/apyhiveapi/heating.py index 5832028..8b91dd0 100644 --- a/src/apyhiveapi/heating.py +++ b/src/apyhiveapi/heating.py @@ -21,8 +21,8 @@ async def get_min_temperature(self, device: dict): Returns: int: Minimum temperature """ - if device["hiveType"] == "nathermostat": - return self.session.data.products[device["hiveID"]]["props"]["minHeat"] + if device["hive_type"] == "nathermostat": + return self.session.data.products[device["hive_id"]]["props"]["minHeat"] return 5 async def get_max_temperature(self, device: dict): @@ -34,8 +34,8 @@ async def get_max_temperature(self, device: dict): Returns: int: Maximum temperature """ - if device["hiveType"] == "nathermostat": - return self.session.data.products[device["hiveID"]]["props"]["maxHeat"] + if device["hive_type"] == "nathermostat": + return self.session.data.products[device["hive_id"]]["props"]["maxHeat"] return 32 async def get_current_temperature(self, device: dict): @@ -54,31 +54,31 @@ async def get_current_temperature(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["temperature"] - if device["hiveID"] in self.session.data.min_max: - if self.session.data.min_max[device["hiveID"]]["TodayDate"] == str( + if device["hive_id"] in self.session.data.min_max: + if self.session.data.min_max[device["hive_id"]]["TodayDate"] == str( datetime.date(datetime.now()) ): - if state < self.session.data.min_max[device["hiveID"]]["TodayMin"]: - self.session.data.min_max[device["hiveID"]]["TodayMin"] = state + if state < self.session.data.min_max[device["hive_id"]]["TodayMin"]: + self.session.data.min_max[device["hive_id"]]["TodayMin"] = state - if state > self.session.data.min_max[device["hiveID"]]["TodayMax"]: - self.session.data.min_max[device["hiveID"]]["TodayMax"] = state + if state > self.session.data.min_max[device["hive_id"]]["TodayMax"]: + self.session.data.min_max[device["hive_id"]]["TodayMax"] = state else: data = { "TodayMin": state, "TodayMax": state, "TodayDate": str(datetime.date(datetime.now())), } - self.session.data.min_max[device["hiveID"]].update(data) + self.session.data.min_max[device["hive_id"]].update(data) - if state < self.session.data.min_max[device["hiveID"]]["RestartMin"]: - self.session.data.min_max[device["hiveID"]]["RestartMin"] = state + if state < self.session.data.min_max[device["hive_id"]]["RestartMin"]: + self.session.data.min_max[device["hive_id"]]["RestartMin"] = state - if state > self.session.data.min_max[device["hiveID"]]["RestartMax"]: - self.session.data.min_max[device["hiveID"]]["RestartMax"] = state + if state > self.session.data.min_max[device["hive_id"]]["RestartMax"]: + self.session.data.min_max[device["hive_id"]]["RestartMax"] = state else: data = { "TodayMin": state, @@ -87,7 +87,7 @@ async def get_current_temperature(self, device: dict): "RestartMin": state, "RestartMax": state, } - self.session.data.min_max[device["hiveID"]] = data + self.session.data.min_max[device["hive_id"]] = data f_state = round(float(state), 1) final = f_state @@ -108,7 +108,7 @@ async def get_target_temperature(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = float(data["state"].get("target", None)) state = float(data["state"].get("heat", state)) except (KeyError, TypeError) as e: @@ -129,7 +129,7 @@ async def get_mode(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["mode"] if state == "BOOST": state = data["props"]["previous"]["mode"] @@ -139,7 +139,7 @@ async def get_mode(self, device: dict): return final - async def getState(self, device: dict): + async def get_state(self, device: dict): """Get heating current state. Args: @@ -176,7 +176,7 @@ async def get_current_operation(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["working"] except KeyError as e: await self.session.log.error(e) @@ -195,7 +195,7 @@ async def get_boost_status(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = HIVETOHA["Boost"].get(data["state"].get("boost", False), "ON") except KeyError as e: await self.session.log.error(e) @@ -215,7 +215,7 @@ async def get_boost_time(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["boost"] except KeyError as e: await self.session.log.error(e) @@ -235,7 +235,7 @@ async def get_heat_on_demand(self, device): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["autoBoost"]["active"] except KeyError as e: await self.session.log.error(e) @@ -265,17 +265,17 @@ async def set_target_temperature(self, device: dict, new_temp: str): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( - data["type"], device["hiveID"], target=new_temp + data["type"], device["hive_id"], target=new_temp ) if resp["original"] == 200: - await self.session.get_devices(device["hiveID"]) + await self.session.get_devices(device["hive_id"]) final = True return final @@ -294,16 +294,16 @@ async def set_mode(self, device: dict, new_mode: str): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( - data["type"], device["hiveID"], mode=new_mode + data["type"], device["hive_id"], mode=new_mode ) if resp["original"] == 200: - await self.session.get_devices(device["hiveID"]) + await self.session.get_devices(device["hive_id"]) final = True return final @@ -325,20 +325,20 @@ async def set_boost_on(self, device: dict, mins: str, temp: float): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( data["type"], - device["hiveID"], + device["hive_id"], mode="BOOST", boost=mins, target=temp, ) if resp["original"] == 200: - await self.session.get_devices(device["hiveID"]) + await self.session.get_devices(device["hive_id"]) final = True return final @@ -356,28 +356,28 @@ async def set_boost_off(self, device: dict): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] - await self.session.get_devices(device["hiveID"]) + data = self.session.data.products[device["hive_id"]] + await self.session.get_devices(device["hive_id"]) if await self.get_boost_status(device) == "ON": prev_mode = data["props"]["previous"]["mode"] if prev_mode == "MANUAL" or prev_mode == "OFF": pre_temp = data["props"]["previous"].get("target", 7) resp = await self.session.api.set_state( data["type"], - device["hiveID"], + device["hive_id"], mode=prev_mode, target=pre_temp, ) else: resp = await self.session.api.set_state( - data["type"], device["hiveID"], mode=prev_mode + data["type"], device["hive_id"], mode=prev_mode ) if resp["original"] == 200: - await self.session.get_devices(device["hiveID"]) + await self.session.get_devices(device["hive_id"]) final = True return final @@ -395,17 +395,17 @@ async def set_heat_on_demand(self, device: dict, state: str): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] await self.session.hive_refresh_tokens() resp = await self.session.api.set_state( - data["type"], device["hiveID"], autoBoost=state + data["type"], device["hive_id"], autoBoost=state ) if resp["original"] == 200: - await self.session.get_devices(device["hiveID"]) + await self.session.get_devices(device["hive_id"]) final = True return final @@ -435,20 +435,20 @@ async def get_climate(self, device: dict): Returns: dict: Updated device. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) - if device["deviceData"]["online"]: + if device["device_data"]["online"]: dev_data = {} self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device["device_id"], "device_name": device["device_name"], "temperatureunit": device["temperatureunit"], @@ -461,18 +461,18 @@ async def get_climate(self, device: dict): "mode": await self.get_mode(device), "boost": await self.get_boost_status(device), }, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "custom": device.get("custom", None), "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device @@ -491,7 +491,7 @@ async def get_schedule_now_next_later(self, device: dict): try: if online and current_mode == "SCHEDULE": - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = self.session.helper.get_schedule_nnl(data["state"]["schedule"]) except KeyError as e: await self.session.log.error(e) @@ -511,7 +511,7 @@ async def min_max_temperature(self, device: dict): final = None try: - state = self.session.data.min_max[device["hiveID"]] + state = self.session.data.min_max[device["hive_id"]] final = state except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/helper/const.py b/src/apyhiveapi/helper/const.py index 03d56f6..c21015f 100644 --- a/src/apyhiveapi/helper/const.py +++ b/src/apyhiveapi/helper/const.py @@ -56,116 +56,116 @@ "Switch": ["activeplug"], } sensor_commands = { - "SMOKE_CO": "self.session.hub.get_smoke_status(device)", - "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", - "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", - "Camera_Temp": "self.session.camera.getCameraTemperature(device)", - "Current_Temperature": "self.session.heating.get_current_temperature(device)", - "Heating_Current_Temperature": "self.session.heating.get_current_temperature(device)", - "Heating_Target_Temperature": "self.session.heating.get_target_temperature(device)", - "Heating_State": "self.session.heating.getState(device)", - "Heating_Mode": "self.session.heating.get_mode(device)", - "Heating_Boost": "self.session.heating.get_boost_status(device)", - "Hotwater_State": "self.session.hotwater.getState(device)", - "Hotwater_Mode": "self.session.hotwater.get_mode(device)", - "Hotwater_Boost": "self.session.hotwater.getBoost(device)", - "Battery": 'self.session.attr.getBattery(device["device_id"])', - "Mode": 'self.session.attr.get_mode(device["hiveID"])', - "Availability": "self.online(device)", - "Connectivity": "self.online(device)", - "Power": "self.session.switch.getPowerUsage(device)", + "smoke_co": "self.session.hub.get_smoke_status(device)", + "dog_bark": "self.session.hub.get_dog_bark_status(device)", + "glass_break": "self.session.hub.get_glass_break_status(device)", + "camera_temp": "self.session.camera.get_camera_temperature(device)", + "current_temperature": "self.session.heating.get_current_temperature(device)", + "heating_current_temperature": "self.session.heating.get_current_temperature(device)", + "heating_target_temperature": "self.session.heating.get_target_temperature(device)", + "heating_state": "self.session.heating.get_state(device)", + "heating_mode": "self.session.heating.get_mode(device)", + "heating_boost": "self.session.heating.get_boost_status(device)", + "hotwater_state": "self.session.hotwater.get_state(device)", + "hotwater_mode": "self.session.hotwater.get_mode(device)", + "hotwater_boost": "self.session.hotwater.get_boost(device)", + "battery": 'self.session.attr.get_battery(device["device_id"])', + "mode": 'self.session.attr.get_mode(device["hive_id"])', + "availability": "self.online(device)", + "connectivity": "self.online(device)", + "power": "self.session.switch.get_power_usage(device)", } PRODUCTS = { "sense": [ - 'addList("binary_sensor", p, haName="Glass Detection", hiveType="GLASS_BREAK")', - 'addList("binary_sensor", p, haName="Smoke Detection", hiveType="SMOKE_CO")', - 'addList("binary_sensor", p, haName="Dog Bark Detection", hiveType="DOG_BARK")', + 'add_list("binary_sensor", p, ha_name="Glass Detection", hive_type="GLASS_BREAK")', + 'add_list("binary_sensor", p, ha_name="Smoke Detection", hive_type="SMOKE_CO")', + 'add_list("binary_sensor", p, ha_name="Dog Bark Detection", hive_type="DOG_BARK")', ], "heating": [ - 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("switch", p, haName=" Heat on Demand", hiveType="Heating_Heat_On_Demand", category="config")', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', - 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', + 'add_list("climate", p, temperature_unit=self.data["user"]["temperature_unit"])', + 'add_list("switch", p, ha_name=" Heat on Demand", hive_type="heating_heat_on_demand", category="config")', + 'add_list("sensor", p, ha_name=" Current Temperature", hive_type="heating_current_temperature", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Target Temperature", hive_type="heating_target_temperature", category="diagnostic")', + 'add_list("sensor", p, ha_name=" State", hive_type="heating_state", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Mode", hive_type="heating_mode", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Boost", hive_type="heating_boost", category="diagnostic")', ], "trvcontrol": [ - 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" Target Temperature", hiveType="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, haName=" State", hiveType="Heating_State", category="diagnostic")', - 'addList("sensor", p, haName=" Mode", hiveType="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Boost", hiveType="Heating_Boost", category="diagnostic")', + 'add_list("climate", p, temperature_unit=self.data["user"]["temperature_unit"])', + 'add_list("sensor", p, ha_name=" Current Temperature", hive_type="heating_current_temperature", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Target Temperature", hive_type="heating_target_temperature", category="diagnostic")', + 'add_list("sensor", p, ha_name=" State", hive_type="heating_state", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Mode", hive_type="heating_mode", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Boost", hive_type="heating_boost", category="diagnostic")', ], "hotwater": [ - 'addList("water_heater", p,)', - 'addList("sensor", p, haName="Hotwater State", hiveType="Hotwater_State", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Mode", hiveType="Hotwater_Mode", category="diagnostic")', - 'addList("sensor", p, haName="Hotwater Boost", hiveType="Hotwater_Boost", category="diagnostic")', + 'add_list("water_heater", p,)', + 'add_list("sensor", p, ha_name="Hotwater State", hive_type="hotwater_state", category="diagnostic")', + 'add_list("sensor", p, ha_name="Hotwater Mode", hive_type="hotwater_mode", category="diagnostic")', + 'add_list("sensor", p, ha_name="Hotwater Boost", hive_type="hotwater_boost", category="diagnostic")', ], "activeplug": [ - 'addList("switch", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - 'addList("sensor", p, haName=" Power", hiveType="Power", category="diagnostic")', - 'addList("sensor", p, haName=" Energy", hiveType="Energy", category="diagnostic")', + 'add_list("switch", p)', + 'add_list("sensor", p, ha_name=" Mode", hive_type="mode", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Availability", hive_type="availability", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Power", hive_type="power", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Energy", hive_type="energy", category="diagnostic")', ], "warmwhitelight": [ - 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("light", p)', + 'add_list("sensor", p, ha_name=" Mode", hive_type="mode", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], "tuneablelight": [ - 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("light", p)', + 'add_list("sensor", p, ha_name=" Mode", hive_type="mode", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], "colourtuneablelight": [ - 'addList("light", p)', - 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("light", p)', + 'add_list("sensor", p, ha_name=" Mode", hive_type="mode", category="diagnostic")', + 'add_list("sensor", p, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], # "hivecamera": [ - # 'addList("camera", p)', - # 'addList("sensor", p, haName=" Mode", hiveType="Mode", category="diagnostic")', - # 'addList("sensor", p, haName=" Availability", hiveType="Availability", category="diagnostic")', - # 'addList("sensor", p, haName=" Temperature", hiveType="Camera_Temp", category="diagnostic")', + # 'add_list("camera", p)', + # 'add_list("sensor", p, ha_name=" Mode", hive_type="mode", category="diagnostic")', + # 'add_list("sensor", p, ha_name=" Availability", hive_type="availability", category="diagnostic")', + # 'add_list("sensor", p, ha_name=" Temperature", hive_type="camera_temp", category="diagnostic")', # ], "motionsensor": [ - 'addList("binary_sensor", p)', - 'addList("sensor", p, haName=" Current Temperature", hiveType="Current_Temperature", category="diagnostic")', + 'add_list("binary_sensor", p)', + 'add_list("sensor", p, ha_name=" Current Temperature", hive_type="current_temperature", category="diagnostic")', ], - "contactsensor": ['addList("binary_sensor", p)'], + "contactsensor": ['add_list("binary_sensor", p)'], } DEVICES = { "contactsensor": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Battery Level", hive_type="battery", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], "hub": [ - 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity", category="diagnostic")', + 'add_list("binary_sensor", d, ha_name="Hive Hub Status", hive_type="connectivity", category="diagnostic")', ], "motionsensor": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Battery Level", hive_type="battery", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], "sense": [ - 'addList("binary_sensor", d, haName="Hive Hub Status", hiveType="Connectivity")', + 'add_list("binary_sensor", d, ha_name="Hive Hub Status", hive_type="connectivity")', ], - "siren": ['addList("alarm_control_panel", d)'], + "siren": ['add_list("alarm_control_panel", d)'], "thermostatui": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Battery Level", hive_type="battery", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], "trv": [ - 'addList("sensor", d, haName=" Battery Level", hiveType="Battery", category="diagnostic")', - 'addList("sensor", d, haName=" Availability", hiveType="Availability", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Battery Level", hive_type="battery", category="diagnostic")', + 'add_list("sensor", d, ha_name=" Availability", hive_type="availability", category="diagnostic")', ], } ACTIONS = ( - 'addList("switch", a, hiveName=a["name"], haName=a["name"], hiveType="action")' + 'add_list("switch", a, hive_name=a["name"], ha_name=a["name"], hive_type="action")' ) \ No newline at end of file diff --git a/src/apyhiveapi/helper/debugger.py b/src/apyhiveapi/helper/debugger.py index 5f3060d..81efd54 100644 --- a/src/apyhiveapi/helper/debugger.py +++ b/src/apyhiveapi/helper/debugger.py @@ -10,11 +10,11 @@ def __init__(self, name, enabled): """Initialise debugger.""" self.name = name self.enabled = enabled - self.logging = logging.getLogger(__name__) - self.debugOutFolder = "" - self.debugOutFile = "" - self.debugEnabled = False - self.debugList = [] + self.logging = logging.get_logger(__name__) + self.debug_out_folder = "" + self.debug_out_file = "" + self.debug_enabled = False + self.debug_list = [] def __enter__(self): """Set trace calls on entering debugger.""" diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index d008aec..2ec1975 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -52,8 +52,8 @@ def device_recovered(self, n_id: str): n_id (str): ID of the device. """ # name = HiveHelper.get_device_name(n_id) - if n_id in self.session.config.errorList: - self.session.config.errorList.pop(n_id) + if n_id in self.session.config.error_list: + self.session.config.error_list.pop(n_id) def get_device_from_id(self, n_id: str): """Get product/device data from ID. @@ -84,14 +84,14 @@ def get_device_data(self, product: dict): device = product type = product["type"] if type in ("heating", "hotwater"): - for aDevice in self.session.data.devices: - if self.session.data.devices[aDevice]["type"] in HIVE_TYPES["Thermo"]: + for a_device in self.session.data.devices: + if self.session.data.devices[a_device]["type"] in HIVE_TYPES["Thermo"]: try: if ( product["props"]["zone"] - == self.session.data.devices[aDevice]["props"]["zone"] + == self.session.data.devices[a_device]["props"]["zone"] ): - device = self.session.data.devices[aDevice] + device = self.session.data.devices[a_device] except KeyError: pass elif type == "trvcontrol": @@ -204,40 +204,40 @@ def get_heat_on_demand_device(self, device: dict): Returns: [dictionary]: [Gets the thermostat device linked to TRV.] """ - trv = self.session.data.products.get(device["HiveID"]) + trv = self.session.data.products.get(device["hive_id"]) thermostat = self.session.data.products.get(trv["state"]["zone"]) return thermostat async def call_sensor_function(self, device): """Helper to decide which function to call.""" - if device["hiveType"] == "SMOKE_CO": + if device["hive_type"] == "SMOKE_CO": return await self.session.hub.get_smoke_status(device) - if device["hiveType"] == "DOG_BARK": + if device["hive_type"] == "DOG_BARK": return await self.session.hub.get_dog_bark_status(device) - if device["hiveType"] == "GLASS_BREAK": + if device["hive_type"] == "GLASS_BREAK": return await self.session.hub.get_glass_break_status(device) - if device["hiveType"] == "Camera_Temp": - return await self.session.camera.getCameraTemperature(device) - if device["hiveType"] == "Heating_Current_Temperature": + if device["hive_type"] == "Camera_Temp": + return await self.session.camera.get_camera_temperature(device) + if device["hive_type"] == "Heating_Current_Temperature": return await self.session.heating.get_current_temperature(device) - if device["hiveType"] == "Heating_Target_Temperature": + if device["hive_type"] == "Heating_Target_Temperature": return await self.session.heating.get_target_temperature(device) - if device["hiveType"] == "Heating_State": - return await self.session.heating.getState(device) - if device["hiveType"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): + if device["hive_type"] == "Heating_State": + return await self.session.heating.get_state(device) + if device["hive_type"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): return await self.session.heating.get_mode(device) - if device["hiveType"] == "Heating_Boost": + if device["hive_type"] == "Heating_Boost": return await self.session.heating.get_boost_status(device) - if device["hiveType"] == "Hotwater_State": - return await self.session.hotwater.getState(device) - if device["hiveType"] == "Hotwater_Boost": - return await self.session.hotwater.getBoost(device) - if device["hiveType"] == "Battery": - return await self.session.attr.getBattery(device["device_id"]) - if device["hiveType"] in ("Availability", "Connectivity"): + if device["hive_type"] == "Hotwater_State": + return await self.session.hotwater.get_state(device) + if device["hive_type"] == "Hotwater_Boost": + return await self.session.hotwater.get_boost(device) + if device["hive_type"] == "Battery": + return await self.session.attr.get_battery(device["device_id"]) + if device["hive_type"] in ("Availability", "Connectivity"): return await self.online(device) - if device["hiveType"] == "Power": - return await self.session.switch.getPowerUsage(device) + if device["hive_type"] == "Power": + return await self.session.switch.get_power_usage(device) return None async def call_products_to_add(self, entity_type, product): @@ -246,17 +246,17 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "binary_sensor", product, - haName="Glass Detection", - hiveType="GLASS_BREAK", + ha_name="Glass Detection", + hive_type="GLASS_BREAK", ) self.session.add_list( - "binary_sensor", product, haName="Smoke Detection", hiveType="SMOKE_CO" + "binary_sensor", product, ha_name="Smoke Detection", hive_type="SMOKE_CO" ) self.session.add_list( "binary_sensor", product, - haName="Dog Bark Detection", - hiveType="DOG_BARK", + ha_name="Dog Bark Detection", + hive_type="DOG_BARK", ) if entity_type == "heating": self.session.add_list( @@ -267,43 +267,43 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "switch", product, - haName=" Heat on Demand", - hiveType="Heating_Heat_On_Demand", + ha_name=" Heat on Demand", + hive_type="Heating_Heat_On_Demand", category="config", ) self.session.add_list( "sensor", product, - haName=" Current Temperature", - hiveType="Heating_Current_Temperature", + ha_name=" Current Temperature", + hive_type="Heating_Current_Temperature", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Target Temperature", - hiveType="Heating_Target_Temperature", + ha_name=" Target Temperature", + hive_type="Heating_Target_Temperature", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" State", - hiveType="Heating_State", + ha_name=" State", + hive_type="Heating_State", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Heating_Mode", + ha_name=" Mode", + hive_type="Heating_Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Boost", - hiveType="Heating_Boost", + ha_name=" Boost", + hive_type="Heating_Boost", category="diagnostic", ) if entity_type == "trvcontrol": @@ -315,36 +315,36 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName=" Current Temperature", - hiveType="Heating_Current_Temperature", + ha_name=" Current Temperature", + hive_type="Heating_Current_Temperature", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Target Temperature", - hiveType="Heating_Target_Temperature", + ha_name=" Target Temperature", + hive_type="Heating_Target_Temperature", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" State", - hiveType="Heating_State", + ha_name=" State", + hive_type="Heating_State", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Heating_Mode", + ha_name=" Mode", + hive_type="Heating_Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Boost", - hiveType="Heating_Boost", + ha_name=" Boost", + hive_type="Heating_Boost", category="diagnostic", ) if entity_type == "hotwater": @@ -355,22 +355,22 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName="Hotwater State", - hiveType="Hotwater_State", + ha_name="Hotwater State", + hive_type="Hotwater_State", category="diagnostic", ) self.session.add_list( "sensor", product, - haName="Hotwater Mode", - hiveType="Hotwater_Mode", + ha_name="Hotwater Mode", + hive_type="Hotwater_Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName="Hotwater Boost", - hiveType="Hotwater_Boost", + ha_name="Hotwater Boost", + hive_type="Hotwater_Boost", category="diagnostic", ) if entity_type == "activeplug": @@ -378,22 +378,22 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Mode", + ha_name=" Mode", + hive_type="Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Power", - hiveType="Power", + ha_name=" Power", + hive_type="Power", category="diagnostic", ) if entity_type == "warmwhitelight": @@ -401,15 +401,15 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Mode", + ha_name=" Mode", + hive_type="Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) if entity_type == "tuneablelight": @@ -417,15 +417,15 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Mode", + ha_name=" Mode", + hive_type="Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) if entity_type == "colourtuneablelight": @@ -433,15 +433,15 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Mode", + ha_name=" Mode", + hive_type="Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) if entity_type == "hivecamera": @@ -449,22 +449,22 @@ async def call_products_to_add(self, entity_type, product): self.session.add_list( "sensor", product, - haName=" Mode", - hiveType="Mode", + ha_name=" Mode", + hive_type="Mode", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) self.session.add_list( "sensor", product, - haName=" Temperature", - hiveType="Camera_Temp", + ha_name=" Temperature", + hive_type="Camera_Temp", category="diagnostic", ) if entity_type == "motionsensor": @@ -479,46 +479,46 @@ async def call_devices_to_add(self, entity_type, device): self.session.add_list( "sensor", device, - haName=" Battery Level", - hiveType="Battery", + ha_name=" Battery Level", + hive_type="Battery", category="diagnostic", ) self.session.add_list( "sensor", device, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) if entity_type == "hub": self.session.add_list( "binary_sensor", device, - haName="Hive Hub Status", - hiveType="Connectivity", + ha_name="Hive Hub Status", + hive_type="Connectivity", category="diagnostic", ) if entity_type == "motionsensor": self.session.add_list( "sensor", device, - haName=" Battery Level", - hiveType="Battery", + ha_name=" Battery Level", + hive_type="Battery", category="diagnostic", ) self.session.add_list( "sensor", device, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) if entity_type == "sense": self.session.add_list( "binary_sensor", device, - haName="Hive Hub Status", - hiveType="Connectivity", + ha_name="Hive Hub Status", + hive_type="Connectivity", ) if entity_type == "siren": self.session.add_list("alarm_control_panel", device) @@ -526,30 +526,30 @@ async def call_devices_to_add(self, entity_type, device): self.session.add_list( "sensor", device, - haName=" Battery Level", - hiveType="Battery", + ha_name=" Battery Level", + hive_type="Battery", category="diagnostic", ) self.session.add_list( "sensor", device, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) if entity_type == "trv": self.session.add_list( "sensor", device, - haName=" Battery Level", - hiveType="Battery", + ha_name=" Battery Level", + hive_type="Battery", category="diagnostic", ) self.session.add_list( "sensor", device, - haName=" Availability", - hiveType="Availability", + ha_name=" Availability", + hive_type="Availability", category="diagnostic", ) @@ -558,7 +558,7 @@ async def call_action_to_add(self, action): await self.session.add_list( "switch", action, - hiveName=action["name"], - haName=action["name"], - hiveType="action", + hive_name=action["name"], + ha_name=action["name"], + hive_type="action", ) diff --git a/src/apyhiveapi/helper/hivedataclasses.py b/src/apyhiveapi/helper/hivedataclasses.py index ca9c8fd..ba6b566 100644 --- a/src/apyhiveapi/helper/hivedataclasses.py +++ b/src/apyhiveapi/helper/hivedataclasses.py @@ -8,14 +8,14 @@ class Device: """Class for keeping track of an device.""" - hiveID: str - hiveName: str - hiveType: str - haType: str - deviceData: dict + hive_id: str + hive_name: str + hive_type: str + ha_type: str + device_data: dict status: dict data: dict - parentDevice: str - isGroup: bool + parent_device: str + is_group: bool device_id: str device_name: str diff --git a/src/apyhiveapi/helper/logger.py b/src/apyhiveapi/helper/logger.py index 00bd7e1..69c0180 100644 --- a/src/apyhiveapi/helper/logger.py +++ b/src/apyhiveapi/helper/logger.py @@ -22,15 +22,15 @@ async def error(self, e="UNKNOWN"): async def error_check(self, n_id, n_type, error_type, **kwargs): """Error has occurred.""" message = None - name = self.session.helper.getDeviceName(n_id) + name = self.session.helper.get_device_name(n_id) if error_type is False: message = "Device offline could not update entity - " + name - if n_id not in self.session.config.errorList: + if n_id not in self.session.config.error_list: self.session.logger.warning(message) - self.session.config.errorList.update({n_id: datetime.now()}) + self.session.config.error_list.update({n_id: datetime.now()}) elif error_type == "Failed": message = "ERROR - No data found for device - " + name - if n_id not in self.session.config.errorList: + if n_id not in self.session.config.error_list: self.session.logger.error(message) - self.session.config.errorList.update({n_id: datetime.now()}) + self.session.config.error_list.update({n_id: datetime.now()}) diff --git a/src/apyhiveapi/hive.py b/src/apyhiveapi/hive.py index 222a69f..2663696 100644 --- a/src/apyhiveapi/hive.py +++ b/src/apyhiveapi/hive.py @@ -123,7 +123,7 @@ def __init__( if debug: sys.settrace(trace_debug) - def setDebugging(self, debugger: list): + def set_debugging(self, debugger: list): """Set function to debug. Args: diff --git a/src/apyhiveapi/hotwater.py b/src/apyhiveapi/hotwater.py index 50bb25b..b41c56d 100644 --- a/src/apyhiveapi/hotwater.py +++ b/src/apyhiveapi/hotwater.py @@ -11,7 +11,7 @@ class HiveHotwater: object: Hotwater Object. """ - hotwaterType = "Hotwater" + hot_water_type = "Hotwater" async def get_mode(self, device: dict): """Get hotwater current mode. @@ -26,11 +26,11 @@ async def get_mode(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["mode"] if state == "BOOST": state = data["props"]["previous"]["mode"] - final = HIVETOHA[self.hotwaterType].get(state, state) + final = HIVETOHA[self.hot_water_type].get(state, state) except KeyError as e: await self.session.log.error(e) @@ -58,7 +58,7 @@ async def get_boost(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["boost"] final = HIVETOHA["Boost"].get(state, "ON") except KeyError as e: @@ -78,7 +78,7 @@ async def get_boost_time(self, device: dict): state = None if await self.get_boost(device) == "ON": try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["boost"] except KeyError as e: await self.session.log.error(e) @@ -98,7 +98,7 @@ async def get_state(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["status"] mode_current = await self.get_mode(device) if mode_current == "SCHEDULE": @@ -108,7 +108,7 @@ async def get_state(self, device: dict): snan = self.session.helper.get_schedule_nnl(data["state"]["schedule"]) state = snan["now"]["value"]["status"] - final = HIVETOHA[self.hotwaterType].get(state, state) + final = HIVETOHA[self.hot_water_type].get(state, state) except KeyError as e: await self.session.log.error(e) @@ -126,11 +126,11 @@ async def set_mode(self, device: dict, new_mode: str): """ final = False - if device["hiveID"] in self.session.data.products: + if device["hive_id"] in self.session.data.products: await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( - data["type"], device["hiveID"], mode=new_mode + data["type"], device["hive_id"], mode=new_mode ) if resp["original"] == 200: final = True @@ -152,13 +152,13 @@ async def set_boost_on(self, device: dict, mins: int): if ( int(mins) > 0 - and device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + and device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( - data["type"], device["hiveID"], mode="BOOST", boost=mins + data["type"], device["hive_id"], mode="BOOST", boost=mins ) if resp["original"] == 200: final = True @@ -178,15 +178,15 @@ async def set_boost_off(self, device: dict): final = False if ( - device["hiveID"] in self.session.data.products + device["hive_id"] in self.session.data.products and await self.get_boost(device) == "ON" - and device["deviceData"]["online"] + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] prev_mode = data["props"]["previous"]["mode"] resp = await self.session.api.set_state( - data["type"], device["hiveID"], mode=prev_mode + data["type"], device["hive_id"], mode=prev_mode ) if resp["original"] == 200: await self.session.get_devices() @@ -219,37 +219,37 @@ async def get_water_heater(self, device: dict): Returns: dict: Updated device. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) - if device["deviceData"]["online"]: + if device["device_data"]["online"]: dev_data = {} self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device["device_id"], "device_name": device["device_name"], "status": {"current_operation": await self.get_mode(device)}, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "custom": device.get("custom", None), "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device @@ -267,7 +267,7 @@ async def get_schedule_now_next_later(self, device: dict): try: mode_current = await self.get_mode(device) if mode_current == "SCHEDULE": - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = self.session.helper.get_schedule_nnl(data["state"]["schedule"]) except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/hub.py b/src/apyhiveapi/hub.py index d1e4f3a..eee69af 100644 --- a/src/apyhiveapi/hub.py +++ b/src/apyhiveapi/hub.py @@ -10,8 +10,8 @@ class HiveHub: object: Returns a hub object. """ - hubType = "Hub" - logType = "Sensor" + hub_type = "Hub" + log_type = "Sensor" def __init__(self, session: object = None): """Initialise hub. @@ -34,9 +34,9 @@ async def get_smoke_status(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["sensors"]["SMOKE_CO"]["active"] - final = HIVETOHA[self.hubType]["Smoke"].get(state, state) + final = HIVETOHA[self.hub_type]["Smoke"].get(state, state) except KeyError as e: await self.session.log.error(e) @@ -55,9 +55,9 @@ async def get_dog_bark_status(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["sensors"]["DOG_BARK"]["active"] - final = HIVETOHA[self.hubType]["Dog"].get(state, state) + final = HIVETOHA[self.hub_type]["Dog"].get(state, state) except KeyError as e: await self.session.log.error(e) @@ -76,9 +76,9 @@ async def get_glass_break_status(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["sensors"]["GLASS_BREAK"]["active"] - final = HIVETOHA[self.hubType]["Glass"].get(state, state) + final = HIVETOHA[self.hub_type]["Glass"].get(state, state) except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/light.py b/src/apyhiveapi/light.py index e89c4b9..b8a2cf2 100644 --- a/src/apyhiveapi/light.py +++ b/src/apyhiveapi/light.py @@ -12,9 +12,9 @@ class HiveLight: object: Hivelight """ - lightType = "Light" + light_type = "Light" - async def getState(self, device: dict): + async def get_state(self, device: dict): """Get light current state. Args: @@ -27,15 +27,15 @@ async def getState(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["status"] - final = HIVETOHA[self.lightType].get(state, state) + final = HIVETOHA[self.light_type].get(state, state) except KeyError as e: await self.session.log.error(e) return final - async def getBrightness(self, device: dict): + async def get_brightness(self, device: dict): """Get light current brightness. Args: @@ -48,7 +48,7 @@ async def getBrightness(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["brightness"] final = (state / 100) * 255 except KeyError as e: @@ -56,7 +56,7 @@ async def getBrightness(self, device: dict): return final - async def getMinColorTemp(self, device: dict): + async def get_min_color_temp(self, device: dict): """Get light minimum color temperature. Args: @@ -69,7 +69,7 @@ async def getMinColorTemp(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["colourTemperature"]["max"] final = round((1 / state) * 1000000) except KeyError as e: @@ -77,7 +77,7 @@ async def getMinColorTemp(self, device: dict): return final - async def getMaxColorTemp(self, device: dict): + async def get_max_color_temp(self, device: dict): """Get light maximum color temperature. Args: @@ -90,7 +90,7 @@ async def getMaxColorTemp(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["colourTemperature"]["min"] final = round((1 / state) * 1000000) except KeyError as e: @@ -98,7 +98,7 @@ async def getMaxColorTemp(self, device: dict): return final - async def getColorTemp(self, device: dict): + async def get_color_temp(self, device: dict): """Get light current color temperature. Args: @@ -111,7 +111,7 @@ async def getColorTemp(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["colourTemperature"] final = round((1 / state) * 1000000) except KeyError as e: @@ -119,7 +119,7 @@ async def getColorTemp(self, device: dict): return final - async def getColor(self, device: dict): + async def get_color(self, device: dict): """Get light current colour. Args: @@ -132,7 +132,7 @@ async def getColor(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = [ (data["state"]["hue"]) / 360, (data["state"]["saturation"]) / 100, @@ -146,7 +146,7 @@ async def getColor(self, device: dict): return final - async def getColorMode(self, device: dict): + async def get_color_mode(self, device: dict): """Get Colour Mode. Args: @@ -158,14 +158,14 @@ async def getColorMode(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["colourMode"] except KeyError as e: await self.session.log.error(e) return state - async def setStatusOff(self, device: dict): + async def set_status_off(self, device: dict): """Set light to turn off. Args: @@ -177,13 +177,13 @@ async def setStatusOff(self, device: dict): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( - data["type"], device["hiveID"], status="OFF" + data["type"], device["hive_id"], status="OFF" ) if resp["original"] == 200: @@ -192,7 +192,7 @@ async def setStatusOff(self, device: dict): return final - async def setStatusOn(self, device: dict): + async def set_status_on(self, device: dict): """Set light to turn on. Args: @@ -204,14 +204,14 @@ async def setStatusOn(self, device: dict): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( - data["type"], device["hiveID"], status="ON" + data["type"], device["hive_id"], status="ON" ) if resp["original"] == 200: final = True @@ -219,7 +219,7 @@ async def setStatusOn(self, device: dict): return final - async def setBrightness(self, device: dict, n_brightness: int): + async def set_brightness(self, device: dict, n_brightness: int): """Set brightness of the light. Args: @@ -232,14 +232,14 @@ async def setBrightness(self, device: dict, n_brightness: int): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( data["type"], - device["hiveID"], + device["hive_id"], status="ON", brightness=n_brightness, ) @@ -249,7 +249,7 @@ async def setBrightness(self, device: dict, n_brightness: int): return final - async def setColorTemp(self, device: dict, color_temp: int): + async def set_color_temp(self, device: dict, color_temp: int): """Set light to turn on. Args: @@ -262,22 +262,22 @@ async def setColorTemp(self, device: dict, color_temp: int): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] if data["type"] == "tuneablelight": resp = await self.session.api.set_state( data["type"], - device["hiveID"], + device["hive_id"], colourTemperature=color_temp, ) else: resp = await self.session.api.set_state( data["type"], - device["hiveID"], + device["hive_id"], colourMode="WHITE", colourTemperature=color_temp, ) @@ -288,7 +288,7 @@ async def setColorTemp(self, device: dict, color_temp: int): return final - async def setColor(self, device: dict, new_color: list): + async def set_color(self, device: dict, new_color: list): """Set light to turn on. Args: @@ -301,15 +301,15 @@ async def setColor(self, device: dict, new_color: list): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( data["type"], - device["hiveID"], + device["hive_id"], colourMode="COLOUR", hue=str(new_color[0]), saturation=str(new_color[1]), @@ -337,7 +337,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getLight(self, device: dict): + async def get_light(self, device: dict): """Get light data. Args: @@ -346,69 +346,69 @@ async def getLight(self, device: dict): Returns: dict: Updated device. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} - if device["deviceData"]["online"]: + if device["device_data"]["online"]: self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device["device_id"], "device_name": device["device_name"], "status": { - "state": await self.getState(device), - "brightness": await self.getBrightness(device), + "state": await self.get_state(device), + "brightness": await self.get_brightness(device), }, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "custom": device.get("custom", None), "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } - if device["hiveType"] in ("tuneablelight", "colourtuneablelight"): + if device["hive_type"] in ("tuneablelight", "colourtuneablelight"): dev_data.update( { - "min_mireds": await self.getMinColorTemp(device), - "max_mireds": await self.getMaxColorTemp(device), + "min_mireds": await self.get_min_color_temp(device), + "max_mireds": await self.get_max_color_temp(device), } ) dev_data["status"].update( - {"color_temp": await self.getColorTemp(device)} + {"color_temp": await self.get_color_temp(device)} ) - if device["hiveType"] == "colourtuneablelight": - mode = await self.getColorMode(device) + if device["hive_type"] == "colourtuneablelight": + mode = await self.get_color_mode(device) if mode == "COLOUR": dev_data["status"].update( { - "hs_color": await self.getColor(device), - "mode": await self.getColorMode(device), + "hs_color": await self.get_color(device), + "mode": await self.get_color_mode(device), } ) else: dev_data["status"].update( { - "mode": await self.getColorMode(device), + "mode": await self.get_color_mode(device), } ) - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device - async def turnOn(self, device: dict, brightness: int, color_temp: int, color: list): + async def turn_on(self, device: dict, brightness: int, color_temp: int, color: list): """Set light to turn on. Args: @@ -421,15 +421,15 @@ async def turnOn(self, device: dict, brightness: int, color_temp: int, color: li boolean: True/False if successful. """ if brightness is not None: - return await self.setBrightness(device, brightness) + return await self.set_brightness(device, brightness) if color_temp is not None: - return await self.setColorTemp(device, color_temp) + return await self.set_color_temp(device, color_temp) if color is not None: - return await self.setColor(device, color) + return await self.set_color(device, color) - return await self.setStatusOn(device) + return await self.set_status_on(device) - async def turnOff(self, device: dict): + async def turn_off(self, device: dict): """Set light to turn off. Args: @@ -438,4 +438,4 @@ async def turnOff(self, device: dict): Returns: boolean: True/False if successful. """ - return await self.setStatusOff(device) + return await self.set_status_off(device) diff --git a/src/apyhiveapi/plug.py b/src/apyhiveapi/plug.py index 2af29bc..e20c387 100644 --- a/src/apyhiveapi/plug.py +++ b/src/apyhiveapi/plug.py @@ -10,7 +10,7 @@ class HiveSmartPlug: object: Returns Plug object """ - plugType = "Switch" + plug_type = "Switch" async def get_state(self, device: dict): """Get smart plug state. @@ -24,7 +24,7 @@ async def get_state(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["state"]["status"] state = HIVETOHA["Switch"].get(state, state) except KeyError as e: @@ -44,7 +44,7 @@ async def get_power_usage(self, device: dict): state = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] state = data["props"]["powerConsumption"] except KeyError as e: await self.session.log.error(e) @@ -63,11 +63,11 @@ async def set_status_on(self, device: dict): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( data["type"], data["id"], status="ON" ) @@ -89,11 +89,11 @@ async def set_status_off(self, device: dict): final = False if ( - device["hiveID"] in self.session.data.products - and device["deviceData"]["online"] + device["hive_id"] in self.session.data.products + and device["device_data"]["online"] ): await self.session.hive_refresh_tokens() - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] resp = await self.session.api.set_state( data["type"], data["id"], status="OFF" ) @@ -128,32 +128,32 @@ async def get_switch(self, device: dict): Returns: dict: Return device after update is complete. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) dev_data = {} - if device["deviceData"]["online"]: + if device["device_data"]["online"]: self.session.helper.device_recovered(device["device_id"]) data = self.session.data.devices[device["device_id"]] dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device["device_id"], "device_name": device["device_name"], "status": { "state": await self.get_switch_state(device), }, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "custom": device.get("custom", None), "attributes": {}, } - if device["hiveType"] == "activeplug": + if device["hive_type"] == "activeplug": dev_data.update( { "status": { @@ -161,16 +161,16 @@ async def get_switch(self, device: dict): "power_usage": await self.get_power_usage(device), }, "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } ) - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device @@ -183,7 +183,7 @@ async def get_switch_state(self, device: dict): Returns: boolean: Return True or False for the state. """ - if device["hiveType"] == "Heating_Heat_On_Demand": + if device["hive_type"] == "Heating_Heat_On_Demand": return await self.session.heating.get_heat_on_demand(device) else: return await self.get_state(device) @@ -197,7 +197,7 @@ async def turn_on(self, device: dict): Returns: function: Calls relevant function. """ - if device["hiveType"] == "Heating_Heat_On_Demand": + if device["hive_type"] == "Heating_Heat_On_Demand": return await self.session.heating.set_heat_on_demand(device, "ENABLED") else: return await self.set_status_on(device) @@ -211,7 +211,7 @@ async def turn_off(self, device: dict): Returns: function: Calls relevant function. """ - if device["hiveType"] == "Heating_Heat_On_Demand": + if device["hive_type"] == "Heating_Heat_On_Demand": return await self.session.heating.set_heat_on_demand(device, "DISABLED") else: return await self.set_status_off(device) diff --git a/src/apyhiveapi/sensor.py b/src/apyhiveapi/sensor.py index 8589d7c..181c4d5 100644 --- a/src/apyhiveapi/sensor.py +++ b/src/apyhiveapi/sensor.py @@ -6,9 +6,9 @@ class HiveSensor: """Hive Sensor Code.""" - sensorType = "Sensor" + sensor_type = "Sensor" - async def getState(self, device: dict): + async def get_state(self, device: dict): """Get sensor state. Args: @@ -21,10 +21,10 @@ async def getState(self, device: dict): final = None try: - data = self.session.data.products[device["hiveID"]] + data = self.session.data.products[device["hive_id"]] if data["type"] == "contactsensor": state = data["props"]["status"] - final = HIVETOHA[self.sensorType].get(state, state) + final = HIVETOHA[self.sensor_type].get(state, state) elif data["type"] == "motionsensor": final = data["props"]["motion"]["status"] except KeyError as e: @@ -47,7 +47,7 @@ async def online(self, device: dict): try: data = self.session.data.devices[device["device_id"]] state = data["props"]["online"] - final = HIVETOHA[self.sensorType].get(state, state) + final = HIVETOHA[self.sensor_type].get(state, state) except KeyError as e: await self.session.log.error(e) @@ -69,7 +69,7 @@ def __init__(self, session: object = None): """ self.session = session - async def getSensor(self, device: dict): + async def get_sensor(self, device: dict): """Gets updated sensor data. Args: @@ -78,62 +78,62 @@ async def getSensor(self, device: dict): Returns: dict: Updated device. """ - device["deviceData"].update( + device["device_data"].update( {"online": await self.session.attr.online_offline(device["device_id"])} ) data = {} - if device["deviceData"]["online"] or device["hiveType"] in ( + if device["device_data"]["online"] or device["hive_type"] in ( "Availability", "Connectivity", ): - if device["hiveType"] not in ("Availability", "Connectivity"): + if device["hive_type"] not in ("Availability", "Connectivity"): self.session.helper.device_recovered(device["device_id"]) dev_data = {} dev_data = { - "hiveID": device["hiveID"], - "hiveName": device["hiveName"], - "hiveType": device["hiveType"], - "haName": device["haName"], - "haType": device["haType"], + "hive_id": device["hive_id"], + "hive_name": device["hive_name"], + "hive_type": device["hive_type"], + "ha_name": device["ha_name"], + "ha_type": device["ha_type"], "device_id": device.get("device_id", None), "device_name": device.get("device_name", None), - "deviceData": {}, + "device_data": {}, "custom": device.get("custom", None), } if device["device_id"] in self.session.data.devices: data = self.session.data.devices.get(device["device_id"], {}) - elif device["hiveID"] in self.session.data.products: - data = self.session.data.products.get(device["hiveID"], {}) + elif device["hive_id"] in self.session.data.products: + data = self.session.data.products.get(device["hive_id"], {}) sensor_state = self.session.helper.call_sensor_function(dev_data) if sensor_state is not None: dev_data.update( { "status": {"state": sensor_state}, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), } ) - elif device["hiveType"] in HIVE_TYPES["Sensor"]: - data = self.session.data.devices.get(device["hiveID"], {}) + elif device["hive_type"] in HIVE_TYPES["Sensor"]: + data = self.session.data.devices.get(device["hive_id"], {}) dev_data.update( { - "status": {"state": await self.getState(device)}, - "deviceData": data.get("props", None), - "parentDevice": data.get("parent", None), + "status": {"state": await self.get_state(device)}, + "device_data": data.get("props", None), + "parent_device": data.get("parent", None), "attributes": await self.session.attr.state_attributes( - device["device_id"], device["hiveType"] + device["device_id"], device["hive_type"] ), } ) - self.session.devices.update({device["hiveID"]: dev_data}) - return self.session.devices[device["hiveID"]] + self.session.devices.update({device["hive_id"]: dev_data}) + return self.session.devices[device["hive_id"]] else: await self.session.log.error_check( - device["device_id"], "ERROR", device["deviceData"]["online"] + device["device_id"], "ERROR", device["device_data"]["online"] ) return device diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index b1ddb8c..800c7a0 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -42,7 +42,7 @@ class hive_session: object: Session object. """ - sessionType = "Session" + session_type = "Session" def __init__( self, @@ -78,13 +78,13 @@ def __init__( "alarm": False, "battery": [], "camera": False, - "errorList": {}, + "error_list": {}, "file": False, - "homeID": None, + "home_id": None, "last_updated": datetime.now(), "mode": [], "scan_interval": timedelta(seconds=120), - "userID": None, + "user_id": None, "username": username, } ) @@ -118,7 +118,7 @@ def open_file(self, file: str): return data - def add_list(self, entityType: str, data: dict, **kwargs: dict): + def add_list(self, entity_type: str, data: dict, **kwargs: dict): """Add entity to the list. Args: @@ -138,26 +138,26 @@ def add_list(self, entityType: str, data: dict, **kwargs: dict): try: formatted_data = { - "hiveID": data.get("id", ""), - "hiveName": device_name, - "hiveType": data.get("type", ""), - "haType": entityType, - "deviceData": device.get("props", data.get("props", {})), - "parentDevice": data.get("parent", None), - "isGroup": data.get("isGroup", False), + "hive_id": data.get("id", ""), + "hive_name": device_name, + "hive_type": data.get("type", ""), + "ha_type": entity_type, + "device_data": device.get("props", data.get("props", {})), + "parent_device": data.get("parent", None), + "is_group": data.get("is_group", False), "device_id": device["id"], "device_name": device_name, } - if kwargs.get("haName", "FALSE")[0] == " ": - kwargs["haName"] = device_name + kwargs["haName"] + if kwargs.get("ha_name", "FALSE")[0] == " ": + kwargs["ha_name"] = device_name + kwargs["ha_name"] else: - formatted_data["haName"] = device_name + formatted_data["ha_name"] = device_name formatted_data.update(kwargs) except KeyError as error: self.logger.error(error) - self.device_list[entityType].append(formatted_data) + self.device_list[entity_type].append(formatted_data) return formatted_data async def update_interval(self, new_interval: timedelta): @@ -199,15 +199,15 @@ async def update_tokens(self, tokens: dict, update_expiry_time: bool = True): data = tokens.get("AuthenticationResult") self.tokens.token_data.update({"token": data["IdToken"]}) if "RefreshToken" in data: - self.tokens.token_data.update({"refreshToken": data["RefreshToken"]}) - self.tokens.token_data.update({"accessToken": data["AccessToken"]}) + self.tokens.token_data.update({"refresh_token": data["RefreshToken"]}) + self.tokens.token_data.update({"access_token": data["AccessToken"]}) if update_expiry_time: self.tokens.token_created = datetime.now() elif "token" in tokens: data = tokens self.tokens.token_data.update({"token": data["token"]}) - self.tokens.token_data.update({"refreshToken": data["refreshToken"]}) - self.tokens.token_data.update({"accessToken": data["accessToken"]}) + self.tokens.token_data.update({"refresh_token": data["refreshToken"]}) + self.tokens.token_data.update({"access_token": data["accessToken"]}) if "ExpiresIn" in data: self.tokens.token_expiry = timedelta(seconds=data["ExpiresIn"]) @@ -302,7 +302,7 @@ async def hive_refresh_tokens(self): expiry_time = self.tokens.token_created + self.tokens.token_expiry if datetime.now() >= expiry_time: result = await self.auth.refresh_token( - self.tokens.token_data["refreshToken"] + self.tokens.token_data["refresh_token"] ) if "AuthenticationResult" in result: @@ -326,7 +326,7 @@ async def update_data(self, device: dict): if datetime.now() >= ep and not self.update_lock.locked(): try: await self.update_lock.acquire() - await self.get_devices(device["hiveID"]) + await self.get_devices(device["hive_id"]) if len(self.device_list["camera"]) > 0: for camera in self.data.camera: await self.get_camera(self.devices[camera]) @@ -389,24 +389,16 @@ async def get_camera(self, device): has_camera_image = bool(camera_image["parsed"]["events"][0]) self.data.camera[device["id"]] = {} - self.data.camera[device["id"]]["cameraImage"] = None - self.data.camera[device["id"]]["cameraRecording"] = None + self.data.camera[device["id"]]["camera_image"] = None + self.data.camera[device["id"]]["camera_recording"] = None if camera_image is not None and has_camera_image: self.data.camera[device["id"]] = {} - self.data.camera[device["id"]]["cameraImage"] = camera_image["parsed"][ + self.data.camera[device["id"]]["camera_image"] = camera_image["parsed"][ "events" ][0] if camera_recording is not None and has_camera_recording: - self.data.camera[device["id"]]["cameraRecording"] = camera_recording[ - "parsed" - ] - - async def get_devices(self, n_id: str): - """Get latest data for Hive nodes. - - Args: - n_id (str): ID of the device requesting data. + self.data.camera[device["id"]]["camera_recording"] = camera_recording[ Raises: HTTPException: HTTP error has occurred updating the devices. @@ -437,7 +429,7 @@ async def get_devices(self, n_id: str): for hive_type in api_resp_p: if hive_type == "user": self.data.user = api_resp_p[hive_type] - self.config.userID = api_resp_p[hive_type]["id"] + self.config.user_id = api_resp_p[hive_type]["id"] if hive_type == "products": for a_product in api_resp_p[hive_type]: temp_products.update({a_product["id"]: a_product}) @@ -452,7 +444,7 @@ async def get_devices(self, n_id: str): for a_action in api_resp_p[hive_type]: temp_actions.update({a_action["id"]: a_action}) if hive_type == "homes": - self.config.homeID = api_resp_p[hive_type]["homes"][0]["id"] + self.config.home_id = api_resp_p[hive_type]["homes"][0]["id"] if len(temp_products) > 0: self.data.products = copy.deepcopy(temp_products) diff --git a/tests/apyhiveapi/test_hub.py b/tests/apyhiveapi/test_hub.py index f6e3611..f676057 100644 --- a/tests/apyhiveapi/test_hub.py +++ b/tests/apyhiveapi/test_hub.py @@ -12,7 +12,7 @@ async def test_hub_get_smoke_status_detected(): await hive.async_start_session() hive_session = hive.async_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products[smoke_sensor["hiveID"]]["props"]["sensors"][ + hive_session.session.data.products[smoke_sensor["hive_id"]]["props"]["sensors"][ "SMOKE_CO" ]["active"] = True state = await hive_session.hub.get_smoke_status(smoke_sensor) @@ -40,7 +40,7 @@ async def test_hub_get_smoke_status_with_key_error(): await hive.async_start_session() hive_session = hive.async_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products.pop(smoke_sensor["hiveID"]) + hive_session.session.data.products.pop(smoke_sensor["hive_id"]) state = await hive_session.hub.get_smoke_status(smoke_sensor) assert state is None @@ -65,7 +65,7 @@ async def test_hub_get_glass_break_not_detected(): await hive.async_start_session() hive_session = hive.async_hive glass_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products[glass_sensor["hiveID"]]["props"]["sensors"][ + hive_session.session.data.products[glass_sensor["hive_id"]]["props"]["sensors"][ "GLASS_BREAK" ]["active"] = False state = await hive_session.hub.get_glass_break_status(glass_sensor) @@ -80,7 +80,7 @@ async def test_hub_get_glass_break_detection_with_key_error(): await hive.async_start_session() hive_session = hive.async_hive glass_sensor = hive_session.session.device_list["binary_sensor"][0] - hive_session.session.data.products.pop(glass_sensor["hiveID"]) + hive_session.session.data.products.pop(glass_sensor["hive_id"]) state = await hive_session.hub.get_glass_break_status(glass_sensor) assert state is None @@ -93,7 +93,7 @@ async def test_hub_get_dog_bark_detected(): await hive.async_start_session() hive_session = hive.async_hive dog_sensor = hive_session.session.device_list["binary_sensor"][2] - hive_session.session.data.products[dog_sensor["hiveID"]]["props"]["sensors"][ + hive_session.session.data.products[dog_sensor["hive_id"]]["props"]["sensors"][ "DOG_BARK" ]["active"] = True state = await hive_session.hub.get_dog_bark_status(dog_sensor) @@ -120,7 +120,7 @@ async def test_hub_get_dog_bark_detection_status_with_key_error(): await hive.async_start_session() hive_session = hive.async_hive dog_sensor = hive_session.session.device_list["binary_sensor"][2] - hive_session.session.data.products.pop(dog_sensor["hiveID"]) + hive_session.session.data.products.pop(dog_sensor["hive_id"]) state = await hive_session.hub.get_dog_bark_status(dog_sensor) assert state is None diff --git a/tests/apyhiveapi/test_plug.py b/tests/apyhiveapi/test_plug.py index 2199795..50336c1 100644 --- a/tests/apyhiveapi/test_plug.py +++ b/tests/apyhiveapi/test_plug.py @@ -14,7 +14,7 @@ async def test_switch_update_switch_online(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - device_data = await hive_session.switch.getSwitch(switch) + device_data = await hive_session.switch.get_switch(switch) assert device_data != {} @@ -26,10 +26,10 @@ async def test_switch_update_switch_offline(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - switch["deviceData"]["online"] = False - device_data = await hive_session.switch.getSwitch(switch) + switch["device_data"]["online"] = False + device_data = await hive_session.switch.get_switch(switch) - assert device_data["hiveID"] in hive_session.session.config.errorList + assert device_data["hive_id"] in hive_session.session.config.error_list @pytest.mark.asyncio @@ -39,7 +39,7 @@ async def test_switch_get_plug_state(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - state = await hive_session.switch.getSwitchState(switch) + state = await hive_session.switch.get_switchState(switch) assert state in (True, False) @@ -51,8 +51,8 @@ async def test_switch_get_plug_state_with_key_error(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - hive_session.session.data.products.pop(switch["hiveID"]) - state = await hive_session.switch.getState(switch) + hive_session.session.data.products.pop(switch["hive_id"]) + state = await hive_session.switch.get_state(switch) assert state is None @@ -64,7 +64,7 @@ async def test_switch_get_heat_on_demand_state(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][0] - state = await hive_session.switch.getSwitchState(switch) + state = await hive_session.switch.get_switchState(switch) assert state in (True, False) @@ -81,7 +81,7 @@ async def test_switch_turn_on_successfully(): "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: - result = await hive_session.switch.turnOn(switch) + result = await hive_session.switch.turn_on(switch) assert result is True assert len(api_call.mock_calls) == 1 @@ -99,7 +99,7 @@ async def test_switch_turn_on_unsuccessfully(): "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: - result = await hive_session.switch.turnOn(switch) + result = await hive_session.switch.turn_on(switch) assert result is False assert len(api_call.mock_calls) == 1 @@ -117,7 +117,7 @@ async def test_switch_turn_off_successfully(): "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: - result = await hive_session.switch.turnOff(switch) + result = await hive_session.switch.turn_off(switch) assert result is True assert len(api_call.mock_calls) == 1 @@ -135,7 +135,7 @@ async def test_switch_turn_off_unsuccessfully(): "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: - result = await hive_session.switch.turnOff(switch) + result = await hive_session.switch.turn_off(switch) assert result is False assert len(api_call.mock_calls) == 1 @@ -153,7 +153,7 @@ async def test_switch_heat_on_demand_turn_on_successfully(): "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: - result = await hive_session.switch.turnOn(switch) + result = await hive_session.switch.turn_on(switch) assert result is True assert len(api_call.mock_calls) == 1 @@ -171,7 +171,7 @@ async def test_switch_heat_on_demand_turn_on_unsuccessfully(): "apyhiveapi.api.hive_async_api.HiveApiAsync.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: - result = await hive_session.switch.turnOff(switch) + result = await hive_session.switch.turn_off(switch) assert result is False assert len(api_call.mock_calls) == 1 @@ -184,7 +184,7 @@ async def test_plug_get_power_usage(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - power_usage = await hive_session.switch.getPowerUsage(switch) + power_usage = await hive_session.switch.get_power_usage(switch) assert power_usage is not None @@ -196,7 +196,7 @@ async def test_plug_get_power_usage_with_key_error(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - hive_session.session.data.products.pop(switch["hiveID"]) - state = await hive_session.switch.getPowerUsage(switch) + hive_session.session.data.products.pop(switch["hive_id"]) + state = await hive_session.switch.get_power_usage(switch) assert state is None diff --git a/tests/apyhiveapi/test_session.py b/tests/apyhiveapi/test_session.py index a69d772..5a2be39 100644 --- a/tests/apyhiveapi/test_session.py +++ b/tests/apyhiveapi/test_session.py @@ -6,7 +6,7 @@ @pytest.mark.asyncio -async def test_startSession(): +async def test_start_session(): """Test a session can be started.""" hive = MockSession() device_list = await hive.async_start_session() diff --git a/tests/common.py b/tests/common.py index 0d56566..10a5e35 100644 --- a/tests/common.py +++ b/tests/common.py @@ -49,9 +49,9 @@ def __init__(self): def sync_start_session(self): """Start a sync session.""" self.sync_hive = HiveSync(username=USERNAME, password=PASSWORD) - return self.sync_hive.startSession(TEMP_CONFIG) + return self.sync_hive.start_session(TEMP_CONFIG) async def async_start_session(self): """Start a async session.""" self.async_hive = HiveAsync(username=USERNAME, password=PASSWORD) - return await self.async_hive.startSession(TEMP_CONFIG) + return await self.async_hive.start_session(TEMP_CONFIG) diff --git a/tests/pyhiveapi/test_hub.py b/tests/pyhiveapi/test_hub.py index 94ca927..64eda5a 100644 --- a/tests/pyhiveapi/test_hub.py +++ b/tests/pyhiveapi/test_hub.py @@ -9,7 +9,7 @@ def test_hub_get_smoke_status_detected(): hive.sync_start_session() hive_session = hive.sync_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products[smoke_sensor["hiveID"]]["props"]["sensors"][ + hive_session.session.data.products[smoke_sensor["hive_id"]]["props"]["sensors"][ "SMOKE_CO" ]["active"] = True state = hive_session.hub.get_smoke_status(smoke_sensor) @@ -35,7 +35,7 @@ def test_hub_get_smoke_status_with_key_error(): hive.sync_start_session() hive_session = hive.sync_hive smoke_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products.pop(smoke_sensor["hiveID"]) + hive_session.session.data.products.pop(smoke_sensor["hive_id"]) state = hive_session.hub.get_smoke_status(smoke_sensor) assert state is None @@ -58,7 +58,7 @@ def test_hub_get_glass_break_not_detected(): hive.sync_start_session() hive_session = hive.sync_hive glass_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products[glass_sensor["hiveID"]]["props"]["sensors"][ + hive_session.session.data.products[glass_sensor["hive_id"]]["props"]["sensors"][ "GLASS_BREAK" ]["active"] = False state = hive_session.hub.get_glass_break_status(glass_sensor) @@ -72,7 +72,7 @@ def test_hub_get_glass_break_detection_with_key_error(): hive.sync_start_session() hive_session = hive.sync_hive glass_sensor = hive_session.session.device_list["binary_sensor"][0] - hive_session.session.data.products.pop(glass_sensor["hiveID"]) + hive_session.session.data.products.pop(glass_sensor["hive_id"]) state = hive_session.hub.get_glass_break_status(glass_sensor) assert state is None @@ -84,7 +84,7 @@ def test_hub_get_dog_bark_detected(): hive.sync_start_session() hive_session = hive.sync_hive dog_sensor = hive_session.session.device_list["binary_sensor"][2] - hive_session.session.data.products[dog_sensor["hiveID"]]["props"]["sensors"][ + hive_session.session.data.products[dog_sensor["hive_id"]]["props"]["sensors"][ "DOG_BARK" ]["active"] = True state = hive_session.hub.get_dog_bark_status(dog_sensor) @@ -109,7 +109,7 @@ def test_hub_get_dog_bark_detection_status_with_key_error(): hive.sync_start_session() hive_session = hive.sync_hive dog_sensor = hive_session.session.device_list["binary_sensor"][1] - hive_session.session.data.products.pop(dog_sensor["hiveID"]) + hive_session.session.data.products.pop(dog_sensor["hive_id"]) state = hive_session.hub.get_dog_bark_status(dog_sensor) assert state is None diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_plug.py index 118e755..c8bad09 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_plug.py @@ -11,7 +11,7 @@ def test_switch_update_switch_online(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - device_data = hive_session.switch.getSwitch(switch) + device_data = hive_session.switch.get_switch(switch) assert device_data != {} @@ -22,10 +22,10 @@ def test_switch_update_switch_offline(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - switch["deviceData"]["online"] = False - device_data = hive_session.switch.getSwitch(switch) + switch["device_data"]["online"] = False + device_data = hive_session.switch.get_switch(switch) - assert device_data["hiveID"] in hive_session.session.config.errorList + assert device_data["hive_id"] in hive_session.session.config.error_list def test_switch_get_plug_state(): @@ -34,7 +34,7 @@ def test_switch_get_plug_state(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - state = hive_session.switch.getSwitchState(switch) + state = hive_session.switch.get_switchState(switch) assert state in (True, False) @@ -45,8 +45,8 @@ def test_switch_get_plug_state_with_key_error(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - hive_session.session.data.products.pop(switch["hiveID"]) - state = hive_session.switch.getState(switch) + hive_session.session.data.products.pop(switch["hive_id"]) + state = hive_session.switch.get_state(switch) assert state is None @@ -57,7 +57,7 @@ def test_switch_get_heat_on_demand_state(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][0] - state = hive_session.switch.getSwitchState(switch) + state = hive_session.switch.get_switchState(switch) assert state in (True, False) @@ -73,7 +73,7 @@ def test_switch_turn_on_successfully(): "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: - result = hive_session.switch.turnOn(switch) + result = hive_session.switch.turn_on(switch) assert result is True assert len(api_call.mock_calls) == 1 @@ -90,7 +90,7 @@ def test_switch_turn_on_unsuccessfully(): "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: - result = hive_session.switch.turnOn(switch) + result = hive_session.switch.turn_on(switch) assert result is False assert len(api_call.mock_calls) == 1 @@ -107,7 +107,7 @@ def test_switch_turn_off_successfully(): "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: - result = hive_session.switch.turnOff(switch) + result = hive_session.switch.turn_off(switch) assert result is True assert len(api_call.mock_calls) == 1 @@ -124,7 +124,7 @@ def test_switch_turn_off_unsuccessfully(): "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: - result = hive_session.switch.turnOff(switch) + result = hive_session.switch.turn_off(switch) assert result is False assert len(api_call.mock_calls) == 1 @@ -141,7 +141,7 @@ def test_switch_heat_on_demand_turn_on_successfully(): "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 200, "parsed": {}}, ) as api_call: - result = hive_session.switch.turnOn(switch) + result = hive_session.switch.turn_on(switch) assert result is True assert len(api_call.mock_calls) == 1 @@ -158,7 +158,7 @@ def test_switch_heat_on_demand_turn_on_unsuccessfully(): "pyhiveapi.api.hive_api.HiveApi.set_state", return_value={"original": 401, "parsed": {}}, ) as api_call: - result = hive_session.switch.turnOff(switch) + result = hive_session.switch.turn_off(switch) assert result is False assert len(api_call.mock_calls) == 1 @@ -170,7 +170,7 @@ def test_plug_get_power_usage(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - power_usage = hive_session.switch.getPowerUsage(switch) + power_usage = hive_session.switch.get_power_usage(switch) assert power_usage is not None @@ -181,7 +181,7 @@ def test_plug_get_power_usage_with_key_error(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - hive_session.session.data.products.pop(switch["hiveID"]) - state = hive_session.switch.getPowerUsage(switch) + hive_session.session.data.products.pop(switch["hive_id"]) + state = hive_session.switch.get_power_usage(switch) assert state is None From 481bdaad74f78d86c9278686249300c62d7cd09f Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 21 Dec 2024 16:42:16 +0000 Subject: [PATCH 19/26] Update latest changes --- pyhiveapi/apyhiveapi/helper/const.py | 170 --------------------------- setup.cfg | 2 +- setup.py | 2 +- src/apyhiveapi/session.py | 12 +- 4 files changed, 4 insertions(+), 182 deletions(-) delete mode 100644 pyhiveapi/apyhiveapi/helper/const.py diff --git a/pyhiveapi/apyhiveapi/helper/const.py b/pyhiveapi/apyhiveapi/helper/const.py deleted file mode 100644 index 9e78b9c..0000000 --- a/pyhiveapi/apyhiveapi/helper/const.py +++ /dev/null @@ -1,170 +0,0 @@ -"""Constants for Pyhiveapi.""" -# pylint: skip-file -SYNC_PACKAGE_NAME = "pyhiveapi" -SYNC_PACKAGE_DIR = "/pyhiveapi/" -ASYNC_PACKAGE_NAME = "apyhiveapi" -ASYNC_PACKAGE_DIR = "/apyhiveapi/" -SMS_REQUIRED = "SMS_MFA" - - -# HTTP return codes. -HTTP_OK = 200 -HTTP_CREATED = 201 -HTTP_ACCEPTED = 202 -HTTP_MOVED_PERMANENTLY = 301 -HTTP_BAD_REQUEST = 400 -HTTP_UNAUTHORIZED = 401 -HTTP_FORBIDDEN = 403 -HTTP_NOT_FOUND = 404 -HTTP_METHOD_NOT_ALLOWED = 405 -HTTP_UNPROCESSABLE_ENTITY = 422 -HTTP_TOO_MANY_REQUESTS = 429 -HTTP_INTERNAL_SERVER_ERROR = 500 -HTTP_BAD_GATEWAY = 502 -HTTP_SERVICE_UNAVAILABLE = 503 - - -HIVETOHA = { - "Alarm": {"home": "armed_home", "away": "armed_away", "asleep": "armed_night"}, - "Attribute": {True: "Online", False: "Offline"}, - "Boost": {None: "OFF", False: "OFF"}, - "Heating": {False: "OFF", "ENABLED": True, "DISABLED": False}, - "Hotwater": {"MANUAL": "ON", None: "OFF", False: "OFF"}, - "Hub": { - "Status": {True: 1, False: 0}, - "Smoke": {True: 1, False: 0}, - "Dog": {True: 1, False: 0}, - "Glass": {True: 1, False: 0}, - }, - "Light": {"ON": True, "OFF": False}, - "Sensor": { - "OPEN": True, - "CLOSED": False, - True: "Online", - False: "Offline", - }, - "Switch": {"ON": True, "OFF": False}, -} - -HIVE_TYPES = { - "Hub": ["hub", "sense"], - "Thermo": ["thermostatui", "trv"], - "Heating": ["heating", "trvcontrol"], - "Hotwater": ["hotwater"], - "Light": ["warmwhitelight", "tuneablelight", "colourtuneablelight"], - "Sensor": ["motionsensor", "contactsensor"], - "Switch": ["activeplug"], -} -sensor_commands = { - "SMOKE_CO": "self.session.hub.get_smoke_status(device)", - "DOG_BARK": "self.session.hub.get_dog_bark_status(device)", - "GLASS_BREAK": "self.session.hub.get_glass_break_status(device)", - "Camera_Temp": "self.session.camera.get_camera_temperature(device)", - "Current_Temperature": "self.session.heating.get_current_temperature(device)", - "Heating_Current_Temperature": "self.session.heating.get_current_temperature(device)", - "Heating_Target_Temperature": "self.session.heating.get_target_temperature(device)", - "Heating_State": "self.session.heating.get_state(device)", - "Heating_Mode": "self.session.heating.get_mode(device)", - "Heating_Boost": "self.session.heating.get_boost_status(device)", - "Hotwater_State": "self.session.hotwater.get_state(device)", - "Hotwater_Mode": "self.session.hotwater.get_mode(device)", - "Hotwater_Boost": "self.session.hotwater.get_boost(device)", - "Battery": 'self.session.attr.get_battery(device["device_id"])', - "Mode": 'self.session.attr.get_mode(device["hive_id"])', - "Availability": "self.online(device)", - "Connectivity": "self.online(device)", - "Power": "self.session.switch.get_power_usage(device)", -} - -PRODUCTS = { - "sense": [ - 'addList("binary_sensor", p, ha_name="Glass Detection", hive_type="GLASS_BREAK")', - 'addList("binary_sensor", p, ha_name="Smoke Detection", hive_type="SMOKE_CO")', - 'addList("binary_sensor", p, ha_name="Dog Bark Detection", hive_type="DOG_BARK")', - ], - "heating": [ - 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("switch", p, ha_name=" Heat on Demand", hive_type="Heating_Heat_On_Demand", category="config")', - 'addList("sensor", p, ha_name=" Current Temperature", hive_type="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, ha_name=" Target Temperature", hive_type="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, ha_name=" State", hive_type="Heating_State", category="diagnostic")', - 'addList("sensor", p, ha_name=" Mode", hive_type="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, ha_name=" Boost", hive_type="Heating_Boost", category="diagnostic")', - ], - "trvcontrol": [ - 'addList("climate", p, temperatureunit=self.data["user"]["temperatureUnit"])', - 'addList("sensor", p, ha_name=" Current Temperature", hive_type="Heating_Current_Temperature", category="diagnostic")', - 'addList("sensor", p, ha_name=" Target Temperature", hive_type="Heating_Target_Temperature", category="diagnostic")', - 'addList("sensor", p, ha_name=" State", hive_type="Heating_State", category="diagnostic")', - 'addList("sensor", p, ha_name=" Mode", hive_type="Heating_Mode", category="diagnostic")', - 'addList("sensor", p, ha_name=" Boost", hive_type="Heating_Boost", category="diagnostic")', - ], - "hotwater": [ - 'addList("water_heater", p,)', - 'addList("sensor", p, ha_name="Hot Water State", hive_type="Hotwater_State", category="diagnostic")', - 'addList("sensor", p, ha_name="Hot Water Mode", hive_type="Hotwater_Mode", category="diagnostic")', - 'addList("sensor", p, ha_name="Hot Water Boost", hive_type="Hotwater_Boost", category="diagnostic")', - ], - "activeplug": [ - 'addList("switch", p)', - 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', - 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - 'addList("sensor", p, ha_name=" Power", hive_type="Power", category="diagnostic")', - ], - "warmwhitelight": [ - 'addList("light", p)', - 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', - 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], - "tuneablelight": [ - 'addList("light", p)', - 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', - 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], - "colourtuneablelight": [ - 'addList("light", p)', - 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', - 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], - # "hivecamera": [ - # 'addList("camera", p)', - # 'addList("sensor", p, ha_name=" Mode", hive_type="Mode", category="diagnostic")', - # 'addList("sensor", p, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - # 'addList("sensor", p, ha_name=" Temperature", hive_type="Camera_Temp", category="diagnostic")', - # ], - "motionsensor": [ - 'addList("binary_sensor", p)', - 'addList("sensor", p, ha_name=" Current Temperature", hive_type="Current_Temperature", category="diagnostic")', - ], - "contactsensor": ['addList("binary_sensor", p)'], -} - -DEVICES = { - "contactsensor": [ - 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', - 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], - "hub": [ - 'addList("binary_sensor", d, ha_name="Hive Hub Status", hive_type="Connectivity", category="diagnostic")', - ], - "motionsensor": [ - 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', - 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], - "sense": [ - 'addList("binary_sensor", d, ha_name="Hive Hub Status", hive_type="Connectivity")', - ], - "siren": ['addList("alarm_control_panel", d)'], - "thermostatui": [ - 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', - 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], - "trv": [ - 'addList("sensor", d, ha_name=" Battery Level", hive_type="Battery", category="diagnostic")', - 'addList("sensor", d, ha_name=" Availability", hive_type="Availability", category="diagnostic")', - ], -} - -ACTIONS = ( - 'addList("switch", a, hive_name=a["name"], ha_name=a["name"], hive_type="action")' -) diff --git a/setup.cfg b/setup.cfg index 15bcebc..4d04a49 100644 --- a/setup.cfg +++ b/setup.cfg @@ -69,7 +69,7 @@ warn_unused_configs = true [tool:pytest] minversion = 6.0 -addopts = -ra -q --timeout=10 +addopts = -ra -q testpaths = tests/pyhiveapi tests/apyhiveapi \ No newline at end of file diff --git a/setup.py b/setup.py index 5576394..f23ffab 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ def requirements_from_file(filename="requirements_all.txt"): setup( - version="0.5.16", + version="0.5.17", package_data={"data": ["*.json"]}, include_package_data=True, cmdclass={ diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index 800c7a0..66e7fb6 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -393,20 +393,12 @@ async def get_camera(self, device): self.data.camera[device["id"]]["camera_recording"] = None if camera_image is not None and has_camera_image: - self.data.camera[device["id"]] = {} self.data.camera[device["id"]]["camera_image"] = camera_image["parsed"][ "events" ][0] if camera_recording is not None and has_camera_recording: - self.data.camera[device["id"]]["camera_recording"] = camera_recording[ - - Raises: - HTTPException: HTTP error has occurred updating the devices. - HiveApiError: An API error code has been returned. - - Returns: - boolean: True/False if update was successful. - """ + self.data.camera[device["id"]]["camera_recording"] = camera_recording + get_nodes_successful = False api_resp_d = None From 7e04e4d005d9de4f02fa4bcace1994c7779c75cf Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 27 Jan 2025 21:56:23 +0000 Subject: [PATCH 20/26] fix hive helper --- pyhiveapi/apyhiveapi/helper/hive_helper.py | 213 ----------- src/apyhiveapi/helper/hive_helper.py | 393 ++------------------- 2 files changed, 21 insertions(+), 585 deletions(-) delete mode 100644 pyhiveapi/apyhiveapi/helper/hive_helper.py diff --git a/pyhiveapi/apyhiveapi/helper/hive_helper.py b/pyhiveapi/apyhiveapi/helper/hive_helper.py deleted file mode 100644 index 7943cd7..0000000 --- a/pyhiveapi/apyhiveapi/helper/hive_helper.py +++ /dev/null @@ -1,213 +0,0 @@ -"""Helper class for pyhiveapi.""" -# pylint: skip-file -import datetime -import operator - -from .const import HIVE_TYPES - - -class HiveHelper: - """Hive helper class.""" - - def __init__(self, session: object = None): - """Hive Helper. - - Args: - session (object, optional): Interact with hive account. Defaults to None. - """ - self.session = session - - def getDeviceName(self, n_id: str): - """Resolve a id into a name. - - Args: - n_id (str): ID of a device. - - Returns: - str: Name of device. - """ - try: - product_name = self.session.data.products[n_id]["state"]["name"] - except KeyError: - product_name = False - - try: - device_name = self.session.data.devices[n_id]["state"]["name"] - except KeyError: - device_name = False - - if product_name: - return product_name - elif device_name: - return device_name - elif n_id == "No_ID": - return "Hive" - else: - return n_id - - def deviceRecovered(self, n_id: str): - """Register that a device has recovered from being offline. - - Args: - n_id (str): ID of the device. - """ - # name = HiveHelper.getDeviceName(n_id) - if n_id in self.session.config.errorList: - self.session.config.errorList.pop(n_id) - - def getDeviceFromID(self, n_id: str): - """Get product/device data from ID. - - Args: - n_id (str): ID of the device. - - Returns: - dict: Device data. - """ - data = False - try: - data = self.session.devices[n_id] - except KeyError: - pass - - return data - - def getDeviceData(self, product: dict): - """Get device from product data. - - Args: - product (dict): Product data. - - Returns: - [type]: Device data. - """ - device = product - type = product["type"] - if type in ("heating", "hotwater"): - for aDevice in self.session.data.devices: - if self.session.data.devices[aDevice]["type"] in HIVE_TYPES["Thermo"]: - try: - if ( - product["props"]["zone"] - == self.session.data.devices[aDevice]["props"]["zone"] - ): - device = self.session.data.devices[aDevice] - except KeyError: - pass - elif type == "trvcontrol": - trv_present = len(product["props"]["trvs"]) > 0 - if trv_present: - device = self.session.data.devices[product["props"]["trvs"][0]] - else: - raise KeyError - elif type == "warmwhitelight" and product["props"]["model"] == "SIREN001": - device = self.session.data.devices[product["parent"]] - elif type == "sense": - device = self.session.data.devices[product["parent"]] - else: - device = self.session.data.devices[product["id"]] - - return device - - def convertMinutesToTime(self, minutes_to_convert: str): - """Convert minutes string to datetime. - - Args: - minutes_to_convert (str): minutes in string value. - - Returns: - timedelta: time object of the minutes. - """ - hours_converted, minutes_converted = divmod(minutes_to_convert, 60) - converted_time = datetime.datetime.strptime( - str(hours_converted) + ":" + str(minutes_converted), "%H:%M" - ) - converted_time_string = converted_time.strftime("%H:%M") - return converted_time_string - - def getScheduleNNL(self, hive_api_schedule: list): - """Get the schedule now, next and later of a given nodes schedule. - - Args: - hive_api_schedule (list): Schedule to parse. - - Returns: - dict: Now, Next and later values. - """ - schedule_now_and_next = {} - date_time_now = datetime.datetime.now() - date_time_now_day_int = date_time_now.today().weekday() - - days_t = ( - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday", - "sunday", - ) - - days_rolling_list = list(days_t[date_time_now_day_int:] + days_t)[:7] - - full_schedule_list = [] - - for day_index in range(0, len(days_rolling_list)): - current_day_schedule = hive_api_schedule[days_rolling_list[day_index]] - current_day_schedule_sorted = sorted( - current_day_schedule, - key=operator.itemgetter("start"), - reverse=False, - ) - - for current_slot in range(0, len(current_day_schedule_sorted)): - current_slot_custom = current_day_schedule_sorted[current_slot] - - slot_date = datetime.datetime.now() + datetime.timedelta(days=day_index) - slot_time = self.convertMinutesToTime(current_slot_custom["start"]) - slot_time_date_s = slot_date.strftime("%d-%m-%Y") + " " + slot_time - slot_time_date_dt = datetime.datetime.strptime( - slot_time_date_s, "%d-%m-%Y %H:%M" - ) - if slot_time_date_dt <= date_time_now: - slot_time_date_dt = slot_time_date_dt + datetime.timedelta(days=7) - - current_slot_custom["Start_DateTime"] = slot_time_date_dt - full_schedule_list.append(current_slot_custom) - - fsl_sorted = sorted( - full_schedule_list, - key=operator.itemgetter("Start_DateTime"), - reverse=False, - ) - - schedule_now = fsl_sorted[-1] - schedule_next = fsl_sorted[0] - schedule_later = fsl_sorted[1] - - schedule_now["Start_DateTime"] = schedule_now[ - "Start_DateTime" - ] - datetime.timedelta(days=7) - - schedule_now["End_DateTime"] = schedule_next["Start_DateTime"] - schedule_next["End_DateTime"] = schedule_later["Start_DateTime"] - schedule_later["End_DateTime"] = fsl_sorted[2]["Start_DateTime"] - - schedule_now_and_next["now"] = schedule_now - schedule_now_and_next["next"] = schedule_next - schedule_now_and_next["later"] = schedule_later - - return schedule_now_and_next - - def getHeatOnDemandDevice(self, device: dict): - """Use TRV device to get the linked thermostat device. - - Args: - device ([dictionary]): [The TRV device to lookup.] - - Returns: - [dictionary]: [Gets the thermostat device linked to TRV.] - """ - trv = self.session.data.products.get(device["HiveID"]) - thermostat = self.session.data.products.get(trv["state"]["zone"]) - return thermostat diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index 2ec1975..7943cd7 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -17,7 +17,7 @@ def __init__(self, session: object = None): """ self.session = session - def get_device_name(self, n_id: str): + def getDeviceName(self, n_id: str): """Resolve a id into a name. Args: @@ -45,17 +45,17 @@ def get_device_name(self, n_id: str): else: return n_id - def device_recovered(self, n_id: str): + def deviceRecovered(self, n_id: str): """Register that a device has recovered from being offline. Args: n_id (str): ID of the device. """ - # name = HiveHelper.get_device_name(n_id) - if n_id in self.session.config.error_list: - self.session.config.error_list.pop(n_id) + # name = HiveHelper.getDeviceName(n_id) + if n_id in self.session.config.errorList: + self.session.config.errorList.pop(n_id) - def get_device_from_id(self, n_id: str): + def getDeviceFromID(self, n_id: str): """Get product/device data from ID. Args: @@ -72,7 +72,7 @@ def get_device_from_id(self, n_id: str): return data - def get_device_data(self, product: dict): + def getDeviceData(self, product: dict): """Get device from product data. Args: @@ -84,18 +84,22 @@ def get_device_data(self, product: dict): device = product type = product["type"] if type in ("heating", "hotwater"): - for a_device in self.session.data.devices: - if self.session.data.devices[a_device]["type"] in HIVE_TYPES["Thermo"]: + for aDevice in self.session.data.devices: + if self.session.data.devices[aDevice]["type"] in HIVE_TYPES["Thermo"]: try: if ( product["props"]["zone"] - == self.session.data.devices[a_device]["props"]["zone"] + == self.session.data.devices[aDevice]["props"]["zone"] ): - device = self.session.data.devices[a_device] + device = self.session.data.devices[aDevice] except KeyError: pass elif type == "trvcontrol": - device = self.session.data.devices[product["props"]["trvs"][0]] + trv_present = len(product["props"]["trvs"]) > 0 + if trv_present: + device = self.session.data.devices[product["props"]["trvs"][0]] + else: + raise KeyError elif type == "warmwhitelight" and product["props"]["model"] == "SIREN001": device = self.session.data.devices[product["parent"]] elif type == "sense": @@ -105,7 +109,7 @@ def get_device_data(self, product: dict): return device - def convert_minutes_to_time(self, minutes_to_convert: str): + def convertMinutesToTime(self, minutes_to_convert: str): """Convert minutes string to datetime. Args: @@ -121,7 +125,7 @@ def convert_minutes_to_time(self, minutes_to_convert: str): converted_time_string = converted_time.strftime("%H:%M") return converted_time_string - def get_schedule_nnl(self, hive_api_schedule: list): + def getScheduleNNL(self, hive_api_schedule: list): """Get the schedule now, next and later of a given nodes schedule. Args: @@ -160,7 +164,7 @@ def get_schedule_nnl(self, hive_api_schedule: list): current_slot_custom = current_day_schedule_sorted[current_slot] slot_date = datetime.datetime.now() + datetime.timedelta(days=day_index) - slot_time = self.convert_minutes_to_time(current_slot_custom["start"]) + slot_time = self.convertMinutesToTime(current_slot_custom["start"]) slot_time_date_s = slot_date.strftime("%d-%m-%Y") + " " + slot_time slot_time_date_dt = datetime.datetime.strptime( slot_time_date_s, "%d-%m-%Y %H:%M" @@ -195,7 +199,7 @@ def get_schedule_nnl(self, hive_api_schedule: list): return schedule_now_and_next - def get_heat_on_demand_device(self, device: dict): + def getHeatOnDemandDevice(self, device: dict): """Use TRV device to get the linked thermostat device. Args: @@ -204,361 +208,6 @@ def get_heat_on_demand_device(self, device: dict): Returns: [dictionary]: [Gets the thermostat device linked to TRV.] """ - trv = self.session.data.products.get(device["hive_id"]) + trv = self.session.data.products.get(device["HiveID"]) thermostat = self.session.data.products.get(trv["state"]["zone"]) return thermostat - - async def call_sensor_function(self, device): - """Helper to decide which function to call.""" - if device["hive_type"] == "SMOKE_CO": - return await self.session.hub.get_smoke_status(device) - if device["hive_type"] == "DOG_BARK": - return await self.session.hub.get_dog_bark_status(device) - if device["hive_type"] == "GLASS_BREAK": - return await self.session.hub.get_glass_break_status(device) - if device["hive_type"] == "Camera_Temp": - return await self.session.camera.get_camera_temperature(device) - if device["hive_type"] == "Heating_Current_Temperature": - return await self.session.heating.get_current_temperature(device) - if device["hive_type"] == "Heating_Target_Temperature": - return await self.session.heating.get_target_temperature(device) - if device["hive_type"] == "Heating_State": - return await self.session.heating.get_state(device) - if device["hive_type"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): - return await self.session.heating.get_mode(device) - if device["hive_type"] == "Heating_Boost": - return await self.session.heating.get_boost_status(device) - if device["hive_type"] == "Hotwater_State": - return await self.session.hotwater.get_state(device) - if device["hive_type"] == "Hotwater_Boost": - return await self.session.hotwater.get_boost(device) - if device["hive_type"] == "Battery": - return await self.session.attr.get_battery(device["device_id"]) - if device["hive_type"] in ("Availability", "Connectivity"): - return await self.online(device) - if device["hive_type"] == "Power": - return await self.session.switch.get_power_usage(device) - return None - - async def call_products_to_add(self, entity_type, product): - """Helper to add a product to the list.""" - if entity_type == "sense": - self.session.add_list( - "binary_sensor", - product, - ha_name="Glass Detection", - hive_type="GLASS_BREAK", - ) - self.session.add_list( - "binary_sensor", product, ha_name="Smoke Detection", hive_type="SMOKE_CO" - ) - self.session.add_list( - "binary_sensor", - product, - ha_name="Dog Bark Detection", - hive_type="DOG_BARK", - ) - if entity_type == "heating": - self.session.add_list( - "climate", - product, - temperatureunit=self.session.data["user"]["temperatureUnit"], - ) - self.session.add_list( - "switch", - product, - ha_name=" Heat on Demand", - hive_type="Heating_Heat_On_Demand", - category="config", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Current Temperature", - hive_type="Heating_Current_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Target Temperature", - hive_type="Heating_Target_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" State", - hive_type="Heating_State", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Heating_Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Boost", - hive_type="Heating_Boost", - category="diagnostic", - ) - if entity_type == "trvcontrol": - self.session.add_list( - "climate", - product, - temperatureunit=self.session.data["user"]["temperatureUnit"], - ) - self.session.add_list( - "sensor", - product, - ha_name=" Current Temperature", - hive_type="Heating_Current_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Target Temperature", - hive_type="Heating_Target_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" State", - hive_type="Heating_State", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Heating_Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Boost", - hive_type="Heating_Boost", - category="diagnostic", - ) - if entity_type == "hotwater": - self.session.add_list( - "water_heater", - product, - ) - self.session.add_list( - "sensor", - product, - ha_name="Hotwater State", - hive_type="Hotwater_State", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name="Hotwater Mode", - hive_type="Hotwater_Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name="Hotwater Boost", - hive_type="Hotwater_Boost", - category="diagnostic", - ) - if entity_type == "activeplug": - self.session.add_list("switch", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Power", - hive_type="Power", - category="diagnostic", - ) - if entity_type == "warmwhitelight": - self.session.add_list("light", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "tuneablelight": - self.session.add_list("light", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "colourtuneablelight": - self.session.add_list("light", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "hivecamera": - self.session.add_list("camera", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Temperature", - hive_type="Camera_Temp", - category="diagnostic", - ) - if entity_type == "motionsensor": - self.session.add_list("binary_sensor", product) - if entity_type == "contactsensor": - self.session.add_list("binary_sensor", product) - return None - - async def call_devices_to_add(self, entity_type, device): - """Helper to add a device to the list.""" - if entity_type == "contactsensor": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "hub": - self.session.add_list( - "binary_sensor", - device, - ha_name="Hive Hub Status", - hive_type="Connectivity", - category="diagnostic", - ) - if entity_type == "motionsensor": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "sense": - self.session.add_list( - "binary_sensor", - device, - ha_name="Hive Hub Status", - hive_type="Connectivity", - ) - if entity_type == "siren": - self.session.add_list("alarm_control_panel", device) - if entity_type == "thermostatui": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "trv": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - - async def call_action_to_add(self, action): - """Helper to add an action to the list.""" - await self.session.add_list( - "switch", - action, - hive_name=action["name"], - ha_name=action["name"], - hive_type="action", - ) From e74c63cbf94d9fd3975f6f775d64be888b044374 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 27 Jan 2025 21:57:58 +0000 Subject: [PATCH 21/26] re add trv checks --- src/apyhiveapi/helper/hive_helper.py | 389 +++++++++++++++++++++++++-- 1 file changed, 372 insertions(+), 17 deletions(-) diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index 7943cd7..93a085f 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -17,7 +17,7 @@ def __init__(self, session: object = None): """ self.session = session - def getDeviceName(self, n_id: str): + def get_device_name(self, n_id: str): """Resolve a id into a name. Args: @@ -45,17 +45,17 @@ def getDeviceName(self, n_id: str): else: return n_id - def deviceRecovered(self, n_id: str): + def device_recovered(self, n_id: str): """Register that a device has recovered from being offline. Args: n_id (str): ID of the device. """ - # name = HiveHelper.getDeviceName(n_id) - if n_id in self.session.config.errorList: - self.session.config.errorList.pop(n_id) + # name = HiveHelper.get_device_name(n_id) + if n_id in self.session.config.error_list: + self.session.config.error_list.pop(n_id) - def getDeviceFromID(self, n_id: str): + def get_device_from_id(self, n_id: str): """Get product/device data from ID. Args: @@ -72,7 +72,7 @@ def getDeviceFromID(self, n_id: str): return data - def getDeviceData(self, product: dict): + def get_device_data(self, product: dict): """Get device from product data. Args: @@ -84,14 +84,14 @@ def getDeviceData(self, product: dict): device = product type = product["type"] if type in ("heating", "hotwater"): - for aDevice in self.session.data.devices: - if self.session.data.devices[aDevice]["type"] in HIVE_TYPES["Thermo"]: + for a_device in self.session.data.devices: + if self.session.data.devices[a_device]["type"] in HIVE_TYPES["Thermo"]: try: if ( product["props"]["zone"] - == self.session.data.devices[aDevice]["props"]["zone"] + == self.session.data.devices[a_device]["props"]["zone"] ): - device = self.session.data.devices[aDevice] + device = self.session.data.devices[a_device] except KeyError: pass elif type == "trvcontrol": @@ -99,7 +99,7 @@ def getDeviceData(self, product: dict): if trv_present: device = self.session.data.devices[product["props"]["trvs"][0]] else: - raise KeyError + raise KeyError("TRV not present") elif type == "warmwhitelight" and product["props"]["model"] == "SIREN001": device = self.session.data.devices[product["parent"]] elif type == "sense": @@ -109,7 +109,7 @@ def getDeviceData(self, product: dict): return device - def convertMinutesToTime(self, minutes_to_convert: str): + def convert_minutes_to_time(self, minutes_to_convert: str): """Convert minutes string to datetime. Args: @@ -125,7 +125,7 @@ def convertMinutesToTime(self, minutes_to_convert: str): converted_time_string = converted_time.strftime("%H:%M") return converted_time_string - def getScheduleNNL(self, hive_api_schedule: list): + def get_schedule_nnl(self, hive_api_schedule: list): """Get the schedule now, next and later of a given nodes schedule. Args: @@ -164,7 +164,7 @@ def getScheduleNNL(self, hive_api_schedule: list): current_slot_custom = current_day_schedule_sorted[current_slot] slot_date = datetime.datetime.now() + datetime.timedelta(days=day_index) - slot_time = self.convertMinutesToTime(current_slot_custom["start"]) + slot_time = self.convert_minutes_to_time(current_slot_custom["start"]) slot_time_date_s = slot_date.strftime("%d-%m-%Y") + " " + slot_time slot_time_date_dt = datetime.datetime.strptime( slot_time_date_s, "%d-%m-%Y %H:%M" @@ -199,7 +199,7 @@ def getScheduleNNL(self, hive_api_schedule: list): return schedule_now_and_next - def getHeatOnDemandDevice(self, device: dict): + def get_heat_on_demand_device(self, device: dict): """Use TRV device to get the linked thermostat device. Args: @@ -208,6 +208,361 @@ def getHeatOnDemandDevice(self, device: dict): Returns: [dictionary]: [Gets the thermostat device linked to TRV.] """ - trv = self.session.data.products.get(device["HiveID"]) + trv = self.session.data.products.get(device["hive_id"]) thermostat = self.session.data.products.get(trv["state"]["zone"]) return thermostat + + async def call_sensor_function(self, device): + """Helper to decide which function to call.""" + if device["hive_type"] == "SMOKE_CO": + return await self.session.hub.get_smoke_status(device) + if device["hive_type"] == "DOG_BARK": + return await self.session.hub.get_dog_bark_status(device) + if device["hive_type"] == "GLASS_BREAK": + return await self.session.hub.get_glass_break_status(device) + if device["hive_type"] == "Camera_Temp": + return await self.session.camera.get_camera_temperature(device) + if device["hive_type"] == "Heating_Current_Temperature": + return await self.session.heating.get_current_temperature(device) + if device["hive_type"] == "Heating_Target_Temperature": + return await self.session.heating.get_target_temperature(device) + if device["hive_type"] == "Heating_State": + return await self.session.heating.get_state(device) + if device["hive_type"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): + return await self.session.heating.get_mode(device) + if device["hive_type"] == "Heating_Boost": + return await self.session.heating.get_boost_status(device) + if device["hive_type"] == "Hotwater_State": + return await self.session.hotwater.get_state(device) + if device["hive_type"] == "Hotwater_Boost": + return await self.session.hotwater.get_boost(device) + if device["hive_type"] == "Battery": + return await self.session.attr.get_battery(device["device_id"]) + if device["hive_type"] in ("Availability", "Connectivity"): + return await self.online(device) + if device["hive_type"] == "Power": + return await self.session.switch.get_power_usage(device) + return None + + async def call_products_to_add(self, entity_type, product): + """Helper to add a product to the list.""" + if entity_type == "sense": + self.session.add_list( + "binary_sensor", + product, + ha_name="Glass Detection", + hive_type="GLASS_BREAK", + ) + self.session.add_list( + "binary_sensor", product, ha_name="Smoke Detection", hive_type="SMOKE_CO" + ) + self.session.add_list( + "binary_sensor", + product, + ha_name="Dog Bark Detection", + hive_type="DOG_BARK", + ) + if entity_type == "heating": + self.session.add_list( + "climate", + product, + temperatureunit=self.session.data["user"]["temperatureUnit"], + ) + self.session.add_list( + "switch", + product, + ha_name=" Heat on Demand", + hive_type="Heating_Heat_On_Demand", + category="config", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Current Temperature", + hive_type="Heating_Current_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Target Temperature", + hive_type="Heating_Target_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" State", + hive_type="Heating_State", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Heating_Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Boost", + hive_type="Heating_Boost", + category="diagnostic", + ) + if entity_type == "trvcontrol": + self.session.add_list( + "climate", + product, + temperatureunit=self.session.data["user"]["temperatureUnit"], + ) + self.session.add_list( + "sensor", + product, + ha_name=" Current Temperature", + hive_type="Heating_Current_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Target Temperature", + hive_type="Heating_Target_Temperature", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" State", + hive_type="Heating_State", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Heating_Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Boost", + hive_type="Heating_Boost", + category="diagnostic", + ) + if entity_type == "hotwater": + self.session.add_list( + "water_heater", + product, + ) + self.session.add_list( + "sensor", + product, + ha_name="Hotwater State", + hive_type="Hotwater_State", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name="Hotwater Mode", + hive_type="Hotwater_Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name="Hotwater Boost", + hive_type="Hotwater_Boost", + category="diagnostic", + ) + if entity_type == "activeplug": + self.session.add_list("switch", product) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Power", + hive_type="Power", + category="diagnostic", + ) + if entity_type == "warmwhitelight": + self.session.add_list("light", product) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + if entity_type == "tuneablelight": + self.session.add_list("light", product) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + if entity_type == "colourtuneablelight": + self.session.add_list("light", product) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + if entity_type == "hivecamera": + self.session.add_list("camera", product) + self.session.add_list( + "sensor", + product, + ha_name=" Mode", + hive_type="Mode", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + self.session.add_list( + "sensor", + product, + ha_name=" Temperature", + hive_type="Camera_Temp", + category="diagnostic", + ) + if entity_type == "motionsensor": + self.session.add_list("binary_sensor", product) + if entity_type == "contactsensor": + self.session.add_list("binary_sensor", product) + return None + + async def call_devices_to_add(self, entity_type, device): + """Helper to add a device to the list.""" + if entity_type == "contactsensor": + self.session.add_list( + "sensor", + device, + ha_name=" Battery Level", + hive_type="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + if entity_type == "hub": + self.session.add_list( + "binary_sensor", + device, + ha_name="Hive Hub Status", + hive_type="Connectivity", + category="diagnostic", + ) + if entity_type == "motionsensor": + self.session.add_list( + "sensor", + device, + ha_name=" Battery Level", + hive_type="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + if entity_type == "sense": + self.session.add_list( + "binary_sensor", + device, + ha_name="Hive Hub Status", + hive_type="Connectivity", + ) + if entity_type == "siren": + self.session.add_list("alarm_control_panel", device) + if entity_type == "thermostatui": + self.session.add_list( + "sensor", + device, + ha_name=" Battery Level", + hive_type="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + if entity_type == "trv": + self.session.add_list( + "sensor", + device, + ha_name=" Battery Level", + hive_type="Battery", + category="diagnostic", + ) + self.session.add_list( + "sensor", + device, + ha_name=" Availability", + hive_type="Availability", + category="diagnostic", + ) + + async def call_action_to_add(self, action): + """Helper to add an action to the list.""" + await self.session.add_list( + "switch", + action, + hive_name=action["name"], + ha_name=action["name"], + hive_type="action", + ) From 960bdda5989a1d6c541a5307d51f861cef009c37 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 27 Jan 2025 22:20:44 +0000 Subject: [PATCH 22/26] Update changes --- src/apyhiveapi/helper/hive_helper.py | 427 +++------------------------ 1 file changed, 34 insertions(+), 393 deletions(-) diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index 93a085f..89e7e70 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -1,5 +1,5 @@ """Helper class for pyhiveapi.""" -# pylint: skip-file + import datetime import operator @@ -38,12 +38,12 @@ def get_device_name(self, n_id: str): if product_name: return product_name - elif device_name: + if device_name: return device_name - elif n_id == "No_ID": + if n_id == "No_ID": return "Hive" - else: - return n_id + + return n_id def device_recovered(self, n_id: str): """Register that a device has recovered from being offline. @@ -82,8 +82,8 @@ def get_device_data(self, product: dict): [type]: Device data. """ device = product - type = product["type"] - if type in ("heating", "hotwater"): + device_type = product["type"] + if device_type in ("heating", "hotwater"): for a_device in self.session.data.devices: if self.session.data.devices[a_device]["type"] in HIVE_TYPES["Thermo"]: try: @@ -94,15 +94,15 @@ def get_device_data(self, product: dict): device = self.session.data.devices[a_device] except KeyError: pass - elif type == "trvcontrol": + elif device_type == "trvcontrol": trv_present = len(product["props"]["trvs"]) > 0 if trv_present: device = self.session.data.devices[product["props"]["trvs"][0]] else: - raise KeyError("TRV not present") - elif type == "warmwhitelight" and product["props"]["model"] == "SIREN001": + raise KeyError + elif device_type == "warmwhitelight" and product["props"]["model"] == "SIREN001": device = self.session.data.devices[product["parent"]] - elif type == "sense": + elif device_type == "sense": device = self.session.data.devices[product["parent"]] else: device = self.session.data.devices[product["id"]] @@ -125,18 +125,18 @@ def convert_minutes_to_time(self, minutes_to_convert: str): converted_time_string = converted_time.strftime("%H:%M") return converted_time_string - def get_schedule_nnl(self, hive_api_schedule: list): - """Get the schedule now, next and later of a given nodes schedule. + def get_schedule_nnl(self, hive_api_schedule: list) -> dict: + """Get the schedule now, next, and later of a given node's schedule. Args: hive_api_schedule (list): Schedule to parse. Returns: - dict: Now, Next and later values. + dict: Now, Next, and later values. """ schedule_now_and_next = {} - date_time_now = datetime.datetime.now() - date_time_now_day_int = date_time_now.today().weekday() + now = datetime.datetime.now() + day_int = now.weekday() days_t = ( "monday", @@ -148,50 +148,46 @@ def get_schedule_nnl(self, hive_api_schedule: list): "sunday", ) - days_rolling_list = list(days_t[date_time_now_day_int:] + days_t)[:7] + days_rolling_list = list(days_t[day_int:] + days_t[:day_int]) full_schedule_list = [] - for day_index in range(0, len(days_rolling_list)): - current_day_schedule = hive_api_schedule[days_rolling_list[day_index]] + for day_index, day_name in enumerate(days_rolling_list): + current_day_schedule = hive_api_schedule.get(day_name, []) current_day_schedule_sorted = sorted( current_day_schedule, key=operator.itemgetter("start"), reverse=False, ) - for current_slot in range(0, len(current_day_schedule_sorted)): - current_slot_custom = current_day_schedule_sorted[current_slot] - - slot_date = datetime.datetime.now() + datetime.timedelta(days=day_index) + for current_slot_custom in current_day_schedule_sorted: + slot_date = now + datetime.timedelta(days=day_index) slot_time = self.convert_minutes_to_time(current_slot_custom["start"]) - slot_time_date_s = slot_date.strftime("%d-%m-%Y") + " " + slot_time + slot_time_date_s = f"{slot_date.strftime('%d-%m-%Y')} {slot_time}" slot_time_date_dt = datetime.datetime.strptime( slot_time_date_s, "%d-%m-%Y %H:%M" ) - if slot_time_date_dt <= date_time_now: - slot_time_date_dt = slot_time_date_dt + datetime.timedelta(days=7) + if slot_time_date_dt <= now: + slot_time_date_dt += datetime.timedelta(days=7) current_slot_custom["Start_DateTime"] = slot_time_date_dt full_schedule_list.append(current_slot_custom) - fsl_sorted = sorted( - full_schedule_list, - key=operator.itemgetter("Start_DateTime"), - reverse=False, - ) + full_schedule_list.sort(key=operator.itemgetter("Start_DateTime")) - schedule_now = fsl_sorted[-1] - schedule_next = fsl_sorted[0] - schedule_later = fsl_sorted[1] + if len(full_schedule_list) < 3: + raise ValueError("Schedule list must contain at least three entries.") - schedule_now["Start_DateTime"] = schedule_now[ - "Start_DateTime" - ] - datetime.timedelta(days=7) + schedule_now, schedule_next, schedule_later = ( + full_schedule_list[-1], + full_schedule_list[0], + full_schedule_list[1], + ) + schedule_now["Start_DateTime"] -= datetime.timedelta(days=7) schedule_now["End_DateTime"] = schedule_next["Start_DateTime"] schedule_next["End_DateTime"] = schedule_later["Start_DateTime"] - schedule_later["End_DateTime"] = fsl_sorted[2]["Start_DateTime"] + schedule_later["End_DateTime"] = full_schedule_list[2]["Start_DateTime"] schedule_now_and_next["now"] = schedule_now schedule_now_and_next["next"] = schedule_next @@ -211,358 +207,3 @@ def get_heat_on_demand_device(self, device: dict): trv = self.session.data.products.get(device["hive_id"]) thermostat = self.session.data.products.get(trv["state"]["zone"]) return thermostat - - async def call_sensor_function(self, device): - """Helper to decide which function to call.""" - if device["hive_type"] == "SMOKE_CO": - return await self.session.hub.get_smoke_status(device) - if device["hive_type"] == "DOG_BARK": - return await self.session.hub.get_dog_bark_status(device) - if device["hive_type"] == "GLASS_BREAK": - return await self.session.hub.get_glass_break_status(device) - if device["hive_type"] == "Camera_Temp": - return await self.session.camera.get_camera_temperature(device) - if device["hive_type"] == "Heating_Current_Temperature": - return await self.session.heating.get_current_temperature(device) - if device["hive_type"] == "Heating_Target_Temperature": - return await self.session.heating.get_target_temperature(device) - if device["hive_type"] == "Heating_State": - return await self.session.heating.get_state(device) - if device["hive_type"] in ("Heating_Mode", "Hotwater_Mode", "Mode"): - return await self.session.heating.get_mode(device) - if device["hive_type"] == "Heating_Boost": - return await self.session.heating.get_boost_status(device) - if device["hive_type"] == "Hotwater_State": - return await self.session.hotwater.get_state(device) - if device["hive_type"] == "Hotwater_Boost": - return await self.session.hotwater.get_boost(device) - if device["hive_type"] == "Battery": - return await self.session.attr.get_battery(device["device_id"]) - if device["hive_type"] in ("Availability", "Connectivity"): - return await self.online(device) - if device["hive_type"] == "Power": - return await self.session.switch.get_power_usage(device) - return None - - async def call_products_to_add(self, entity_type, product): - """Helper to add a product to the list.""" - if entity_type == "sense": - self.session.add_list( - "binary_sensor", - product, - ha_name="Glass Detection", - hive_type="GLASS_BREAK", - ) - self.session.add_list( - "binary_sensor", product, ha_name="Smoke Detection", hive_type="SMOKE_CO" - ) - self.session.add_list( - "binary_sensor", - product, - ha_name="Dog Bark Detection", - hive_type="DOG_BARK", - ) - if entity_type == "heating": - self.session.add_list( - "climate", - product, - temperatureunit=self.session.data["user"]["temperatureUnit"], - ) - self.session.add_list( - "switch", - product, - ha_name=" Heat on Demand", - hive_type="Heating_Heat_On_Demand", - category="config", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Current Temperature", - hive_type="Heating_Current_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Target Temperature", - hive_type="Heating_Target_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" State", - hive_type="Heating_State", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Heating_Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Boost", - hive_type="Heating_Boost", - category="diagnostic", - ) - if entity_type == "trvcontrol": - self.session.add_list( - "climate", - product, - temperatureunit=self.session.data["user"]["temperatureUnit"], - ) - self.session.add_list( - "sensor", - product, - ha_name=" Current Temperature", - hive_type="Heating_Current_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Target Temperature", - hive_type="Heating_Target_Temperature", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" State", - hive_type="Heating_State", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Heating_Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Boost", - hive_type="Heating_Boost", - category="diagnostic", - ) - if entity_type == "hotwater": - self.session.add_list( - "water_heater", - product, - ) - self.session.add_list( - "sensor", - product, - ha_name="Hotwater State", - hive_type="Hotwater_State", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name="Hotwater Mode", - hive_type="Hotwater_Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name="Hotwater Boost", - hive_type="Hotwater_Boost", - category="diagnostic", - ) - if entity_type == "activeplug": - self.session.add_list("switch", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Power", - hive_type="Power", - category="diagnostic", - ) - if entity_type == "warmwhitelight": - self.session.add_list("light", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "tuneablelight": - self.session.add_list("light", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "colourtuneablelight": - self.session.add_list("light", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "hivecamera": - self.session.add_list("camera", product) - self.session.add_list( - "sensor", - product, - ha_name=" Mode", - hive_type="Mode", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - self.session.add_list( - "sensor", - product, - ha_name=" Temperature", - hive_type="Camera_Temp", - category="diagnostic", - ) - if entity_type == "motionsensor": - self.session.add_list("binary_sensor", product) - if entity_type == "contactsensor": - self.session.add_list("binary_sensor", product) - return None - - async def call_devices_to_add(self, entity_type, device): - """Helper to add a device to the list.""" - if entity_type == "contactsensor": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "hub": - self.session.add_list( - "binary_sensor", - device, - ha_name="Hive Hub Status", - hive_type="Connectivity", - category="diagnostic", - ) - if entity_type == "motionsensor": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "sense": - self.session.add_list( - "binary_sensor", - device, - ha_name="Hive Hub Status", - hive_type="Connectivity", - ) - if entity_type == "siren": - self.session.add_list("alarm_control_panel", device) - if entity_type == "thermostatui": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - if entity_type == "trv": - self.session.add_list( - "sensor", - device, - ha_name=" Battery Level", - hive_type="Battery", - category="diagnostic", - ) - self.session.add_list( - "sensor", - device, - ha_name=" Availability", - hive_type="Availability", - category="diagnostic", - ) - - async def call_action_to_add(self, action): - """Helper to add an action to the list.""" - await self.session.add_list( - "switch", - action, - hive_name=action["name"], - ha_name=action["name"], - hive_type="action", - ) From 02c386adc11f605a6cef2c694d1b6f026e9a2b0c Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Mon, 27 Jan 2025 22:23:20 +0000 Subject: [PATCH 23/26] update hive helper --- src/apyhiveapi/helper/hive_helper.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index 89e7e70..b279e89 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -125,6 +125,9 @@ def convert_minutes_to_time(self, minutes_to_convert: str): converted_time_string = converted_time.strftime("%H:%M") return converted_time_string + ## Exclude below functions from pylint checks + + @staticmethod def get_schedule_nnl(self, hive_api_schedule: list) -> dict: """Get the schedule now, next, and later of a given node's schedule. @@ -134,6 +137,7 @@ def get_schedule_nnl(self, hive_api_schedule: list) -> dict: Returns: dict: Now, Next, and later values. """ + # pylint: disable=too-many-locals, too-many-branches schedule_now_and_next = {} now = datetime.datetime.now() day_int = now.weekday() From efb1cec2252e13fcaa5391348bc8aed215c62f99 Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sat, 8 Feb 2025 11:40:45 +0000 Subject: [PATCH 24/26] add all pylint change for pylint coverage --- .pylintrc | 8 +- setup.py | 2 +- src/apyhiveapi/__init__.py | 8 +- src/apyhiveapi/action.py | 19 ++- src/apyhiveapi/alarm.py | 11 +- src/apyhiveapi/api/hive_api.py | 73 ++++++----- src/apyhiveapi/api/hive_async_api.py | 105 ++++++++------- src/apyhiveapi/api/hive_auth.py | 2 +- src/apyhiveapi/api/hive_auth_async.py | 5 +- src/apyhiveapi/camera.py | 20 +-- src/apyhiveapi/device_attributes.py | 8 +- src/apyhiveapi/heating.py | 20 +-- src/apyhiveapi/helper/__init__.py | 2 +- src/apyhiveapi/helper/const.py | 3 +- src/apyhiveapi/helper/debugger.py | 28 ++-- src/apyhiveapi/helper/hive_exceptions.py | 9 +- src/apyhiveapi/helper/hive_helper.py | 11 +- src/apyhiveapi/helper/hivedataclasses.py | 1 - src/apyhiveapi/helper/logger.py | 16 ++- src/apyhiveapi/helper/map.py | 33 ++++- src/apyhiveapi/hive.py | 28 ++-- src/apyhiveapi/hotwater.py | 12 +- src/apyhiveapi/hub.py | 2 +- src/apyhiveapi/light.py | 12 +- src/apyhiveapi/plug.py | 26 ++-- src/apyhiveapi/sensor.py | 13 +- src/apyhiveapi/session.py | 158 +++++++++++++---------- tests/common.py | 2 +- 28 files changed, 359 insertions(+), 278 deletions(-) diff --git a/.pylintrc b/.pylintrc index 15a09fa..5006899 100644 --- a/.pylintrc +++ b/.pylintrc @@ -154,7 +154,13 @@ disable=raw-checker-failed, too-many-arguments, too-many-branches, duplicate-code, - import-error + import-error, + R0917, + E1101, + W0603, + W0123, + R0401, + # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/setup.py b/setup.py index 16e3340..7a59212 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ """Setup pyhiveapi package.""" -# pylint: skip-file + import os import re diff --git a/src/apyhiveapi/__init__.py b/src/apyhiveapi/__init__.py index 926049b..9fe3a7e 100644 --- a/src/apyhiveapi/__init__.py +++ b/src/apyhiveapi/__init__.py @@ -1,7 +1,10 @@ """__init__.py.""" -# pylint: skip-file + import os +from .helper.const import SMS_REQUIRED # noqa: F401 +from .hive import Hive # noqa: F401 + if __name__ == "pyhiveapi": from .api.hive_api import HiveApi as API # noqa: F401 from .api.hive_auth import HiveAuth as Auth # noqa: F401 @@ -14,5 +17,4 @@ PATH = os.path.dirname(os.path.realpath(__file__)) + "/test_data/" -from .helper.const import SMS_REQUIRED # noqa: F401 -from .hive import Hive # noqa: F401 + # noqa: F401 diff --git a/src/apyhiveapi/action.py b/src/apyhiveapi/action.py index 189b546..96c260b 100644 --- a/src/apyhiveapi/action.py +++ b/src/apyhiveapi/action.py @@ -1,7 +1,6 @@ """Hive Action Module.""" -# pylint: skip-file - +import json class HiveAction: """Hive Action Code. @@ -30,7 +29,7 @@ async def get_action(self, device: dict): """ dev_data = {} - if device["hive_id"] in self.data["action"]: + if device["hive_id"] in self.session.data.actions: dev_data = { "hive_id": device["hive_id"], "hive_name": device["hive_name"], @@ -45,11 +44,11 @@ async def get_action(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - exists = self.session.data.actions.get("hive_id", False) - if exists is False: - return "REMOVE" - return device + + exists = self.session.data.actions.get("hive_id", False) + if exists is False: + return "REMOVE" + return device async def get_state(self, device: dict): """Get action state. @@ -79,7 +78,7 @@ async def set_status_on(self, device: dict): Returns: boolean: True/False if successful. """ - import json + final = False @@ -104,8 +103,6 @@ async def set_status_off(self, device: dict): Returns: boolean: True/False if successful. """ - import json - final = False if device["hive_id"] in self.session.data.actions: diff --git a/src/apyhiveapi/alarm.py b/src/apyhiveapi/alarm.py index f4912d9..59974fd 100644 --- a/src/apyhiveapi/alarm.py +++ b/src/apyhiveapi/alarm.py @@ -1,5 +1,4 @@ """Hive Alarm Module.""" -# pylint: skip-file class HiveHomeShield: @@ -121,8 +120,8 @@ async def get_alarm(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device diff --git a/src/apyhiveapi/api/hive_api.py b/src/apyhiveapi/api/hive_api.py index 7d86237..da65a57 100644 --- a/src/apyhiveapi/api/hive_api.py +++ b/src/apyhiveapi/api/hive_api.py @@ -1,10 +1,11 @@ """Hive API Module.""" -# pylint: skip-file + import json +from typing import Any, Dict, Optional +from pyquery import PyQuery import requests import urllib3 -from pyquery import PyQuery urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @@ -25,8 +26,10 @@ def __init__(self, hive_session=None, websession=None, token=None): "holiday_mode": "/holiday-mode", "all": "/nodes/all?products=true&devices=true&actions=true", "alarm": "/security-lite?homeId=", - "cameraImages": f"https://event-history-service.{self.camera_base_url}/v1/events/cameras?latest=true&cameraId={{0}}", - "cameraRecordings": f"https://event-history-service.{self.camera_base_url}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", + "cameraImages": f"https://event-history-service.{self.camera_base_url}" \ + "/v1/events/cameras?latest=true&cameraId={{0}}", + "cameraRecordings": f"https://event-history-service.{self.camera_base_url}" \ + "/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", "devices": "/devices", "products": "/products", "actions": "/actions", @@ -39,8 +42,10 @@ def __init__(self, hive_session=None, websession=None, token=None): } self.session = hive_session self.token = token + self.headers = {} + self.websession = websession - def request(self, type, url, jsc=None, camera=False): + def request(self, request_type, url, jsc=None, camera=False): """Make API request.""" if self.session is not None: if camera: @@ -71,30 +76,26 @@ def request(self, type, url, jsc=None, camera=False): "authorization": self.token, } - if type == "GET": + if request_type == "GET": return requests.get( url=url, headers=self.headers, data=jsc, timeout=self.timeout ) - if type == "POST": + if request_type == "POST": return requests.post( url=url, headers=self.headers, data=jsc, timeout=self.timeout ) - def refresh_tokens(self, tokens={}): + return None + + def refresh_tokens(self, tokens: Dict[str, str] = None) -> Dict[str, Any]: """Get new session tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" url = self.urls["refresh"] if self.session is not None: tokens = self.session.tokens.token_data - jsc = ( - "{" - + ",".join( - ('"' + str(i) + '": ' '"' + str(t) + '" ' for i, t in tokens.items()) - ) - + "}" - ) + jsc = json.dumps({str(i): str(t) for i, t in tokens.items()}) try: info = self.request("POST", url, jsc) - data = json.loads(info.text) + data = info.json() if "token" in data and self.session: self.session.update_tokens(data) self.urls.update({"base": data["platform"]["endpoint"]}) @@ -106,19 +107,15 @@ def refresh_tokens(self, tokens={}): return self.json_return - def get_login_info(self): + def get_login_info(self) -> Dict[str, str]: """Get login properties to make the login request.""" url = self.urls["properties"] try: data = requests.get(url=url, verify=False, timeout=self.timeout) html = PyQuery(data.content) json_data = json.loads( - '{"' - + (html("script:first").text()) - .replace(",", ', "') - .replace("=", '":') - .replace("window.", "") - + "}" + f'{{"{html("script:first").text().replace(",", ", ").replace( + "=", ":").replace("window.", "")}"}}' ) login_data = {} @@ -128,37 +125,41 @@ def get_login_info(self): return login_data except (OSError, RuntimeError, ZeroDivisionError): self.error() + return {} - def get_all(self): + def get_all(self) -> Dict[str, Any]: """Build and query all endpoint.""" - json_return = {} + json_return: Dict[str, Any] = {} url = self.urls["base"] + self.urls["all"] try: info = self.request("GET", url) - json_return.update({"original": info.status_code}) - json_return.update({"parsed": info.json()}) + json_return["original"] = info.status_code + json_return["parsed"] = info.json() except (OSError, RuntimeError, ZeroDivisionError): self.error() return json_return - def get_alarm(self, home_id=None): + def get_alarm(self, home_id: Optional[str] = None) -> Dict[str, Any]: """Build and query alarm endpoint.""" if self.session is not None: home_id = self.session.config.home_id url = self.urls["base"] + self.urls["alarm"] + home_id + json_return: Dict[str, Any] = {} try: info = self.request("GET", url) - self.json_return.update({"original": info.status_code}) - self.json_return.update({"parsed": info.json()}) + json_return["original"] = info.status_code + json_return["parsed"] = info.json() except (OSError, RuntimeError, ZeroDivisionError): self.error() - return self.json_return + return json_return - def get_camera_image(self, device=None, access_token=None): + def get_camera_image( + self, device: Optional[Dict[str, Any]] = None + ) -> Dict[str, Any]: """Build and query camera endpoint.""" - json_return = {} + json_return: Dict[str, Any] = {} url = self.urls["cameraImages"].format(device["props"]["hardwareIdentifier"]) try: info = self.request("GET", url, camera=True) @@ -169,9 +170,11 @@ def get_camera_image(self, device=None, access_token=None): return json_return - def get_camera_recording(self, device=None, event_id=None): + def get_camera_recording( + self, device: Optional[Dict[str, Any]] = None, event_id: Optional[str] = None + ) -> Dict[str, Any]: """Build and query camera endpoint.""" - json_return = {} + json_return: Dict[str, Any] = {} url = self.urls["camera_recordings"].format( device["props"]["hardwareIdentifier"], event_id ) diff --git a/src/apyhiveapi/api/hive_async_api.py b/src/apyhiveapi/api/hive_async_api.py index 7b9f016..f65a583 100644 --- a/src/apyhiveapi/api/hive_async_api.py +++ b/src/apyhiveapi/api/hive_async_api.py @@ -1,5 +1,5 @@ """Hive API Module.""" -# pylint: skip-file + import json from typing import Optional @@ -10,6 +10,7 @@ from ..helper.const import HTTP_UNAUTHORIZED from ..helper.hive_exceptions import FileInUse, HiveApiError, NoApiToken +from ..session import HiveSession urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @@ -17,7 +18,11 @@ class HiveApiAsync: """Hive API Code.""" - def __init__(self, hive_session=None, websession: Optional[ClientSession] = None): + def __init__( + self, + hive_session: Optional[HiveSession] = None, + websession: Optional[ClientSession] = None, + ) -> None: """Hive API initialisation.""" self.base_url = "https://beekeeper.hivehome.com/1.0" self.camera_base_url = "prod.hcam.bgchtest.info" @@ -28,8 +33,10 @@ def __init__(self, hive_session=None, websession: Optional[ClientSession] = None "holiday_mode": f"{self.base_url}/holiday-mode", "all": f"{self.base_url}/nodes/all?products=true&devices=true&actions=true", "alarm": f"{self.base_url}/security-lite?homeId=", - "camera_images": f"https://event-history-service.{self.camera_base_url}/v1/events/cameras?latest=true&cameraId={{0}}", - "camera_recordings": f"https://event-history-service.{self.camera_base_url}/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", + "camera_images": f"https://event-history-service.{self.camera_base_url}" \ + "/v1/events/cameras?latest=true&cameraId={{0}}", + "camera_recordings": f"https://event-history-service.{self.camera_base_url}" \ + "/v1/playlist/cameras/{{0}}/events/{{1}}.m3u8", "devices": f"{self.base_url}/devices", "products": f"{self.base_url}/products", "actions": f"{self.base_url}/actions", @@ -43,7 +50,7 @@ def __init__(self, hive_session=None, websession: Optional[ClientSession] = None "parsed": "No response to Hive API request", } self.session = hive_session - self.websession = ClientSession() if websession is None else websession + self.websession = websession async def request( self, method: str, url: str, camera: bool = False, **kwargs @@ -51,25 +58,25 @@ async def request( """Make a request.""" data = kwargs.get("data", None) + headers = {} try: + token = self.session.tokens.token_data["token"] if camera: headers = { "content-type": "application/json", "Accept": "*/*", - "Authorization": f"Bearer {self.session.tokens.token_data['token']}", - "x-jwt-token": self.session.tokens.token_data["token"], + "Authorization": f"Bearer {token}", + "x-jwt-token": token, } else: headers = { "content-type": "application/json", "Accept": "*/*", - "authorization": self.session.tokens.token_data["token"], + "authorization": token, } except KeyError: - if "sso" in url: - pass - else: - raise NoApiToken + if "sso" not in url: + raise NoApiToken from None async with self.websession.request( method, url, headers=headers, data=data @@ -80,13 +87,11 @@ async def request( if resp.status == HTTP_UNAUTHORIZED: self.session.logger.error( - f"Hive token has expired when calling {url} - " - f"HTTP status is - {resp.status}" + "Hive token has expired when calling %s - HTTP status is - %d", url, resp.status ) - elif url is not None and resp.status is not None: + else: self.session.logger.error( - f"Something has gone wrong calling {url} - " - f"HTTP status is - {resp.status}" + "Something has gone wrong calling %s - HTTP status is - %d", url, resp.status ) raise HiveApiError @@ -112,32 +117,26 @@ def get_login_info(self): login_data.update({"REGION": json_data["HiveSSOPoolId"]}) return login_data - async def refresh_tokens(self): - """Refresh tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" - url = self.urls["refresh"] - if self.session is not None: - tokens = self.session.tokens.token_data - jsc = ( - "{" - + ",".join( - ('"' + str(i) + '": ' '"' + str(t) + '" ' for i, t in tokens.items()) - ) - + "}" - ) - try: - await self.request("post", url, data=jsc) - - if self.json_return["original"] == 200: - info = self.json_return["parsed"] - if "token" in info: - await self.session.update_tokens(info) - self.base_url = info["platform"]["endpoint"] - self.camera_base_url = info["platform"]["cameraPlatform"] - return True - except (ConnectionError, OSError, RuntimeError, ZeroDivisionError): - await self.error() - - return self.json_return + # async def refresh_tokens(self) -> bool: + # """Refresh tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT.""" + # url = self.urls["refresh"] + # if self.session is None: + # raise NoSessionError from None + # tokens = self.session.tokens.token_data + # jsc = json.dumps({str(i): str(t) for i, t in tokens.items()}) + # try: + # await self.request("POST", url, data=jsc) + # if self.json_return["original"] == 200: + # info = self.json_return["parsed"] + # if "token" in info: + # await self.session.update_tokens(info) + # self.base_url = info["platform"]["endpoint"] + # self.camera_base_url = info["platform"]["cameraPlatform"] + # return True + # except (ConnectionError, OSError, RuntimeError, ZeroDivisionError): + # await self.error() + + # return self.json_return async def get_all(self): """Build and query all endpoint.""" @@ -178,17 +177,17 @@ async def get_camera_image(self, device): return json_return - async def get_camera_recording(self, device, eventId): + async def get_camera_recording(self, device, event_id): """Build and query alarm endpoint.""" json_return = {} url = self.urls["camera_recordings"].format( - device["props"]["hardwareIdentifier"], eventId + device["props"]["hardwareIdentifier"], event_id ) try: resp = await self.request("get", url, True) - recUrl = await resp.text() + rec_url = await resp.text() json_return.update({"original": resp.status}) - json_return.update({"parsed": recUrl.split("\n")[3]}) + json_return.update({"parsed": rec_url.split("\n")[3]}) except (OSError, RuntimeError, ZeroDivisionError): await self.error() @@ -291,8 +290,8 @@ async def set_state(self, n_type, n_id, **kwargs): except (FileInUse, OSError, RuntimeError, ConnectionError) as e: if e.__class__.__name__ == "FileInUse": return {"original": "file"} - else: - await self.error() + + await self.error() return json_return @@ -316,8 +315,8 @@ async def set_alarm(self, **kwargs): except (FileInUse, OSError, RuntimeError, ConnectionError) as e: if e.__class__.__name__ == "FileInUse": return {"original": "file"} - else: - await self.error() + + await self.error() return json_return @@ -331,8 +330,8 @@ async def set_action(self, n_id, data): except (FileInUse, OSError, RuntimeError, ConnectionError) as e: if e.__class__.__name__ == "FileInUse": return {"original": "file"} - else: - await self.error() + + await self.error() return self.json_return diff --git a/src/apyhiveapi/api/hive_auth.py b/src/apyhiveapi/api/hive_auth.py index e4157ba..96e7abb 100644 --- a/src/apyhiveapi/api/hive_auth.py +++ b/src/apyhiveapi/api/hive_auth.py @@ -113,7 +113,7 @@ def __init__( self.use_file = bool(self.username == "use@file.com") self.file_response = {"AuthenticationResult": {"AccessToken": "file"}} self.api = HiveApi() - self.data = self.api.getLoginInfo() + self.data = self.api.get_login_info() self.__pool_id = self.data.get("UPID") self.__client_id = self.data.get("CLIID") self.__region = self.data.get("REGION").split("_")[0] diff --git a/src/apyhiveapi/api/hive_auth_async.py b/src/apyhiveapi/api/hive_auth_async.py index 33df18d..6a00f00 100644 --- a/src/apyhiveapi/api/hive_auth_async.py +++ b/src/apyhiveapi/api/hive_auth_async.py @@ -57,6 +57,7 @@ class HiveAuthAsync: SMS_MFA_CHALLENGE = "SMS_MFA" DEVICE_VERIFIER_CHALLENGE = "DEVICE_SRP_AUTH" + # pylint: disable=too-many-arguments def __init__( self, username: str, @@ -100,7 +101,7 @@ def __init__( async def async_init(self): """Initialise async variables.""" - self.data = await self.loop.run_in_executor(None, self.api.getLoginInfo) + self.data = await self.loop.run_in_executor(None, self.api.get_login_info) self.__pool_id = self.data.get("UPID") self.__client_id = self.data.get("CLIID") self.__region = self.data.get("REGION").split("_")[0] @@ -218,7 +219,7 @@ async def generate_hash_device(self, device_group_key, device_key): self.device_password = device_password return device_secret_verifier_config - async def get_device_authentication_key( + async def get_device_authentication_key( # pylint: disable=too-many-arguments self, device_group_key, device_key, device_password, server_b_value, salt ): """Get device authentication key.""" diff --git a/src/apyhiveapi/camera.py b/src/apyhiveapi/camera.py index 5fd1938..42e2c0f 100644 --- a/src/apyhiveapi/camera.py +++ b/src/apyhiveapi/camera.py @@ -1,5 +1,4 @@ """Hive Camera Module.""" -# pylint: skip-file class HiveCamera: @@ -27,17 +26,17 @@ async def get_camera_temperature(self, device: dict): return state - async def get_camera_state(self, device: dict): + async def get_camera_state(self, device: dict) -> bool: """Get the camera state. Returns: - boolean: True/False if camera is on. + bool: True/False if camera is on. """ - state = None + state = False try: data = self.session.data.devices[device["hive_id"]] - state = True if data["state"]["mode"] == "ARMED" else False + state = data["state"]["mode"] == "ARMED" except KeyError as e: await self.session.log.error(e) @@ -178,8 +177,9 @@ async def get_camera(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device diff --git a/src/apyhiveapi/device_attributes.py b/src/apyhiveapi/device_attributes.py index 3ef3397..b4a1053 100644 --- a/src/apyhiveapi/device_attributes.py +++ b/src/apyhiveapi/device_attributes.py @@ -1,5 +1,5 @@ """Hive Device Attribute Module.""" -# pylint: skip-file + from .helper.const import HIVETOHA from .helper.logger import Logger @@ -15,7 +15,7 @@ def __init__(self, session: object = None): """ self.session = session self.session.log = Logger() - self.type = "Attribute" + self.data_type = "Attribute" async def state_attributes(self, n_id: str, _type: str): """Get HA State Attributes. @@ -73,7 +73,7 @@ async def get_mode(self, n_id: str): try: data = self.session.data.products[n_id] state = data["state"]["mode"] - final = HIVETOHA[self.type].get(state, state) + final = HIVETOHA[self.data_type].get(state, state) except KeyError as e: await self.session.log.error(e) @@ -95,7 +95,7 @@ async def get_battery(self, n_id: str): data = self.session.data.devices[n_id] state = data["props"]["battery"] final = state - await self.session.log.error_check(n_id, self.type, state) + await self.session.log.error_check(n_id, state) except KeyError as e: await self.session.log.error(e) diff --git a/src/apyhiveapi/heating.py b/src/apyhiveapi/heating.py index 8b91dd0..697deba 100644 --- a/src/apyhiveapi/heating.py +++ b/src/apyhiveapi/heating.py @@ -1,7 +1,8 @@ """Hive Heating Module.""" -# pylint: skip-file -from .helper.const import HIVETOHA +from datetime import datetime + +from .helper.const import HIVETOHA class HiveHeating: """Hive Heating Code. @@ -47,7 +48,6 @@ async def get_current_temperature(self, device: dict): Returns: float: current temperature """ - from datetime import datetime f_state = None state = None @@ -364,7 +364,7 @@ async def set_boost_off(self, device: dict): await self.session.get_devices(device["hive_id"]) if await self.get_boost_status(device) == "ON": prev_mode = data["props"]["previous"]["mode"] - if prev_mode == "MANUAL" or prev_mode == "OFF": + if prev_mode in ("MANUAL", "OFF"): pre_temp = data["props"]["previous"].get("target", 7) resp = await self.session.api.set_state( data["type"], @@ -470,11 +470,11 @@ async def get_climate(self, device: dict): } self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device async def get_schedule_now_next_later(self, device: dict): """Hive get heating schedule now, next and later. @@ -516,4 +516,4 @@ async def min_max_temperature(self, device: dict): except KeyError as e: await self.session.log.error(e) - return final \ No newline at end of file + return final diff --git a/src/apyhiveapi/helper/__init__.py b/src/apyhiveapi/helper/__init__.py index f86f509..1e9a4c2 100644 --- a/src/apyhiveapi/helper/__init__.py +++ b/src/apyhiveapi/helper/__init__.py @@ -1,4 +1,4 @@ """__init__.py file.""" -# pylint: skip-file + from .hive_helper import HiveHelper # noqa: F401 from .logger import Logger # noqa: F401 diff --git a/src/apyhiveapi/helper/const.py b/src/apyhiveapi/helper/const.py index c21015f..79c25c5 100644 --- a/src/apyhiveapi/helper/const.py +++ b/src/apyhiveapi/helper/const.py @@ -1,5 +1,6 @@ -"""Constants for Pyhiveapi.""" # pylint: skip-file +"""Constants for Pyhiveapi.""" + SYNC_PACKAGE_NAME = "pyhiveapi" SYNC_PACKAGE_DIR = "/pyhiveapi/" ASYNC_PACKAGE_NAME = "apyhiveapi" diff --git a/src/apyhiveapi/helper/debugger.py b/src/apyhiveapi/helper/debugger.py index 81efd54..b7ee496 100644 --- a/src/apyhiveapi/helper/debugger.py +++ b/src/apyhiveapi/helper/debugger.py @@ -1,35 +1,45 @@ """Debugger file.""" -# pylint: skip-file + import logging +import sys class DebugContext: """Debug context to trace any function calls inside the context.""" - def __init__(self, name, enabled): + def __init__(self, name: str, enabled: bool): """Initialise debugger.""" self.name = name self.enabled = enabled - self.logging = logging.get_logger(__name__) + self.logging = logging.getLogger(__name__) self.debug_out_folder = "" self.debug_out_file = "" self.debug_enabled = False self.debug_list = [] - def __enter__(self): + def __enter__(self) -> "DebugContext": """Set trace calls on entering debugger.""" print("Entering Debug Decorated func") # Set the trace function to the trace_calls function # So all events are now traced - self.trace_calls + sys.settrace(self.trace_calls) + return self + + def __exit__(self, exc_type, exc_value, exc_traceback): + """Set trace calls on exiting debugger.""" + print("Exiting Debug Decorated func") + sys.settrace(None) def trace_calls(self, frame, event, arg): """Trace calls be made.""" # We want to only trace our call to the decorated function + if arg is not None: + pass + if event != "call": - return - elif frame.f_code.co_name != self.name: - return + return None + if frame.f_code.co_name != self.name: + return None # return the trace function to use when you go into that # function call return self.trace_lines @@ -40,6 +50,8 @@ def trace_lines(self, frame, event, arg): # keep the check for the event 'line' # If you want to print local variables only on return # check only for the 'return' event + if arg is not None: + pass if event not in ["line", "return"]: return co = frame.f_code diff --git a/src/apyhiveapi/helper/hive_exceptions.py b/src/apyhiveapi/helper/hive_exceptions.py index 67bd0ae..8f6309e 100644 --- a/src/apyhiveapi/helper/hive_exceptions.py +++ b/src/apyhiveapi/helper/hive_exceptions.py @@ -1,5 +1,5 @@ """Hive exception class.""" -# pylint: skip-file + class FileInUse(Exception): @@ -80,3 +80,10 @@ class HiveFailedToRefreshTokens(Exception): Args: Exception (object): Exception object to invoke """ + +class NoSessionError(Exception): + """No session error. + + Args: + Exception (object): Exception object to invoke + """ diff --git a/src/apyhiveapi/helper/hive_helper.py b/src/apyhiveapi/helper/hive_helper.py index b279e89..3000632 100644 --- a/src/apyhiveapi/helper/hive_helper.py +++ b/src/apyhiveapi/helper/hive_helper.py @@ -2,6 +2,8 @@ import datetime import operator +import timedelta + from .const import HIVE_TYPES @@ -109,7 +111,8 @@ def get_device_data(self, product: dict): return device - def convert_minutes_to_time(self, minutes_to_convert: str): + @staticmethod + def convert_minutes_to_time(minutes_to_convert: str) -> timedelta: """Convert minutes string to datetime. Args: @@ -125,10 +128,8 @@ def convert_minutes_to_time(self, minutes_to_convert: str): converted_time_string = converted_time.strftime("%H:%M") return converted_time_string - ## Exclude below functions from pylint checks - @staticmethod - def get_schedule_nnl(self, hive_api_schedule: list) -> dict: + def get_schedule_nnl(hive_api_schedule: list) -> dict: """Get the schedule now, next, and later of a given node's schedule. Args: @@ -166,7 +167,7 @@ def get_schedule_nnl(self, hive_api_schedule: list) -> dict: for current_slot_custom in current_day_schedule_sorted: slot_date = now + datetime.timedelta(days=day_index) - slot_time = self.convert_minutes_to_time(current_slot_custom["start"]) + slot_time = HiveHelper.convert_minutes_to_time(current_slot_custom["start"]) slot_time_date_s = f"{slot_date.strftime('%d-%m-%Y')} {slot_time}" slot_time_date_dt = datetime.datetime.strptime( slot_time_date_s, "%d-%m-%Y %H:%M" diff --git a/src/apyhiveapi/helper/hivedataclasses.py b/src/apyhiveapi/helper/hivedataclasses.py index ba6b566..c457857 100644 --- a/src/apyhiveapi/helper/hivedataclasses.py +++ b/src/apyhiveapi/helper/hivedataclasses.py @@ -1,5 +1,4 @@ """Device data class.""" -# pylint: skip-file from dataclasses import dataclass diff --git a/src/apyhiveapi/helper/logger.py b/src/apyhiveapi/helper/logger.py index 69c0180..cff56f8 100644 --- a/src/apyhiveapi/helper/logger.py +++ b/src/apyhiveapi/helper/logger.py @@ -1,5 +1,5 @@ """Custom Logging Module.""" -# pylint: skip-file + import inspect from datetime import datetime @@ -11,15 +11,17 @@ def __init__(self, session=None): """Initialise the logger class.""" self.session = session - async def error(self, e="UNKNOWN"): - """Process and unexpected error.""" + async def error(self, e: Exception = Exception("UNKNOWN")) -> None: + """Process an unexpected error.""" self.session.logger.error( - f"An unexpected error has occurred whilst" - f" executing {inspect.stack()[1][3]}" - f" with exception {e.__class__} {e}" + "An unexpected error has occurred whilst " + "executing %s with exception %s %s", + inspect.stack()[1][3], + e.__class__, + e, ) - async def error_check(self, n_id, n_type, error_type, **kwargs): + async def error_check(self, n_id: str, error_type: bool) -> None: """Error has occurred.""" message = None name = self.session.helper.get_device_name(n_id) diff --git a/src/apyhiveapi/helper/map.py b/src/apyhiveapi/helper/map.py index afcadd6..67d9816 100644 --- a/src/apyhiveapi/helper/map.py +++ b/src/apyhiveapi/helper/map.py @@ -1,5 +1,6 @@ """Dot notation for dictionary.""" -# pylint: skip-file + +from typing import Any class Map(dict): @@ -9,6 +10,30 @@ class Map(dict): dict (dict): dictionary to map. """ - __getattr__ = dict.get - __setattr__ = dict.__setitem__ - __delattr__ = dict.__delitem__ + def __getattr__(self, item: str) -> Any: + """Get item from dictionary. + + Args: + item (str): key to get. + + Returns: + Any: Value of the key. + """ + return self.get(item) # type: ignore + + def __setattr__(self, key: str, value: Any) -> None: + """Set value to dictionary. + + Args: + key (str): key to set. + value (Any): Value to set. + """ + self[key] = value + + def __delattr__(self, key: str) -> None: + """Delete item from dictionary. + + Args: + key (str): Item to delete. + """ + self.pop(key, None) diff --git a/src/apyhiveapi/hive.py b/src/apyhiveapi/hive.py index 2663696..2588fe0 100644 --- a/src/apyhiveapi/hive.py +++ b/src/apyhiveapi/hive.py @@ -1,8 +1,8 @@ """Start Hive Session.""" -# pylint: skip-file + +import os import sys import traceback -from os.path import expanduser from typing import Optional from aiohttp import ClientSession @@ -17,10 +17,10 @@ from .light import Light from .plug import Switch from .sensor import Sensor -from .session import hive_session +from .session import HiveSession debug = [] -home = expanduser("~") +home = os.path.expanduser("~") logger.add( home + "/pyhiveapi_debug.log", filter=lambda record: record["level"].name == "DEBUG" ) @@ -40,6 +40,9 @@ def exception_handler(exctype, value, tb): value ([type]): [description] tb ([type]): [description] """ + with open(os.devnull, "w", encoding="utf-8") as devnull: + print(f"{exctype.__name__}: {value}", file=devnull) + last = len(traceback.extract_tb(tb)) - 1 logger.error( f"-> \n" @@ -85,10 +88,10 @@ def trace_debug(frame, event, arg): elif event == "return": logger.debug(f"returning {arg}") - return trace_debug + return trace_debug -class Hive(hive_session): +class Hive(HiveSession): """Hive Class. Args: @@ -104,7 +107,8 @@ def __init__( """Generate a Hive session. Args: - websession (Optional[ClientSession], optional): This is a websession that can be used for the api. Defaults to None. + websession (Optional[ClientSession], optional): + This is a websession that can be used for the api. Defaults to None. username (str, optional): This is the Hive username used for login. Defaults to None. password (str, optional): This is the Hive password used for login. Defaults to None. """ @@ -123,17 +127,15 @@ def __init__( if debug: sys.settrace(trace_debug) - def set_debugging(self, debugger: list): + def set_debugging(self, debugger: list) -> None: """Set function to debug. Args: debugger (list): a list of functions to debug - - Returns: - object: Returns traceback object. """ global debug debug = debugger if debug: - return sys.settrace(trace_debug) - return sys.settrace(None) + sys.settrace(trace_debug) + else: + sys.settrace(None) diff --git a/src/apyhiveapi/hotwater.py b/src/apyhiveapi/hotwater.py index b41c56d..1ce755f 100644 --- a/src/apyhiveapi/hotwater.py +++ b/src/apyhiveapi/hotwater.py @@ -1,5 +1,5 @@ """Hive Hotwater Module.""" -# pylint: skip-file + from .helper.const import HIVETOHA @@ -247,11 +247,11 @@ async def get_water_heater(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device async def get_schedule_now_next_later(self, device: dict): """Hive get hotwater schedule now, next and later. diff --git a/src/apyhiveapi/hub.py b/src/apyhiveapi/hub.py index eee69af..dba99d2 100644 --- a/src/apyhiveapi/hub.py +++ b/src/apyhiveapi/hub.py @@ -1,5 +1,5 @@ """Hive Hub Module.""" -# pylint: skip-file + from .helper.const import HIVETOHA diff --git a/src/apyhiveapi/light.py b/src/apyhiveapi/light.py index b8a2cf2..6276437 100644 --- a/src/apyhiveapi/light.py +++ b/src/apyhiveapi/light.py @@ -1,5 +1,5 @@ """Hive Light Module.""" -# pylint: skip-file + import colorsys from .helper.const import HIVETOHA @@ -402,11 +402,11 @@ async def get_light(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device async def turn_on(self, device: dict, brightness: int, color_temp: int, color: list): """Set light to turn on. diff --git a/src/apyhiveapi/plug.py b/src/apyhiveapi/plug.py index e20c387..acdd6ae 100644 --- a/src/apyhiveapi/plug.py +++ b/src/apyhiveapi/plug.py @@ -1,5 +1,5 @@ -"""Hive Switch Module.""" -# pylint: skip-file +"""Hive Plug Module.""" + from .helper.const import HIVETOHA @@ -168,11 +168,11 @@ async def get_switch(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device async def get_switch_state(self, device: dict): """Home Assistant wrapper to get updated switch state. @@ -185,8 +185,8 @@ async def get_switch_state(self, device: dict): """ if device["hive_type"] == "Heating_Heat_On_Demand": return await self.session.heating.get_heat_on_demand(device) - else: - return await self.get_state(device) + + return await self.get_state(device) async def turn_on(self, device: dict): """Home Assisatnt wrapper for turning switch on. @@ -199,8 +199,8 @@ async def turn_on(self, device: dict): """ if device["hive_type"] == "Heating_Heat_On_Demand": return await self.session.heating.set_heat_on_demand(device, "ENABLED") - else: - return await self.set_status_on(device) + + return await self.set_status_on(device) async def turn_off(self, device: dict): """Home Assisatnt wrapper for turning switch off. @@ -213,5 +213,5 @@ async def turn_off(self, device: dict): """ if device["hive_type"] == "Heating_Heat_On_Demand": return await self.session.heating.set_heat_on_demand(device, "DISABLED") - else: - return await self.set_status_off(device) + + return await self.set_status_off(device) diff --git a/src/apyhiveapi/sensor.py b/src/apyhiveapi/sensor.py index 181c4d5..9c901d6 100644 --- a/src/apyhiveapi/sensor.py +++ b/src/apyhiveapi/sensor.py @@ -1,7 +1,6 @@ """Hive Sensor Module.""" -# pylint: skip-file -from .helper.const import HIVE_TYPES, HIVETOHA +from .helper.const import HIVE_TYPES, HIVETOHA class HiveSensor: """Hive Sensor Code.""" @@ -132,8 +131,8 @@ async def get_sensor(self, device: dict): self.session.devices.update({device["hive_id"]: dev_data}) return self.session.devices[device["hive_id"]] - else: - await self.session.log.error_check( - device["device_id"], "ERROR", device["device_data"]["online"] - ) - return device + + await self.session.log.error_check( + device["device_id"], device["device_data"]["online"] + ) + return device diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index 177cb10..0e47531 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -1,14 +1,16 @@ """Hive Session Module.""" -# pylint: skip-file + import asyncio import copy +from datetime import datetime, timedelta import json import operator import os import time -from datetime import datetime, timedelta +from typing import Optional from aiohttp.web import HTTPException + from apyhiveapi import API, Auth from .device_attributes import HiveAttributes @@ -29,7 +31,7 @@ from .helper.map import Map -class hive_session: +class HiveSession: """Hive Session Code. Raises: @@ -113,7 +115,7 @@ def open_file(self, file: str): """ path = os.path.dirname(os.path.realpath(__file__)) + "/data/" + file path = path.replace("/pyhiveapi/", "/apyhiveapi/") - with open(path) as j: + with open(path, encoding="utf-8") as j: data = json.loads(j.read()) return data @@ -154,7 +156,7 @@ def add_list(self, entity_type: str, data: dict, **kwargs: dict): else: formatted_data["ha_name"] = device_name formatted_data.update(kwargs) - self.deviceList[entityType].append(formatted_data) + self.device_list[entity_type].append(formatted_data) return formatted_data except KeyError as error: self.logger.error(error) @@ -171,18 +173,17 @@ async def update_interval(self, new_interval: timedelta): interval = new_interval if interval < timedelta(seconds=15): - interval = timedelta(seconds=15) + interval = max(interval, timedelta(seconds=15)) self.config.scan_interval = interval - async def use_file(self, username: str = None): + async def use_file(self, username: Optional[str] = None) -> None: """Update to check if file is being used. Args: - username (str, optional): Looks for use@file.com. Defaults to None. + username (Optional[str], optional): Looks for use@file.com. Defaults to None. """ - using_file = True if username == "use@file.com" else False - if using_file: - self.config.file = True + using_file = username == "use@file.com" + self.config.file = using_file async def update_tokens(self, tokens: dict, update_expiry_time: bool = True): """Update session tokens. @@ -280,8 +281,8 @@ async def device_login(self): try: result = await self.auth.device_login() - except HiveInvalidDeviceAuthentication: - raise HiveInvalidDeviceAuthentication + except HiveInvalidDeviceAuthentication as exc: + raise HiveInvalidDeviceAuthentication from exc if "AuthenticationResult" in result: await self.update_tokens(result) @@ -298,26 +299,23 @@ async def hive_refresh_tokens(self): if self.config.file: return None - else: - expiry_time = self.tokens.token_created + self.tokens.token_expiry - if datetime.now() >= expiry_time: - result = await self.auth.refresh_token( - self.tokens.token_data["refresh_token"] - ) - if "AuthenticationResult" in result: - await self.update_tokens(result) - else: - raise HiveFailedToRefreshTokens + expiry_time = self.tokens.token_created + self.tokens.token_expiry + if datetime.now() >= expiry_time: + result = await self.auth.refresh_token( + self.tokens.token_data["refresh_token"] + ) + + if "AuthenticationResult" in result: + await self.update_tokens(result) + else: + raise HiveFailedToRefreshTokens return result - async def update_data(self, device: dict): + async def update_data(self): """Get latest data for Hive nodes - rate limiting. - Args: - device (dict): Device requesting the update. - Returns: boolean: True/False if update was successful """ @@ -326,7 +324,7 @@ async def update_data(self, device: dict): if datetime.now() >= ep and not self.update_lock.locked(): try: await self.update_lock.acquire() - await self.get_devices(device["hive_id"]) + await self.get_devices() if len(self.device_list["camera"]) > 0: for camera in self.data.camera: await self.get_camera(self.devices[camera]) @@ -349,7 +347,7 @@ async def get_alarm(self): api_resp_d = await self.api.get_alarm() if operator.contains(str(api_resp_d["original"]), "20") is False: raise HTTPException - elif api_resp_d["parsed"] is None: + if api_resp_d["parsed"] is None: raise HiveApiError self.data.alarm = api_resp_d["parsed"] @@ -361,44 +359,63 @@ async def get_camera(self, device): HTTPException: HTTP error has occurred updating the devices. HiveApiError: An API error code has been returned. """ - camera_image = None - camera_recording = None - has_camera_image = False - has_camera_recording = False + camera_info = { + "camera_image": {}, + "camera_recording": {}, + "has_camera_image": False, + "has_camera_recording": False, + } if self.config.file: - camera_image = self.open_file("camera.json") - camera_recording = self.open_file("camera.json") + camera_info["camera_image"] = self.open_file("camera.json") + camera_info["camera_recording"] = self.open_file("camera.json") elif self.tokens is not None: - camera_image = await self.api.get_camera_image(device) - has_camera_recording = bool( - camera_image["parsed"]["events"][0]["hasRecording"] + camera_info["camera_image"] = await self.api.get_camera_image(device) + camera_info["has_camera_image"] = bool( + camera_info["camera_image"]["parsed"]["events"][0]["hasRecording"] ) - if has_camera_recording: - camera_recording = await self.api.get_camera_recording( - device, camera_image["parsed"]["events"][0]["eventId"] + if camera_info["has_camera_image"]: + camera_info["camera_recording"] = await self.api.get_camera_recording( + device, + camera_info["camera_image"]["parsed"]["events"][0]["eventId"], + ) + camera_info["has_camera_recording"] = bool( + camera_info["camera_recording"]["parsed"]["events"][0][ + "hasRecording" + ] ) - if operator.contains(str(camera_image["original"]), "20") is False: + if ( + operator.contains(str(camera_info["camera_image"]["original"]), "20") + is False + ): raise HTTPException - elif camera_image["parsed"] is None: + if camera_info["camera_image"]["parsed"] is None: raise HiveApiError else: raise NoApiToken - has_camera_image = bool(camera_image["parsed"]["events"][0]) - + camera_info["has_camera_image"] = bool( + camera_info["camera_image"]["parsed"]["events"][0] + ) self.data.camera[device["id"]] = {} self.data.camera[device["id"]]["camera_image"] = None self.data.camera[device["id"]]["camera_recording"] = None - if camera_image is not None and has_camera_image: - self.data.camera[device["id"]]["camera_image"] = camera_image["parsed"][ - "events" - ][0] - if camera_recording is not None and has_camera_recording: - self.data.camera[device["id"]]["camera_recording"] = camera_recording - + if camera_info["camera_image"] is not None and camera_info["has_camera_image"]: + self.data.camera[device["id"]]["camera_image"] = camera_info[ + "camera_image" + ]["parsed"]["events"][0] + if ( + camera_info["camera_recording"] is not None + and camera_info["has_camera_recording"] + ): + self.data.camera[device["id"]]["camera_recording"] = camera_info[ + "camera_recording" + ]["parsed"]["events"][0] + + async def get_devices(self): + """Get node data.""" get_nodes_successful = False api_resp_d = None @@ -407,11 +424,12 @@ async def get_camera(self, device): api_resp_d = self.open_file("data.json") elif self.tokens is not None: await self.hive_refresh_tokens() - api_resp_d = await self.api.get_all() - if operator.contains(str(api_resp_d["original"]), "20") is False: - raise HTTPException - elif api_resp_d["parsed"] is None: - raise HiveApiError + await self.hive_refresh_tokens() + api_resp_d = await self.api.get_all() + if operator.contains(str(api_resp_d["original"]), "20") is False: + raise HTTPException + if api_resp_d["parsed"] is None: + raise HiveApiError api_resp_p = api_resp_d["parsed"] temp_products = {} @@ -447,12 +465,18 @@ async def get_camera(self, device): await self.get_alarm() self.config.last_update = datetime.now() get_nodes_successful = True - except (OSError, RuntimeError, HiveApiError, ConnectionError, HTTPException): + except ( + OSError, + RuntimeError, + HiveApiError, + ConnectionError, + HTTPException, + ): get_nodes_successful = False return get_nodes_successful - async def start_session(self, config: dict = {}): + async def start_session(self, config: dict = None): """Setup the Hive platform. Args: @@ -483,7 +507,7 @@ async def start_session(self, config: dict = {}): raise HiveUnknownConfiguration try: - await self.get_devices("No_ID") + await self.get_devices() except HTTPException: return HTTPException @@ -518,14 +542,13 @@ async def create_devices(self): and self.data.products[a_product]["type"] not in HIVE_TYPES["Heating"] ): continue - product_list = PRODUCTS.get(self.data.products[aProduct]["type"], []) - product_name = self.data.products[aProduct]["state"].get("name", "Unknown") + product_list = PRODUCTS.get(self.data.products[a_product]["type"], []) + product_name = self.data.products[a_product]["state"].get("name", "Unknown") for code in product_list: try: eval("self." + code) except (NameError, AttributeError) as e: self.logger.warning(f"Device {product_name} cannot be setup - {e}") - pass if self.data.products[a_product]["type"] in hive_type: self.config.mode.append(p["id"]) @@ -542,7 +565,8 @@ async def create_devices(self): if "action" in HIVE_TYPES["Switch"]: for action in self.data["actions"]: - a = self.data["actions"][action] # noqa: F841 + a = self.data["actions"][action] + type(a) eval("self." + ACTIONS) return self.device_list @@ -563,6 +587,8 @@ def epoch_time(date_time: any, pattern: str, action: str): pattern = "%d.%m.%Y %H:%M:%S" epoch_time = int(time.mktime(time.strptime(str(date_time), pattern))) return epoch_time - elif action == "from_epoch": + if action == "from_epoch": date = datetime.fromtimestamp(int(date_time)).strftime(pattern) - return date \ No newline at end of file + return date + + return None diff --git a/tests/common.py b/tests/common.py index 10a5e35..c9c636f 100644 --- a/tests/common.py +++ b/tests/common.py @@ -1,5 +1,5 @@ """Test the helper method for writing tests.""" -# pylint: skip-file + from dataclasses import dataclass From 7609e0519d6ec577fcab5a124341efb34576515c Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Fri, 14 Feb 2025 23:27:35 +0000 Subject: [PATCH 25/26] update dev code --- setup.cfg | 2 + setup.py | 7 +- src/apyhiveapi/api/hive_async_api.py | 4 +- src/apyhiveapi/plug.py | 2 +- src/apyhiveapi/session.py | 26 ++++--- tests/apyhiveapi/__init__.py | 1 - .../{test_hub.py => test_async_hub.py} | 0 .../{test_plug.py => test_async_plug.py} | 4 +- ...{test_session.py => test_async_session.py} | 0 tests/apyhiveapi/test_async_switch.py | 77 +++++++++++++++++++ tests/common.py | 4 +- tests/pyhiveapi/__init__.py | 1 - .../{test_hub.py => test_sync_hub.py} | 0 .../{test_plug.py => test_sync_plug.py} | 4 +- .../{test_session.py => test_sync_session.py} | 0 15 files changed, 108 insertions(+), 24 deletions(-) delete mode 100644 tests/apyhiveapi/__init__.py rename tests/apyhiveapi/{test_hub.py => test_async_hub.py} (100%) rename tests/apyhiveapi/{test_plug.py => test_async_plug.py} (97%) rename tests/apyhiveapi/{test_session.py => test_async_session.py} (100%) create mode 100644 tests/apyhiveapi/test_async_switch.py delete mode 100644 tests/pyhiveapi/__init__.py rename tests/pyhiveapi/{test_hub.py => test_sync_hub.py} (100%) rename tests/pyhiveapi/{test_plug.py => test_sync_plug.py} (97%) rename tests/pyhiveapi/{test_session.py => test_sync_session.py} (100%) diff --git a/setup.cfg b/setup.cfg index 0a2a9cf..4ad4efb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,6 +17,8 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 [options] diff --git a/setup.py b/setup.py index 7a59212..bb4f2b1 100644 --- a/setup.py +++ b/setup.py @@ -23,15 +23,16 @@ def requirements_from_file(filename="requirements_all.txt"): "build_py": unasync.cmdclass_build_py( rules=[ unasync.Rule( - "/apyhiveapi/", - "/pyhiveapi/", + "/src/apyhiveapi/", + " + /pyhiveapi/", additional_replacements={ "apyhiveapi": "pyhiveapi", "asyncio": "threading", }, ), unasync.Rule( - "/apyhiveapi/api/", + "/src/apyhiveapi/api/", "/pyhiveapi/api/", additional_replacements={ "apyhiveapi": "pyhiveapi", diff --git a/src/apyhiveapi/api/hive_async_api.py b/src/apyhiveapi/api/hive_async_api.py index f65a583..a5655e8 100644 --- a/src/apyhiveapi/api/hive_async_api.py +++ b/src/apyhiveapi/api/hive_async_api.py @@ -10,7 +10,7 @@ from ..helper.const import HTTP_UNAUTHORIZED from ..helper.hive_exceptions import FileInUse, HiveApiError, NoApiToken -from ..session import HiveSession +##from ..session import HiveSession urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @@ -20,7 +20,7 @@ class HiveApiAsync: def __init__( self, - hive_session: Optional[HiveSession] = None, + hive_session = None, websession: Optional[ClientSession] = None, ) -> None: """Hive API initialisation.""" diff --git a/src/apyhiveapi/plug.py b/src/apyhiveapi/plug.py index acdd6ae..81f04ad 100644 --- a/src/apyhiveapi/plug.py +++ b/src/apyhiveapi/plug.py @@ -183,7 +183,7 @@ async def get_switch_state(self, device: dict): Returns: boolean: Return True or False for the state. """ - if device["hive_type"] == "Heating_Heat_On_Demand": + if device["hive_type"] == "heating_heat_on_demand": return await self.session.heating.get_heat_on_demand(device) return await self.get_state(device) diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index 0e47531..69b1bad 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -11,7 +11,13 @@ from aiohttp.web import HTTPException -from apyhiveapi import API, Auth + +if __name__ == "pyhiveapi": + from .api.hive_api import HiveApi as API + from .api.hive_auth import HiveAuth as Auth +else: + from .api.hive_async_api import HiveApiAsync as API + from .api.hive_auth_async import HiveAuthAsync as Auth from .device_attributes import HiveAttributes from .helper.const import ACTIONS, DEVICES, HIVE_TYPES, PRODUCTS @@ -113,7 +119,7 @@ def open_file(self, file: str): Returns: dict: Data from the chosen file. """ - path = os.path.dirname(os.path.realpath(__file__)) + "/data/" + file + path = os.path.dirname(os.path.realpath(__file__)) + "/test_data/" + file path = path.replace("/pyhiveapi/", "/apyhiveapi/") with open(path, encoding="utf-8") as j: data = json.loads(j.read()) @@ -131,7 +137,7 @@ def add_list(self, entity_type: str, data: dict, **kwargs: dict): dict: Entity. """ try: - device = self.helper.getDeviceData(data) + device = self.helper.get_device_data(data) device_name = ( device["state"]["name"] if device["state"]["name"] != "Receiver" @@ -424,12 +430,11 @@ async def get_devices(self): api_resp_d = self.open_file("data.json") elif self.tokens is not None: await self.hive_refresh_tokens() - await self.hive_refresh_tokens() - api_resp_d = await self.api.get_all() - if operator.contains(str(api_resp_d["original"]), "20") is False: - raise HTTPException - if api_resp_d["parsed"] is None: - raise HiveApiError + api_resp_d = await self.api.get_all() + if operator.contains(str(api_resp_d["original"]), "20") is False: + raise HTTPException + if api_resp_d["parsed"] is None: + raise HiveApiError api_resp_p = api_resp_d["parsed"] temp_products = {} @@ -547,8 +552,9 @@ async def create_devices(self): for code in product_list: try: eval("self." + code) - except (NameError, AttributeError) as e: + except (NameError, AttributeError, KeyError) as e: self.logger.warning(f"Device {product_name} cannot be setup - {e}") + pass if self.data.products[a_product]["type"] in hive_type: self.config.mode.append(p["id"]) diff --git a/tests/apyhiveapi/__init__.py b/tests/apyhiveapi/__init__.py deleted file mode 100644 index cf2ff68..0000000 --- a/tests/apyhiveapi/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Apyhiveapi tests.""" diff --git a/tests/apyhiveapi/test_hub.py b/tests/apyhiveapi/test_async_hub.py similarity index 100% rename from tests/apyhiveapi/test_hub.py rename to tests/apyhiveapi/test_async_hub.py diff --git a/tests/apyhiveapi/test_plug.py b/tests/apyhiveapi/test_async_plug.py similarity index 97% rename from tests/apyhiveapi/test_plug.py rename to tests/apyhiveapi/test_async_plug.py index 50336c1..9781c6d 100644 --- a/tests/apyhiveapi/test_plug.py +++ b/tests/apyhiveapi/test_async_plug.py @@ -39,7 +39,7 @@ async def test_switch_get_plug_state(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][1] - state = await hive_session.switch.get_switchState(switch) + state = await hive_session.switch.get_switch_state(switch) assert state in (True, False) @@ -64,7 +64,7 @@ async def test_switch_get_heat_on_demand_state(): await hive.async_start_session() hive_session = hive.async_hive switch = hive_session.session.device_list["switch"][0] - state = await hive_session.switch.get_switchState(switch) + state = await hive_session.switch.get_switch_state(switch) assert state in (True, False) diff --git a/tests/apyhiveapi/test_session.py b/tests/apyhiveapi/test_async_session.py similarity index 100% rename from tests/apyhiveapi/test_session.py rename to tests/apyhiveapi/test_async_session.py diff --git a/tests/apyhiveapi/test_async_switch.py b/tests/apyhiveapi/test_async_switch.py new file mode 100644 index 0000000..66a8773 --- /dev/null +++ b/tests/apyhiveapi/test_async_switch.py @@ -0,0 +1,77 @@ +import pytest +from unittest.mock import AsyncMock, MagicMock +from src.apyhiveapi.plug import Switch +from tests.common import MockSession + +@pytest.fixture +async def session(): + session = MockSession() + hive = await session.async_start_session() + return hive + + +@pytest.mark.asyncio +async def test_session_initialised(session): + assert session is not None + +@pytest.mark.asyncio +async def test_get_switch_happy_path(session): + device = {"device_id": "123", "device_data": {"online": True}, "hive_type": "activeplug"} + session.attr.online_offline = AsyncMock(return_value=True) + session.helper.device_recovered = MagicMock() + session.data.devices = {"123": {"props": "props_data", "parent": "parent_data"}} + session.attr.state_attributes = AsyncMock(return_value={"attr": "value"}) + session.switch.get_switch_state = AsyncMock(return_value="on") + session.switch.get_power_usage = AsyncMock(return_value="100W") + + result = await session.switch.get_switch(device) + + assert result["status"]["state"] == "on" + assert result["status"]["power_usage"] == "100W" + assert result["attributes"] == {"attr": "value"} + +@pytest.mark.asyncio +async def test_get_switch_unhappy_path(switch): + device = {"device_id": "123", "device_data": {"online": False}, "hive_type": "activeplug"} + switch.session.attr.online_offline = AsyncMock(return_value=False) + switch.session.log.error_check = AsyncMock() + + result = await switch.get_switch(device) + + assert result == device + +@pytest.mark.asyncio +async def test_turn_on_happy_path(switch): + device = {"hive_type": "activeplug"} + switch.set_status_on = AsyncMock(return_value="on") + + result = await switch.turn_on(device) + + assert result == "on" + +@pytest.mark.asyncio +async def test_turn_off_happy_path(switch): + device = {"hive_type": "activeplug"} + switch.set_status_off = AsyncMock(return_value="off") + + result = await switch.turn_off(device) + + assert result == "off" + +@pytest.mark.asyncio +async def test_turn_on_unhappy_path(switch): + device = {"hive_type": "Heating_Heat_On_Demand"} + switch.session.heating.set_heat_on_demand = AsyncMock(return_value="ENABLED") + + result = await switch.turn_on(device) + + assert result == "ENABLED" + +@pytest.mark.asyncio +async def test_turn_off_unhappy_path(switch): + device = {"hive_type": "Heating_Heat_On_Demand"} + switch.session.heating.set_heat_on_demand = AsyncMock(return_value="DISABLED") + + result = await switch.turn_off(device) + + assert result == "DISABLED" \ No newline at end of file diff --git a/tests/common.py b/tests/common.py index c9c636f..7e95be1 100644 --- a/tests/common.py +++ b/tests/common.py @@ -5,7 +5,6 @@ from apyhiveapi import Hive as HiveAsync -from pyhiveapi import Hive as HiveSync USERNAME = "use@file.com" PASSWORD = "Test12345" @@ -54,4 +53,5 @@ def sync_start_session(self): async def async_start_session(self): """Start a async session.""" self.async_hive = HiveAsync(username=USERNAME, password=PASSWORD) - return await self.async_hive.start_session(TEMP_CONFIG) + await self.async_hive.start_session(TEMP_CONFIG) + return self.async_hive diff --git a/tests/pyhiveapi/__init__.py b/tests/pyhiveapi/__init__.py deleted file mode 100644 index e84ef15..0000000 --- a/tests/pyhiveapi/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for library.""" diff --git a/tests/pyhiveapi/test_hub.py b/tests/pyhiveapi/test_sync_hub.py similarity index 100% rename from tests/pyhiveapi/test_hub.py rename to tests/pyhiveapi/test_sync_hub.py diff --git a/tests/pyhiveapi/test_plug.py b/tests/pyhiveapi/test_sync_plug.py similarity index 97% rename from tests/pyhiveapi/test_plug.py rename to tests/pyhiveapi/test_sync_plug.py index c8bad09..faf0528 100644 --- a/tests/pyhiveapi/test_plug.py +++ b/tests/pyhiveapi/test_sync_plug.py @@ -34,7 +34,7 @@ def test_switch_get_plug_state(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][1] - state = hive_session.switch.get_switchState(switch) + state = hive_session.switch.get_switch_state(switch) assert state in (True, False) @@ -57,7 +57,7 @@ def test_switch_get_heat_on_demand_state(): hive.sync_start_session() hive_session = hive.sync_hive switch = hive_session.session.device_list["switch"][0] - state = hive_session.switch.get_switchState(switch) + state = hive_session.switch.get_switch_state(switch) assert state in (True, False) diff --git a/tests/pyhiveapi/test_session.py b/tests/pyhiveapi/test_sync_session.py similarity index 100% rename from tests/pyhiveapi/test_session.py rename to tests/pyhiveapi/test_sync_session.py From a618f231b0ea1561aea26c7315d52f5723fadffd Mon Sep 17 00:00:00 2001 From: Khole Jones Date: Sun, 28 Sep 2025 16:37:44 +0100 Subject: [PATCH 26/26] Add parent device to new devicelist --- .pre-commit-config.yaml | 25 +++++++++---------- setup.py | 7 +++--- src/apyhiveapi/api/hive_auth_async.py | 7 ++++++ src/apyhiveapi/session.py | 35 +++++++++++++++------------ 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cdacb76..51a0a50 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,18 +1,18 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.34.0 + rev: v3.20.0 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 25.9.0 hooks: - id: black args: - --safe - --quiet - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.4.1 hooks: - id: codespell args: @@ -21,14 +21,14 @@ repos: - --quiet-level=2 exclude_types: [csv, json] - repo: https://github.com/pycqa/flake8 - rev: 3.9.2 + rev: 7.3.0 hooks: - id: flake8 additional_dependencies: - flake8-docstrings==1.5.0 - pydocstyle==5.1.1 - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.8.6 hooks: - id: bandit args: @@ -36,21 +36,21 @@ repos: - --format=custom - --configfile=tests/bandit.yaml - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 6.0.1 hooks: - id: isort args: ["--profile", "black"] - repo: https://github.com/adrienverge/yamllint.git - rev: v1.26.3 + rev: v1.37.1 hooks: - id: yamllint - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.7.1 + rev: v4.0.0-alpha.8 hooks: - id: prettier stages: [manual] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v6.0.0 hooks: - id: check-executables-have-shebangs stages: [manual] @@ -59,13 +59,10 @@ repos: - id: no-commit-to-branch args: - --branch=master - - repo: local + - repo: https://github.com/pycqa/pylint + rev: v3.3.1 hooks: - id: pylint - name: pylint - entry: pylint - language: system - types: [python] args: [ "-rn", # Only display messages diff --git a/setup.py b/setup.py index bb4f2b1..17e7f1c 100644 --- a/setup.py +++ b/setup.py @@ -9,14 +9,14 @@ def requirements_from_file(filename="requirements_all.txt"): """Get requirements from file.""" - with open(os.path.join(os.path.dirname(__file__), filename)) as r: + with open(os.path.join(os.path.dirname(__file__), filename), encoding="utf-8") as r: reqs = r.read().strip().split("\n") # Return non empty lines and non comments return [r for r in reqs if re.match(r"^\w+", r)] setup( - version="1.0.1", + version="1.0.4", package_data={"data": ["*.json"]}, include_package_data=True, cmdclass={ @@ -24,8 +24,7 @@ def requirements_from_file(filename="requirements_all.txt"): rules=[ unasync.Rule( "/src/apyhiveapi/", - " - /pyhiveapi/", + "/pyhiveapi/", additional_replacements={ "apyhiveapi": "pyhiveapi", "asyncio": "threading", diff --git a/src/apyhiveapi/api/hive_auth_async.py b/src/apyhiveapi/api/hive_auth_async.py index 6a00f00..0645b0b 100644 --- a/src/apyhiveapi/api/hive_auth_async.py +++ b/src/apyhiveapi/api/hive_auth_async.py @@ -17,6 +17,7 @@ from ..helper.hive_exceptions import ( HiveApiError, + HiveFailedToRefreshTokens, HiveInvalid2FACode, HiveInvalidDeviceAuthentication, HiveInvalidPassword, @@ -560,6 +561,12 @@ async def refresh_token(self, token): "NotAuthorizedException", "CodeMismatchException", ): + error_message = err.response.get("Error", {}).get("Message", "") + if any( + msg in error_message + for msg in ["Refresh Token has expired", "Invalid Refresh Token"] + ): + raise HiveFailedToRefreshTokens from err raise HiveInvalid2FACode from err except botocore.exceptions.EndpointConnectionError as err: if err.__class__.__name__ == "EndpointConnectionError": diff --git a/src/apyhiveapi/session.py b/src/apyhiveapi/session.py index 69b1bad..9b243b3 100644 --- a/src/apyhiveapi/session.py +++ b/src/apyhiveapi/session.py @@ -2,23 +2,15 @@ import asyncio import copy -from datetime import datetime, timedelta import json import operator import os import time +from datetime import datetime, timedelta from typing import Optional from aiohttp.web import HTTPException - -if __name__ == "pyhiveapi": - from .api.hive_api import HiveApi as API - from .api.hive_auth import HiveAuth as Auth -else: - from .api.hive_async_api import HiveApiAsync as API - from .api.hive_auth_async import HiveAuthAsync as Auth - from .device_attributes import HiveAttributes from .helper.const import ACTIONS, DEVICES, HIVE_TYPES, PRODUCTS from .helper.hive_exceptions import ( @@ -36,6 +28,13 @@ from .helper.logger import Logger from .helper.map import Map +if __name__ == "pyhiveapi": + from .api.hive_api import HiveApi as API + from .api.hive_auth import HiveAuth as Auth +else: + from .api.hive_async_api import HiveApiAsync as API + from .api.hive_auth_async import HiveAuthAsync as Auth + class HiveSession: """Hive Session Code. @@ -160,12 +159,18 @@ def add_list(self, entity_type: str, data: dict, **kwargs: dict): if kwargs.get("ha_name", "FALSE")[0] == " ": kwargs["ha_name"] = device_name + kwargs["ha_name"] else: - formatted_data["ha_name"] = device_name + formatted_data["haName"] = device_name + formatted_data.update(kwargs) - self.device_list[entity_type].append(formatted_data) + + if data.get("type", "") == "hub": + self.device_list["parent"].append(formatted_data) + else: + self.device_list[entity_type].append(formatted_data) + return formatted_data except KeyError as error: - self.logger.error(error) + self.log.error(error) return None async def update_interval(self, new_interval: timedelta): @@ -488,7 +493,7 @@ async def start_session(self, config: dict = None): config (dict, optional): Configuration for Home Assistant to use. Defaults to {}. Raises: - HiveUnknownConfiguration: Unknown configuration identifed. + HiveUnknownConfiguration: Unknown configuration identified. HiveReauthRequired: Tokens have expired and reauthentication is required. Returns: @@ -527,6 +532,7 @@ async def create_devices(self): Returns: list: List of devices """ + self.device_list["parent"] = [] self.device_list["alarm_control_panel"] = [] self.device_list["binary_sensor"] = [] self.device_list["camera"] = [] @@ -553,8 +559,7 @@ async def create_devices(self): try: eval("self." + code) except (NameError, AttributeError, KeyError) as e: - self.logger.warning(f"Device {product_name} cannot be setup - {e}") - pass + self.log.warning(f"Device {product_name} cannot be setup - {e}") if self.data.products[a_product]["type"] in hive_type: self.config.mode.append(p["id"])