Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split tests and clean up #471

Merged
merged 4 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 0 additions & 51 deletions .pylintrc

This file was deleted.

22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pyatmo
======
# pyatmo

[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![GitHub Actions](https://github.com/jabesq/pyatmo/workflows/Python%20package/badge.svg)](https://github.com/jabesq/pyatmo/actions?workflow=Python+package)
Expand All @@ -11,16 +10,14 @@ pyatmo
>
> I apologize for any inconvenience this may cause, and I sincerely hope to have the capacity to allocate more time to this repository in the near future. Your understanding is greatly appreciated.

***

---

Simple API to access Netatmo devices and data like weather station or camera data from Python 3.
For more detailed information see [dev.netatmo.com](http://dev.netatmo.com)

This project has no relation with the Netatmo company.

Install
-------
## Install

To install pyatmo simply run:

Expand All @@ -31,14 +28,12 @@ Once installed you can simply add `pyatmo` to your Python 3 scripts by including

import pyatmo

Note
----
## Note

The module requires a valid user account and a registered application. See [usage.md](./usage.md) for further information.
The module requires a valid user account and a registered application.
Be aware that the module may stop working if Netatmo decides to change their API.

Development
-----------
## Development

Clone the repo and install dependencies:

Expand All @@ -51,8 +46,7 @@ To add the pre-commit hook to your environment run:
pip install pre-commit
pre-commit install

Testing
-------
## Testing

To run the full suite simply run the following command from within the virtual environment:

Expand All @@ -64,7 +58,7 @@ or

To generate code coverage xml (e.g. for use in VSCode) run

python -m pytest --cov-report xml:cov.xml --cov smart_home --cov-append tests/
python -m pytest --cov-report xml:cov.xml --cov pyatmo --cov-append tests/

Another way to run the tests is by using `tox`. This runs the tests against the installed package and multiple versions of python.

Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ fixture-parentheses = false

[tool.ruff.isort]
force-sort-within-sections = true
known-first-party = ["homeassistant"]
combine-as-imports = true
split-on-trailing-comma = false

Expand Down
4 changes: 0 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ exclude = tests
[options.package_data]
pyatmo = py.typed

[flake8]
max-line-length = 88
ignore = W503, E501

[pep8]
max-line-length = 88
ignore = W503, E501
Expand Down
85 changes: 0 additions & 85 deletions src/pyatmo/__main__.py

This file was deleted.

10 changes: 5 additions & 5 deletions src/pyatmo/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
SETSTATE_ENDPOINT,
RawData,
)
from pyatmo.helpers import extract_raw_data_new
from pyatmo.helpers import extract_raw_data
from pyatmo.home import Home
from pyatmo.modules.module import MeasureInterval, Module

Expand Down Expand Up @@ -63,7 +63,7 @@ async def async_update_topology(self) -> None:
resp = await self.auth.async_post_api_request(
endpoint=GETHOMESDATA_ENDPOINT,
)
self.raw_data = extract_raw_data_new(await resp.json(), "homes")
self.raw_data = extract_raw_data(await resp.json(), "homes")

self.user = self.raw_data.get("user", {}).get("email")

Expand All @@ -75,7 +75,7 @@ async def async_update_status(self, home_id: str) -> None:
endpoint=GETHOMESTATUS_ENDPOINT,
params={"home_id": home_id},
)
raw_data = extract_raw_data_new(await resp.json(), HOME)
raw_data = extract_raw_data(await resp.json(), HOME)
await self.homes[home_id].update(raw_data)

async def async_update_events(self, home_id: str) -> None:
Expand All @@ -84,7 +84,7 @@ async def async_update_events(self, home_id: str) -> None:
endpoint=GETEVENTS_ENDPOINT,
params={"home_id": home_id},
)
raw_data = extract_raw_data_new(await resp.json(), HOME)
raw_data = extract_raw_data(await resp.json(), HOME)
await self.homes[home_id].update(raw_data)

async def async_update_weather_stations(self) -> None:
Expand Down Expand Up @@ -165,7 +165,7 @@ async def _async_update_data(
) -> None:
"""Retrieve status data from <endpoint>."""
resp = await self.auth.async_post_api_request(endpoint=endpoint, params=params)
raw_data = extract_raw_data_new(await resp.json(), tag)
raw_data = extract_raw_data(await resp.json(), tag)
await self.update_devices(raw_data, area_id)

async def async_set_state(self, home_id: str, data: dict[str, Any]) -> None:
Expand Down
48 changes: 2 additions & 46 deletions src/pyatmo/helpers.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,15 @@
"""Collection of helper functions."""
from __future__ import annotations

from calendar import timegm
from datetime import datetime, timezone
import logging
import time
from typing import Any
from typing import Any, cast

from pyatmo.const import RawData
from pyatmo.exceptions import NoDevice

LOG: logging.Logger = logging.getLogger(__name__)


def to_time_string(value: str) -> str:
"""Convert epoch to time string."""

return (
datetime.fromtimestamp(int(value), tz=timezone.utc)
.isoformat(sep="_")
.split("+")[0]
)


def to_epoch(value: str) -> int:
"""Convert time string to epoch."""

return timegm(time.strptime(f"{value}GMT", "%Y-%m-%d_%H:%M:%S%Z"))


def today_stamps() -> tuple[int, int]:
"""Return today's start and end timestamps."""

today: int = timegm(time.strptime(time.strftime("%Y-%m-%d") + "GMT", "%Y-%m-%d%Z"))
return today, today + 3600 * 24


def fix_id(raw_data: RawData) -> dict[str, Any]:
"""Fix known errors in station ids like superfluous spaces."""

Expand All @@ -48,7 +22,7 @@ def fix_id(raw_data: RawData) -> dict[str, Any]:
if "_id" not in station:
continue

station["_id"] = station["_id"].replace(" ", "")
station["_id"] = cast(dict, station)["_id"].replace(" ", "")

for module in station.get("modules", {}):
module["_id"] = module["_id"].replace(" ", "")
Expand All @@ -57,24 +31,6 @@ def fix_id(raw_data: RawData) -> dict[str, Any]:


def extract_raw_data(resp: Any, tag: str) -> dict[str, Any]:
"""Extract raw data from server response."""
if (
resp is None
or "body" not in resp
or tag not in resp["body"]
or ("errors" in resp["body"] and "modules" not in resp["body"][tag])
):
LOG.debug("Server response: %s", resp)
raise NoDevice("No device found, errors in response")

if not (raw_data := fix_id(resp["body"].get(tag))):
LOG.debug("Server response: %s", resp)
raise NoDevice("No device data available")

return raw_data


def extract_raw_data_new(resp: Any, tag: str) -> dict[str, Any]:
"""Extract raw data from server response."""
raw_data = {}

Expand Down
Loading