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

Add pre-commit configuration #33

Merged
merged 9 commits into from
Aug 19, 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
14 changes: 14 additions & 0 deletions .github/workflows/hassfest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Validate with hassfest

on:
push:
pull_request:
schedule:
- cron: '0 0 * * *'

jobs:
validate:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- uses: "home-assistant/actions/hassfest@master"
15 changes: 15 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: pre-commit

on:
push:
pull_request:
schedule:
- cron: '0 0 * * *'

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: pre-commit/action@v3.0.0
24 changes: 24 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-added-large-files
- id: trailing-whitespace
- id: end-of-file-fixer
- id: mixed-line-ending
args: ["--fix=lf"]
# - repo: https://github.com/astral-sh/ruff-pre-commit
# rev: v0.0.284
# hooks:
# - id: ruff
# args: ["--fix"]

- repo: https://github.com/psf/black
rev: 23.7.0
hooks:
- id: black

- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Add `https://github.com/kdeyev/eyeonwater` as Repository and select the "Integra

2. Add EyeOnWater integration following [HACS instructions](https://github.com/hacs/integration)

Follow the configuration dialog:
Follow the configuration dialog:
- Choose EyeOnWater hostname (choose eyeonwater.com unless you are in Canada).
- Choose the measurement system you prefer to use. "Imperial" will create a water sensor counting gallons, "Metric" will create a water sensor counting cubic meters.
- Use your username and password, which you use to log in on eyeonwater.com
Expand Down
19 changes: 12 additions & 7 deletions custom_components/eyeonwater/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
try:
await eye_on_water_data.client.authenticate()
except EyeOnWaterAuthError:
_LOGGER.error("Username or password was not accepted")
_LOGGER.exception("Username or password was not accepted")
return False
except asyncio.TimeoutError as error:
raise ConfigEntryNotReady from error

# Fetch actual meter_info for all meters
try:
await eye_on_water_data.setup()
await eye_on_water_data.read_meters()
except Exception as e:
_LOGGER.error(f"Reading meters failed: {e}")
raise e
message = f"Reading meters failed: {e}"
_LOGGER.exception(message)
raise

try:
await eye_on_water_data.import_historical_data(days_to_load=30)
except Exception as e:
_LOGGER.error(f"Loading historical data failed: {e}")

message = f"Loading historical data failed: {e}"
_LOGGER.exception(message)

for meter in eye_on_water_data.meters:
_LOGGER.debug(meter.meter_uuid, meter.meter_id, meter.meter_info)
Expand All @@ -67,7 +69,10 @@ async def async_update_data():
update_method=async_update_data,
update_interval=SCAN_INTERVAL,
request_refresh_debouncer=debounce.Debouncer(
hass, _LOGGER, cooldown=DEBOUNCE_COOLDOWN, immediate=True
hass,
_LOGGER,
cooldown=DEBOUNCE_COOLDOWN,
immediate=True,
),
)

Expand All @@ -77,7 +82,7 @@ async def async_update_data():
DATA_SMART_METER: eye_on_water_data,
}

watch_task = asyncio.create_task(coordinator.async_refresh())
asyncio.create_task(coordinator.async_refresh())
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True
Expand Down
1 change: 1 addition & 0 deletions custom_components/eyeonwater/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
),
]


async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the EyeOnWater sensors."""
coordinator = hass.data[DOMAIN][config_entry.entry_id][DATA_COORDINATOR]
Expand Down
14 changes: 7 additions & 7 deletions custom_components/eyeonwater/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Config flow for EyeOnWater integration."""
import asyncio
import contextlib
import logging
from typing import Any

Expand All @@ -24,12 +23,13 @@
{
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
},
)


def create_account_from_config(
hass: core.HomeAssistant, data: dict[str, Any]
hass: core.HomeAssistant,
data: dict[str, Any],
) -> Account:
"""Create account login from config."""
CountryCode = hass.config.country
Expand All @@ -43,13 +43,12 @@ def create_account_from_config(
username = data[CONF_USERNAME]
password = data[CONF_PASSWORD]

account = Account(
return Account(
eow_hostname=eow_hostname,
username=username,
password=password,
metric_measurement_system=metric_measurement_system,
)
return account


async def validate_input(hass: core.HomeAssistant, data):
Expand Down Expand Up @@ -79,7 +78,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):

async def async_step_user(self, user_input=None):
"""Handle the initial step."""

errors = {}
if user_input is not None:
try:
Expand All @@ -100,7 +98,9 @@ async def async_step_user(self, user_input=None):
return self.async_create_entry(title=info["title"], data=user_input)

return self.async_show_form(
step_id="user", data_schema=DATA_SCHEMA, errors=errors
step_id="user",
data_schema=DATA_SCHEMA,
errors=errors,
)


Expand Down
38 changes: 22 additions & 16 deletions custom_components/eyeonwater/coordinator.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
"""EyeOnWater coordinator."""
import logging
import datetime
from typing import List
import logging

from homeassistant.components.recorder.models import StatisticData, StatisticMetaData
from homeassistant.components.recorder.statistics import async_import_statistics
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.update_coordinator import UpdateFailed
from homeassistant.components.recorder.models import StatisticData, StatisticMetaData
from homeassistant.components.recorder.statistics import async_import_statistics

from .const import WATER_METER_NAME

from .config_flow import create_account_from_config
from .eow import (
Account,
Client,
Meter,
EyeOnWaterAPIError,
EyeOnWaterAuthError,
EyeOnWaterResponseIsEmpty,
Meter,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -58,7 +55,6 @@ async def read_meters(self):

async def import_historical_data(self, days_to_load: int = 2):
"""Import historical data for today and past N days."""

for meter in self.meters:
statistics = await self.get_historical_data(meter, days_to_load)

Expand All @@ -77,12 +73,16 @@ async def import_historical_data(self, days_to_load: int = 2):
async_import_statistics(self.hass, metadata, statistics)

async def get_historical_data(
self, meter: Meter, days_to_load: int = 2
) -> List[StatisticData]:
self,
meter: Meter,
days_to_load: int = 2,
) -> list[StatisticData]:
"""Retrieve historical data for today and past N days."""

today = datetime.datetime.now().replace(
hour=0, minute=0, second=0, microsecond=0
hour=0,
minute=0,
second=0,
microsecond=0,
)

date_list = [today - datetime.timedelta(days=x) for x in range(0, days_to_load)]
Expand All @@ -92,16 +92,22 @@ async def get_historical_data(
else:
units = meter.native_unit_of_measurement.upper()

_LOGGER.info(
f"adding historical statistics for {meter.meter_id} on {date_list} with units {units}"
message = (
f"adding historical statistics for {meter.meter_id} on {date_list} with units {units}",
)
_LOGGER.info(message)

statistics = []

for date in date_list:
_LOGGER.debug(
f"requesting historical statistics for {meter.meter_id} on {date} with units {units}",
)
try:
data = await meter.get_historical_data(
date=date, units=units, client=self.client
date=date,
units=units,
client=self.client,
)
except EyeOnWaterResponseIsEmpty:
# Suppress this exception. It's valid situation when data was not reported by EOW for the requested day
Expand All @@ -116,7 +122,7 @@ async def get_historical_data(
StatisticData(
start=row["start"],
sum=row["sum"],
)
),
)

return statistics
Loading