Skip to content

Commit

Permalink
Merge pull request #91 from golles/spring-improvements
Browse files Browse the repository at this point in the history
Spring improvements
  • Loading branch information
golles authored May 18, 2023
2 parents 9f3997d + a9d5420 commit 8c2f87a
Show file tree
Hide file tree
Showing 26 changed files with 319 additions and 257 deletions.
24 changes: 17 additions & 7 deletions .github/ISSUE_TEMPLATE/issue.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,30 @@ body:
validations:
required: true
attributes:
label: What version of this integration has the issue?
placeholder: 1.1.4
label: Integration version
placeholder: "2.4.0"
description: >
Can be found in the Configuration panel -> Info.
Can be found in the Configuration panel -> Integrations -> Kamstrup 403
- type: input
id: ha_version
validations:
required: true
attributes:
label: What version of Home Assistant Core has the issue?
placeholder: core-2021.12.3
label: Home Assistant version
placeholder: core-2023.4.0
description: >
Can be found in the Configuration panel -> Info.
Can be found in [![System info](https://my.home-assistant.io/badges/system_health.svg)](https://my.home-assistant.io/redirect/system_health/)
- type: input
id: py_version
validations:
required: true
attributes:
label: Python version
placeholder: "3.10"
description: >
Can be found in [![System info](https://my.home-assistant.io/badges/system_health.svg)](https://my.home-assistant.io/redirect/system_health/)
- type: markdown
attributes:
Expand All @@ -56,7 +66,7 @@ body:
id: logs
attributes:
label: Home Assistant log
description: Paste your full log here, [how to enable logs](../blob/main/README.md#collect-logs).
description: Paste your full log here, Please copy from your log file and not from the frontend, [how to enable logs](../blob/main/README.md#collect-logs)
render: shell

- type: textarea
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ jobs:
python-version: "3.10"

- name: Install requirements
run: python3 -m pip install -r requirements_test.txt
run: |
python3 -m pip install -r requirements.txt
python3 -m pip install -r requirements_test.txt
- name: Run tests
run: |
Expand All @@ -50,6 +52,7 @@ jobs:
--durations=10 \
-n auto \
--cov custom_components.kamstrup_403 \
--cov-report=term \
--cov-report=xml \
-o console_output_style=count \
-p no:sugar \
Expand Down
8 changes: 4 additions & 4 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"version": "2.0.0",
"tasks": [
{
"label": "Run Home Assistant on port 9123",
"label": "Run Home Assistant on port 8123",
"type": "shell",
"command": "scripts/develop",
"problemMatcher": []
Expand All @@ -16,19 +16,19 @@
{
"label": "Run pytest",
"type": "shell",
"command": "pytest tests",
"command": "pytest",
"problemMatcher": []
},
{
"label": "Run pytest with coverage",
"type": "shell",
"command": "pytest --durations=10 --cov-report xml --cov=custom_components.kamstrup_403 tests",
"command": "pytest --cov-report term --cov-report xml --cov=custom_components.kamstrup_403",
"problemMatcher": []
},
{
"label": "Run black",
"type": "shell",
"command": "black . --check",
"command": "black .",
"problemMatcher": []
},
{
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ custom_components/kamstrup_403/translations/nl.json
custom_components/kamstrup_403/__init__.py
custom_components/kamstrup_403/config_flow.py
custom_components/kamstrup_403/const.py
custom_components/kamstrup_403/coordinator.py
custom_components/kamstrup_403/diagnostics.py
custom_components/kamstrup_403/manifest.json
custom_components/kamstrup_403/sensor.py
Expand Down
135 changes: 17 additions & 118 deletions custom_components/kamstrup_403/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,36 @@
"""
from datetime import timedelta
import logging
from typing import Any, List

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PORT, CONF_SCAN_INTERVAL, CONF_TIMEOUT
from homeassistant.core import Config, HomeAssistant
from homeassistant.const import CONF_PORT, CONF_SCAN_INTERVAL, CONF_TIMEOUT, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
import serial

from .const import (
DEFAULT_BAUDRATE,
DEFAULT_SCAN_INTERVAL,
DEFAULT_TIMEOUT,
DOMAIN,
NAME,
PLATFORMS,
VERSION,
)
from .pykamstrup.kamstrup import MULTIPLE_NBR_MAX, Kamstrup
from .coordinator import KamstrupUpdateCoordinator
from .pykamstrup.kamstrup import Kamstrup

_LOGGER: logging.Logger = logging.getLogger(__package__)


async def async_setup(_hass: HomeAssistant, _config: Config) -> bool:
"""Set up this integration using YAML is not supported."""
return True
PLATFORMS: list[Platform] = [
Platform.SENSOR,
]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up this integration using UI."""
if hass.data.get(DOMAIN) is None:
hass.data.setdefault(DOMAIN, {})
hass.data.setdefault(DOMAIN, {})

port = entry.data.get(CONF_PORT)
scan_interval_seconds = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
Expand All @@ -53,9 +49,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)

try:
client = Kamstrup(port, DEFAULT_BAUDRATE, timeout_seconds)
client = Kamstrup(port=port, baudrate=DEFAULT_BAUDRATE, timeout=timeout_seconds)
except Exception as exception:
_LOGGER.error("Can't establish a connection with %s", port)
_LOGGER.error("Can't establish a connection to %s", port)
raise ConfigEntryNotReady() from exception

device_info = DeviceInfo(
Expand All @@ -66,123 +62,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
model=VERSION,
)

coordinator = KamstrupUpdateCoordinator(
hass.data[DOMAIN][entry.entry_id] = coordinator = KamstrupUpdateCoordinator(
hass=hass, client=client, scan_interval=scan_interval, device_info=device_info
)

hass.data[DOMAIN][entry.entry_id] = coordinator

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator

for platform in PLATFORMS:
if entry.options.get(platform, True):
await hass.async_add_job(
hass.config_entries.async_forward_entry_setup(entry, platform)
)

await coordinator.async_config_entry_first_refresh()

if not coordinator.last_update_success:
raise ConfigEntryNotReady
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(entry.add_update_listener(async_reload_entry))

return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload this config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
del hass.data[DOMAIN][entry.entry_id]
return unload_ok
"""Handle removal of an entry."""
if unloaded := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
return unloaded


async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload config entry."""
await async_unload_entry(hass, entry)
await async_setup_entry(hass, entry)


class KamstrupUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching data from the Kamstrup serial reader."""

def __init__(
self,
hass: HomeAssistant,
client: Kamstrup,
scan_interval: int,
device_info: DeviceInfo,
) -> None:
"""Initialize."""
self.kamstrup = client
self.device_info = device_info

self._commands: List[int] = []

super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=scan_interval)

def register_command(self, command: int) -> None:
"""Add a command to the commands list."""
_LOGGER.debug("Register command %s", command)
self._commands.append(command)

def unregister_command(self, command: int) -> None:
"""Remove a command from the commands list."""
_LOGGER.debug("Unregister command %s", command)
self._commands.remove(command)

@property
def commands(self) -> List[int]:
"""List of registered commands"""
return self._commands

async def _async_update_data(self) -> dict[int, Any]:
"""Update data via library."""
_LOGGER.debug("Start update")

data = {}
failed_counter = 0

# The amount of values that can request at once is limited, do it in chunks.
chunks: list[list[int]] = [
self._commands[i : i + MULTIPLE_NBR_MAX]
for i in range(0, len(self._commands), MULTIPLE_NBR_MAX)
]

for chunk in chunks:
_LOGGER.debug("Get values for %s", chunk)

try:
values = self.kamstrup.get_values(chunk)
except serial.SerialException as exception:
_LOGGER.error(
"Device disconnected or multiple access on port? \nException: %e",
exception,
)
except Exception as exception:
_LOGGER.error(
"Error reading multiple %s \nException: %s", chunk, exception
)
raise UpdateFailed() from exception

for command in chunk:
if command in values:
value, unit = values[command]
data[command] = {"value": value, "unit": unit}
_LOGGER.debug(
"New value for sensor %s, value: %s %s", command, value, unit
)

failed_counter += len(chunk) - len(values)

if failed_counter == len(data):
_LOGGER.error(
"Finished update, No readings from the meter. Please check the IR connection"
)
else:
_LOGGER.debug(
"Finished update, %s out of %s readings failed",
failed_counter,
len(data),
)

return data
Loading

0 comments on commit 8c2f87a

Please sign in to comment.