From bba8b74f5ce96e976c4b1b98fc1b6b875a4f89eb Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:34:08 -0600 Subject: [PATCH 01/22] Update TODO.md --- TODO.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index d6cc75fe..960b638b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,14 @@ -# Todo +#TODOs (A checklist of sorts) -## Features -- [ ] Add caching to Entity.get_state (to make it fetch state automatically) +## Code Features +- [ ] Add Testing Suite/Workflow the runs Home Assistant Core to test library. +- [ ] Clean up Model `repr` methods with disabling model field `repr`s. -- [X] Create AsyncClient for integration in async applications and libraries +## Code Bugs +None yet? -- [X] Add if statements to all Client methods that call malformed_id and raise MalformedInputError if true. +## Maintainence +- [ ] Initialize project Milestones and Wiki -## Documentation \ No newline at end of file +## Documentation +- [ ] Add runnable Code Examples From 544e65764b9bfe831cfe42a71fb03f9d7788a897 Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:34:20 -0600 Subject: [PATCH 02/22] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 960b638b..c5271e95 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,4 @@ -#TODOs (A checklist of sorts) +# TODOs (A checklist of sorts) ## Code Features - [ ] Add Testing Suite/Workflow the runs Home Assistant Core to test library. From 011fc382066d1f28d4c22441412a90f90391b949 Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:36:47 -0600 Subject: [PATCH 03/22] Update TODO.md --- TODO.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index c5271e95..a45fe858 100644 --- a/TODO.md +++ b/TODO.md @@ -8,7 +8,9 @@ None yet? ## Maintainence -- [ ] Initialize project Milestones and Wiki +- [ ] Initialize project Milestones and Wiki. +- [ ] Add Workflow that issues labeled as `bug` to Code Bugs in TODO.md. ## Documentation -- [ ] Add runnable Code Examples +- [ ] Add runnable Code Examples. +- [ ] Document project scripts. From 6a47208c6950213facd5b2ad7afa7271415dee96 Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:38:48 -0600 Subject: [PATCH 04/22] Update TODO.md --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index a45fe858..45cd5893 100644 --- a/TODO.md +++ b/TODO.md @@ -14,3 +14,4 @@ None yet? ## Documentation - [ ] Add runnable Code Examples. - [ ] Document project scripts. +- [ ] Document branch naming scheme (i.e. `feature/`, `maintainence/`, `bug/`, `docs/`) From b3bac9dbff4059566237f214143a9b3e612b03bd Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:39:16 -0600 Subject: [PATCH 05/22] Update TODO.md --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 45cd5893..e62944c0 100644 --- a/TODO.md +++ b/TODO.md @@ -10,6 +10,7 @@ None yet? ## Maintainence - [ ] Initialize project Milestones and Wiki. - [ ] Add Workflow that issues labeled as `bug` to Code Bugs in TODO.md. +- [ ] Fix workflows to only run when python paths are modified. ## Documentation - [ ] Add runnable Code Examples. From 4f67f8f570f540735d020105a161ed9ff1aa529d Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:54:08 -0600 Subject: [PATCH 06/22] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 028c1c90..d4a27928 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![GitHub release (latest by date)](https://img.shields.io/github/v/release/GrandMoff100/HomeassistantAPI?style=for-the-badge) ![GitHub release (latest by date)](https://img.shields.io/github/downloads/GrandMoff100/HomeassistantAPI/latest/total?style=for-the-badge) -![Home AssistantLogo](https://github.com/GrandMoff100/HomeAssistantAPI/blob/7edb4e6298d37bda19c08b807613c6d351788491/docs/images/homeassistant-logo.png?raw=true) +![Home Assistant Logo](https://github.com/GrandMoff100/HomeAssistantAPI/blob/7edb4e6298d37bda19c08b807613c6d351788491/docs/images/homeassistant-logo.png?raw=true) Python Wrapper for Homeassistant's [REST API](https://developers.home-assistant.io/docs/api/rest/) From d52f8ea8aaeb5c048926a96a07904cc183c4c6f1 Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 21 Feb 2022 23:56:05 -0600 Subject: [PATCH 07/22] Update TODO.md --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index e62944c0..6151b530 100644 --- a/TODO.md +++ b/TODO.md @@ -9,7 +9,7 @@ None yet? ## Maintainence - [ ] Initialize project Milestones and Wiki. -- [ ] Add Workflow that issues labeled as `bug` to Code Bugs in TODO.md. +- [ ] Add Workflow that issues labeled `bug` and `feature` into their respective sections in TODO.md. - [ ] Fix workflows to only run when python paths are modified. ## Documentation From 9e5948cc3bc89143fb6c67cfc1a982c83d8997d5 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 04:22:05 +0000 Subject: [PATCH 08/22] Exclude model client attribute for export and repr --- homeassistant_api/_async/models/entity.py | 4 +++- homeassistant_api/_async/models/events.py | 4 +++- homeassistant_api/models/domains.py | 4 +++- homeassistant_api/models/entity.py | 4 +++- homeassistant_api/models/events.py | 4 +++- homeassistant_api/processing.py | 4 ++-- homeassistant_api/rawapi.py | 5 +++-- 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/homeassistant_api/_async/models/entity.py b/homeassistant_api/_async/models/entity.py index f5db913d..2a3e76ff 100644 --- a/homeassistant_api/_async/models/entity.py +++ b/homeassistant_api/_async/models/entity.py @@ -2,6 +2,8 @@ from os.path import join from typing import TYPE_CHECKING, Any, Dict, Optional, cast +from pydantic import Field + from ...models import BaseModel, History, State if TYPE_CHECKING: @@ -12,7 +14,7 @@ class AsyncGroup(BaseModel): """Represents the groups that entities belong to""" group_id: str - client: "Client" + client: "Client" = Field(exclude=True, repr=False) entities: Dict[str, "AsyncEntity"] = {} def add_entity(self, entity_slug: str, state: State) -> None: diff --git a/homeassistant_api/_async/models/events.py b/homeassistant_api/_async/models/events.py index 81e3aeed..0925b0dc 100644 --- a/homeassistant_api/_async/models/events.py +++ b/homeassistant_api/_async/models/events.py @@ -1,6 +1,8 @@ """Event Model File""" from typing import TYPE_CHECKING, Dict, cast +from pydantic import Field + from ...models import BaseModel if TYPE_CHECKING: @@ -17,7 +19,7 @@ class AsyncEvent(BaseModel): event_type: str listener_count: int - client: "Client" + client: "Client" = Field(exclude=True, repr=False) async def async_fire(self, **event_data) -> str: """Fires the event type in homeassistant. Ex. `on_startup`""" diff --git a/homeassistant_api/models/domains.py b/homeassistant_api/models/domains.py index ef64b120..56dfa3e0 100644 --- a/homeassistant_api/models/domains.py +++ b/homeassistant_api/models/domains.py @@ -1,6 +1,8 @@ """File for Service and Domain data models""" from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple +from pydantic import Field + from .base import BaseModel from .states import State @@ -12,7 +14,7 @@ class Domain(BaseModel): """Model representing the domain that services belong to.""" domain_id: str - client: "Client" + client: "Client" = Field(exclude=True, repr=False) services: Dict[str, "Service"] = {} def add_service(self, service_id: str, **data) -> None: diff --git a/homeassistant_api/models/entity.py b/homeassistant_api/models/entity.py index a1c85748..9a85680d 100644 --- a/homeassistant_api/models/entity.py +++ b/homeassistant_api/models/entity.py @@ -3,6 +3,8 @@ from os.path import join from typing import TYPE_CHECKING, Any, Dict, Optional, cast +from pydantic import Field + from .base import BaseModel from .history import History from .states import State @@ -15,7 +17,7 @@ class Group(BaseModel): """Represents the groups that entities belong to.""" group_id: str - client: "Client" + client: "Client" = Field(exclude=True, repr=False) entities: Dict[str, "Entity"] = {} def add_entity(self, entity_slug: str, state: State) -> None: diff --git a/homeassistant_api/models/events.py b/homeassistant_api/models/events.py index 67f1a590..41864bab 100644 --- a/homeassistant_api/models/events.py +++ b/homeassistant_api/models/events.py @@ -2,6 +2,8 @@ from typing import TYPE_CHECKING, Dict, cast +from pydantic import Field + from .base import BaseModel if TYPE_CHECKING: @@ -18,7 +20,7 @@ class Event(BaseModel): event_type: str listener_count: int - client: "Client" + client: "Client" = Field(exclude=True, repr=False) def fire(self, **event_data) -> str: """Fires the corresponding event in Home Assistant.""" diff --git a/homeassistant_api/processing.py b/homeassistant_api/processing.py index 6683c971..8cbfd1a1 100644 --- a/homeassistant_api/processing.py +++ b/homeassistant_api/processing.py @@ -2,7 +2,7 @@ import inspect import json -from typing import Callable, Dict, Tuple, Union +from typing import Callable, ClassVar, Dict, Tuple, Union import simplejson from aiohttp import ClientResponse @@ -26,7 +26,7 @@ class Processing(BaseModel): """Uses to processor functions to convert json data into common python data types.""" response: Union[Response, CachedResponse, ClientResponse, AsyncCachedResponse] - _processors: Dict[str, Tuple[Callable, ...]] = {} + _processors: ClassVar[Dict[str, Tuple[Callable, ...]]] = {} @staticmethod def processor(mimetype: str): diff --git a/homeassistant_api/rawapi.py b/homeassistant_api/rawapi.py index 42e82be3..aa98607a 100644 --- a/homeassistant_api/rawapi.py +++ b/homeassistant_api/rawapi.py @@ -26,8 +26,6 @@ def __init__( ) -> None: if global_request_kwargs is None: global_request_kwargs = {} - if not self.api_url.endswith("/"): - self.api_url += "/" if cache_backend is None: cache_backend = "memory" if cache_expire_after is None: @@ -39,6 +37,9 @@ def __init__( self.cache_backend = cache_backend self.cache_expire_after = cache_expire_after + if not api_url.endswith("/"): + self.api_url += "/" + def endpoint(self, path: str) -> str: """Joins the api base url with a local path to an absolute url""" return os.path.join(self.api_url, path) From 07c3ecd27a1bfedb6c5fc18fbb0549c42360d568 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 04:24:49 +0000 Subject: [PATCH 09/22] [MegaLinter] Apply linters fixes --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 6151b530..42ce6d1a 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,7 @@ ## Code Bugs None yet? -## Maintainence +## Maintenance - [ ] Initialize project Milestones and Wiki. - [ ] Add Workflow that issues labeled `bug` and `feature` into their respective sections in TODO.md. - [ ] Fix workflows to only run when python paths are modified. @@ -15,4 +15,4 @@ None yet? ## Documentation - [ ] Add runnable Code Examples. - [ ] Document project scripts. -- [ ] Document branch naming scheme (i.e. `feature/`, `maintainence/`, `bug/`, `docs/`) +- [ ] Document branch naming scheme (i.e. `feature/`, `maintenance/`, `bug/`, `docs/`) From d748ae54bd502c283abb50e9679a86ff7e0fae7c Mon Sep 17 00:00:00 2001 From: Nate Date: Tue, 22 Feb 2022 22:38:34 -0600 Subject: [PATCH 10/22] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d4a27928..c39c9b23 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # HomeassistantAPI ![Lines of code](https://img.shields.io/tokei/lines/github/GrandMoff100/HomeassistantAPI?style=for-the-badge) -![PyPI - Downloads](https://img.shields.io/pypi/dm/HomeAssistant-API?style=for-the-badge) +[![PyPI - Downloads](https://img.shields.io/pypi/dm/HomeAssistant-API?style=for-the-badge)](https://pypi.org/project/homeassistant_api) ![GitHub commits since latest release (by date including pre-releases)](https://img.shields.io/github/commits-since/GrandMoff100/HomeassistantAPI/latest/dev?include_prereleases&style=for-the-badge) -![Read the Docs (version)](https://img.shields.io/readthedocs/homeassistantapi/stable?style=for-the-badge) -![GitHub release (latest by date)](https://img.shields.io/github/v/release/GrandMoff100/HomeassistantAPI?style=for-the-badge) -![GitHub release (latest by date)](https://img.shields.io/github/downloads/GrandMoff100/HomeassistantAPI/latest/total?style=for-the-badge) +[![Read the Docs (version)](https://img.shields.io/readthedocs/homeassistantapi?style=for-the-badge)](https://homeassistantapi.readthedocs.io/en/latest/?badge=latest) +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/GrandMoff100/HomeassistantAPI?style=for-the-badge)](https://github.com/GrandMoff100/HomeassistantAPI/releases) +[![GitHub release (latest by date)](https://img.shields.io/github/downloads/GrandMoff100/HomeassistantAPI/latest/total?style=for-the-badge)](https://github.com/GrandMoff100/HomeassistantAPI/releases) -![Home Assistant Logo](https://github.com/GrandMoff100/HomeAssistantAPI/blob/7edb4e6298d37bda19c08b807613c6d351788491/docs/images/homeassistant-logo.png?raw=true) +[![Home Assistant Logo](https://github.com/GrandMoff100/HomeAssistantAPI/blob/7edb4e6298d37bda19c08b807613c6d351788491/docs/images/homeassistant-logo.png?raw=true)](https://home-assistant.io) Python Wrapper for Homeassistant's [REST API](https://developers.home-assistant.io/docs/api/rest/) From 6ad1ad89798005c9dea3406a0a42b2c01cce7159 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 14:56:20 +0000 Subject: [PATCH 11/22] Added paths argument to workflow trigger event --- .github/workflows/code_rules.yml | 2 ++ .github/workflows/codeql-analysis.yml | 2 ++ TODO.md | 8 +++++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/code_rules.yml b/.github/workflows/code_rules.yml index f3f69aff..b3263492 100644 --- a/.github/workflows/code_rules.yml +++ b/.github/workflows/code_rules.yml @@ -2,6 +2,8 @@ name: Code Standards on: push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) + paths: + - '**.py' pull_request: branches: - master diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e45157da..48cf4de8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -14,6 +14,8 @@ name: "CodeQL" on: push: branches: [dev] + paths: + - '**.py' pull_request: # The branches below must be a subset of the branches above branches: [dev] diff --git a/TODO.md b/TODO.md index 42ce6d1a..55ebcdde 100644 --- a/TODO.md +++ b/TODO.md @@ -1,18 +1,20 @@ # TODOs (A checklist of sorts) ## Code Features + - [ ] Add Testing Suite/Workflow the runs Home Assistant Core to test library. -- [ ] Clean up Model `repr` methods with disabling model field `repr`s. +- [X] Clean up Model `repr` methods with disabling model field `repr`s. ## Code Bugs + None yet? ## Maintenance -- [ ] Initialize project Milestones and Wiki. -- [ ] Add Workflow that issues labeled `bug` and `feature` into their respective sections in TODO.md. + - [ ] Fix workflows to only run when python paths are modified. ## Documentation + - [ ] Add runnable Code Examples. - [ ] Document project scripts. - [ ] Document branch naming scheme (i.e. `feature/`, `maintenance/`, `bug/`, `docs/`) From 8ccbdf1016fbb6dccfa1da31f15857c59697a1d0 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 14:58:32 +0000 Subject: [PATCH 12/22] [MegaLinter] Apply linters fixes --- .github/workflows/code_rules.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code_rules.yml b/.github/workflows/code_rules.yml index b3263492..52a26604 100644 --- a/.github/workflows/code_rules.yml +++ b/.github/workflows/code_rules.yml @@ -3,7 +3,7 @@ name: Code Standards on: push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) paths: - - '**.py' + - "**.py" pull_request: branches: - master diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 48cf4de8..6bd877de 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,7 +15,7 @@ on: push: branches: [dev] paths: - - '**.py' + - "**.py" pull_request: # The branches below must be a subset of the branches above branches: [dev] From db65222341f3c33c02fc932a4e917984376d1b8c Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 15:38:58 +0000 Subject: [PATCH 13/22] Added Logbook Entry model to Client --- homeassistant_api/mixins.py | 6 +++--- homeassistant_api/models/__init__.py | 1 + homeassistant_api/models/logbook.py | 17 +++++++++++++++ homeassistant_api/rawapi.py | 26 ++++++++++++++++++++++- homeassistant_api/rawclient.py | 31 +++++++--------------------- main.py | 14 +++++++++++++ 6 files changed, 68 insertions(+), 27 deletions(-) create mode 100644 homeassistant_api/models/logbook.py diff --git a/homeassistant_api/mixins.py b/homeassistant_api/mixins.py index e8720535..8d73df18 100644 --- a/homeassistant_api/mixins.py +++ b/homeassistant_api/mixins.py @@ -21,7 +21,7 @@ def process_services_json(self, json: Dict[str, Any]) -> Domain: @staticmethod def process_state_json(json: Dict[str, Any]) -> State: """Constructs State model from json data""" - return State(**json) + return State.parse_obj(json) def process_event_json(self, json: Dict[str, Any]) -> Event: """Constructs Event model from json data""" @@ -43,11 +43,11 @@ async def async_process_services_json( @staticmethod async def async_process_state_json(json: Dict[str, Any]) -> State: """Constructs State model from json data""" - return State(**json) + return State.parse_obj(json) async def async_process_event_json( self, json: Dict[str, Any], ) -> AsyncEvent: - """Constructs Event model from json data""" + """Constructs Event model from json data.""" return AsyncEvent(**json, client=self) diff --git a/homeassistant_api/models/__init__.py b/homeassistant_api/models/__init__.py index 6d2a7934..0d33c4dc 100644 --- a/homeassistant_api/models/__init__.py +++ b/homeassistant_api/models/__init__.py @@ -4,4 +4,5 @@ from .entity import Entity, Group from .events import Event from .history import History +from .logbook import LogbookEntry from .states import State diff --git a/homeassistant_api/models/logbook.py b/homeassistant_api/models/logbook.py new file mode 100644 index 00000000..ffcb0c88 --- /dev/null +++ b/homeassistant_api/models/logbook.py @@ -0,0 +1,17 @@ +"""Module for the Logbook Entry model.""" +from datetime import datetime +from typing import Optional + +from .base import BaseModel + + +class LogbookEntry(BaseModel): + """Model representing""" + + when: datetime + name: str + entity_id: str + state: Optional[str] = None + domain: Optional[str] = None + context_id: Optional[str] = None + icon: Optional[str] = None diff --git a/homeassistant_api/rawapi.py b/homeassistant_api/rawapi.py index aa98607a..071b1f3e 100644 --- a/homeassistant_api/rawapi.py +++ b/homeassistant_api/rawapi.py @@ -2,7 +2,7 @@ import os from datetime import datetime -from typing import Dict, Optional, Tuple +from typing import Dict, Optional, Tuple, Union from .const import DATE_FMT from .errors import MalformedInputError @@ -133,3 +133,27 @@ def prepare_get_entity_histories_params( else: url = "history/period" return params, url + + @staticmethod + def prepare_get_logbook_entry_params( + filter_entity: Optional[Entity] = None, + start_timestamp: Optional[ + Union[str, datetime] + ] = None, # Defaults to 1 day before + end_timestamp: Optional[Union[str, datetime]] = None, + ) -> Tuple[Dict[str, str], str]: + """Prepares the query string and url path for retrieving logbook entries.""" + params: Dict[str, str] = {} + if filter_entity is not None: + params.update(entity=filter_entity.entity_id) + if end_timestamp is not None: + if isinstance(end_timestamp, datetime): + end_timestamp = end_timestamp.strftime(DATE_FMT) + params.update(end_time=end_timestamp) + if start_timestamp is not None: + if isinstance(start_timestamp, datetime): + formatted_timestamp = start_timestamp.strftime(DATE_FMT) + url = os.path.join("logbook", formatted_timestamp) + else: + url = "logbook" + return params, url diff --git a/homeassistant_api/rawclient.py b/homeassistant_api/rawclient.py index cbcefca6..dd3d9b89 100644 --- a/homeassistant_api/rawclient.py +++ b/homeassistant_api/rawclient.py @@ -1,16 +1,14 @@ """Module for all interaction with homeassistant.""" -from datetime import datetime from os.path import join from typing import Any, Dict, Generator, List, Optional, Tuple, Union, cast import requests from requests_cache import CachedSession -from .const import DATE_FMT from .errors import APIConfigurationError, RequestError from .mixins import JsonProcessingMixin -from .models import Domain, Entity, Event, Group, History, State +from .models import Domain, Entity, Event, Group, History, LogbookEntry, State from .processing import Processing from .rawapi import RawWrapper @@ -87,27 +85,14 @@ def api_config(self) -> Dict[str, Any]: def logbook_entries( self, - filter_entity: Optional[Entity] = None, - start_timestamp: Optional[ - Union[str, datetime] - ] = None, # Defaults to 1 day before - end_timestamp: Optional[Union[str, datetime]] = None, - ) -> List[Dict[str, Any]]: + *args, + **kwargs, + ) -> Generator[LogbookEntry, None, None]: """Returns a list of logbook entries from homeassistant.""" - params: Dict[str, str] = {} - if filter_entity is not None: - params.update(entity=filter_entity.entity_id) - if end_timestamp is not None: - if isinstance(end_timestamp, datetime): - end_timestamp = end_timestamp.strftime(DATE_FMT) - params.update(end_time=end_timestamp) - if start_timestamp is not None: - if isinstance(start_timestamp, datetime): - formatted_timestamp = start_timestamp.strftime(DATE_FMT) - url = join("logbook", formatted_timestamp) - else: - url = "logbook" - return cast(List[Dict[str, Any]], self.request(url, params=params)) + params, url = self.prepare_get_logbook_entry_params(*args, **kwargs) + data = self.request(url, params=params) + for entry in data: + yield LogbookEntry.parse_obj(entry) def get_entity_histories(self, *args, **kwargs) -> Generator[History, None, None]: """ diff --git a/main.py b/main.py index e69de29b..cd434b66 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,14 @@ +import os + +from homeassistant_api import Client + +client = Client( + "https://larsen-hassio.duckdns.org:8123/api", + os.environ["HOMEASSISTANT_TOKEN"], +) + + +entries = client.logbook_entries() + +for entry in entries: + print(entry.entity_id) From 36b578d223fd6521aff0f8e8d50d6b3d18b0037b Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 15:43:51 +0000 Subject: [PATCH 14/22] Added Logbook Entry to async Client --- homeassistant_api/_async/asyncclient.py | 32 +++++++------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/homeassistant_api/_async/asyncclient.py b/homeassistant_api/_async/asyncclient.py index 529d562e..b73ff52b 100644 --- a/homeassistant_api/_async/asyncclient.py +++ b/homeassistant_api/_async/asyncclient.py @@ -1,16 +1,14 @@ """Module for interacting with Home Assistant asyncronously.""" import asyncio -from datetime import datetime from os.path import join from typing import Any, AsyncGenerator, Dict, List, Optional, Tuple, Union, cast import aiohttp from aiohttp_client_cache import CachedSession -from ..const import DATE_FMT from ..errors import APIConfigurationError, MalformedDataError, RequestError from ..mixins import JsonProcessingMixin -from ..models import Domain, Event, History, State +from ..models import Domain, Event, History, LogbookEntry, State from ..processing import Processing from ..rawapi import RawWrapper from .models import AsyncEntity, AsyncGroup @@ -85,28 +83,14 @@ async def async_api_config(self) -> Dict[str, Any]: async def async_logbook_entries( self, - filter_entity: AsyncEntity = None, - start_timestamp: Union[str, datetime] = None, # Defaults to 1 day before - end_timestamp: Union[str, datetime] = None, - ) -> Tuple[Dict[str, Any], ...]: + *args, + **kwargs, + ) -> AsyncGenerator[LogbookEntry, None]: """Returns a list of logbook entries from homeassistant.""" - params: Dict[str, str] = {} - if filter_entity is not None: - params.update(entity=filter_entity.entity_id) - if end_timestamp is not None: - if isinstance(end_timestamp, datetime): - end_timestamp = end_timestamp.strftime(DATE_FMT) - params.update(end_time=end_timestamp) - if start_timestamp is not None: - if isinstance(start_timestamp, datetime): - formatted_timestamp = start_timestamp.strftime(DATE_FMT) - url = join("logbook", formatted_timestamp) - else: - url = "logbook" - return cast( - Tuple[Dict[str, Any], ...], - await self.async_request(url, params=params), - ) + params, url = self.prepare_get_logbook_entry_params(*args, **kwargs) + data = await self.async_request(url, params=params) + for entry in data: + yield LogbookEntry.parse_obj(entry) async def async_get_entity_histories( self, From 50527f650415876588d2b1a5928362b663205735 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 16:00:50 +0000 Subject: [PATCH 15/22] Fixed dead link in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6c24d33..18dae9dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ ## v2.3.0 - Bug fixes (see closed issues between releases) -- Added global request kwargs parameter to Client objects (see [docs](homeassistantapi.rtfd.io/en/latest/api.html#homeassistant_api.Client)) +- Added global request kwargs parameter to Client objects (see [docs](https://homeassistantapi.rtfd.io/en/latest/api.html#homeassistant_api.Client)) ## v2.2.0 From 22fbffa97fa23fa7dcf38b69c6aca3780329675b Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 16:08:25 +0000 Subject: [PATCH 16/22] Fixed mega-linter bugs. --- .github/workflows/python-publish.yml | 5 +---- .mega-linter.yml | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index e30af944..70df6eb9 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -24,7 +24,4 @@ jobs: env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - poetry publish --build \ - --username $TWINE_USERNAME \ - --password $TWINE_PASSWORD + run: poetry publish --build -u $TWINE_USERNAME -p $TWINE_PASSWORD diff --git a/.mega-linter.yml b/.mega-linter.yml index c50d542c..8e05a761 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -5,6 +5,8 @@ APPLY_FIXES: all # all, none, or list of linter keys DISABLE: - PYTHON - COPYPASTE +DISABLE_LINTERS: + - SPELL_CSPELL SHOW_ELAPSED_TIME: true FILEIO_REPORTER: true RST_FILTER_REGEX_EXCLUDE: "(:resource:`.+`)" From 7f3fd344ff93af3b77a7b44174d41fb4e5ab39d1 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 16:15:46 +0000 Subject: [PATCH 17/22] Added quotes to prevent word splitting --- .github/workflows/python-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 70df6eb9..1578057b 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -24,4 +24,4 @@ jobs: env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: poetry publish --build -u $TWINE_USERNAME -p $TWINE_PASSWORD + run: poetry publish --build -u "$TWINE_USERNAME" -p "$TWINE_PASSWORD" From 2a6feebdc868cee931c67607b947d40cb53d4839 Mon Sep 17 00:00:00 2001 From: GrandMoff100 Date: Wed, 23 Feb 2022 16:16:40 +0000 Subject: [PATCH 18/22] Enabled fail_on_error --- .mega-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mega-linter.yml b/.mega-linter.yml index 8e05a761..a4c5da7f 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -10,4 +10,4 @@ DISABLE_LINTERS: SHOW_ELAPSED_TIME: true FILEIO_REPORTER: true RST_FILTER_REGEX_EXCLUDE: "(:resource:`.+`)" -DISABLE_ERRORS: true # Uncomment if you want MegaLinter to detect errors but not block CI to pass +# DISABLE_ERRORS: true # Uncomment if you want MegaLinter to detect errors but not block CI to pass From 64f17a4ed3b465b3f9166d4fe53af1235adbfdcd Mon Sep 17 00:00:00 2001 From: Nate Date: Wed, 23 Feb 2022 21:31:26 -0600 Subject: [PATCH 19/22] Update main.py --- main.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/main.py b/main.py index cd434b66..8b137891 100644 --- a/main.py +++ b/main.py @@ -1,14 +1 @@ -import os -from homeassistant_api import Client - -client = Client( - "https://larsen-hassio.duckdns.org:8123/api", - os.environ["HOMEASSISTANT_TOKEN"], -) - - -entries = client.logbook_entries() - -for entry in entries: - print(entry.entity_id) From 6449d5f53b743ab57bb65572f6f755331337a5b2 Mon Sep 17 00:00:00 2001 From: Nate Date: Sun, 27 Feb 2022 14:55:52 -0600 Subject: [PATCH 20/22] Update and rename development.rst to CONTRIBUTING.rst --- docs/{development.rst => CONTRIBUTING.rst} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename docs/{development.rst => CONTRIBUTING.rst} (99%) diff --git a/docs/development.rst b/docs/CONTRIBUTING.rst similarity index 99% rename from docs/development.rst rename to docs/CONTRIBUTING.rst index 1d9af6db..594cebae 100644 --- a/docs/development.rst +++ b/docs/CONTRIBUTING.rst @@ -1,7 +1,7 @@ .. _development_page: ***************** -Development +Contributing ***************** This page is where development related things are. From ae91962286e023e8c22e422cc0107f3ac115d658 Mon Sep 17 00:00:00 2001 From: Nate Date: Sun, 27 Feb 2022 15:39:31 -0600 Subject: [PATCH 21/22] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index c39c9b23..1e547269 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ ![GitHub commits since latest release (by date including pre-releases)](https://img.shields.io/github/commits-since/GrandMoff100/HomeassistantAPI/latest/dev?include_prereleases&style=for-the-badge) [![Read the Docs (version)](https://img.shields.io/readthedocs/homeassistantapi?style=for-the-badge)](https://homeassistantapi.readthedocs.io/en/latest/?badge=latest) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/GrandMoff100/HomeassistantAPI?style=for-the-badge)](https://github.com/GrandMoff100/HomeassistantAPI/releases) -[![GitHub release (latest by date)](https://img.shields.io/github/downloads/GrandMoff100/HomeassistantAPI/latest/total?style=for-the-badge)](https://github.com/GrandMoff100/HomeassistantAPI/releases) [![Home Assistant Logo](https://github.com/GrandMoff100/HomeAssistantAPI/blob/7edb4e6298d37bda19c08b807613c6d351788491/docs/images/homeassistant-logo.png?raw=true)](https://home-assistant.io) From 08877f42d54e3671222d456ec52a27e83f7624c3 Mon Sep 17 00:00:00 2001 From: Nate Date: Sun, 27 Feb 2022 15:41:22 -0600 Subject: [PATCH 22/22] Update CODEOWNERS --- .github/CODEOWNERS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5c9cbe58..d2d2769c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,7 @@ # These owners are the default owners for everything in the repo. # Unless a later match takes precedence, # These owners will be requested for review when someone opens a pull request. -* @GrandMoff100 \ No newline at end of file +* @GrandMoff100 + +# Custom CSS Styling +docs/static/css/custom.css @FoxNerdSaysMoo