Skip to content

Commit

Permalink
Merge pull request #15 from golles/configure_scan_interval
Browse files Browse the repository at this point in the history
Make scan interval user configurable
  • Loading branch information
golles authored Jun 12, 2022
2 parents 12eba75 + bbe959e commit 9852415
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 39 deletions.
6 changes: 5 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
"files.eol": "\n",
"editor.tabSize": 4,
"terminal.integrated.shell.linux": "/bin/bash",
"python.pythonPath": "/usr/bin/python3",
"python.pythonPath": "/usr/local/python/bin/python",
"python.analysis.autoSearchPaths": false,
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"python.linting.pylintArgs": [
"--disable",
"import-error"
],
"python.formatting.provider": "black",
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
Expand Down
22 changes: 14 additions & 8 deletions custom_components/kamstrup_403/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import serial

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PORT
from homeassistant.const import CONF_PORT, CONF_SCAN_INTERVAL
from homeassistant.core import Config, HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
Expand All @@ -20,14 +20,13 @@

from .const import (
DEFAULT_BAUDRATE,
DEFAULT_SCAN_INTERVAL,
DEFAULT_TIMEOUT,
DOMAIN,
PLATFORMS,
SENSORS,
)

SCAN_INTERVAL = timedelta(seconds=60)

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


Expand All @@ -42,9 +41,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
hass.data.setdefault(DOMAIN, {})

port = entry.data.get(CONF_PORT)
scan_interval_seconds = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
scan_interval = timedelta(seconds=scan_interval_seconds)

client = Kamstrup(port, DEFAULT_BAUDRATE, DEFAULT_TIMEOUT)

coordinator = KamstrupUpdateCoordinator(hass, client=client)
coordinator = KamstrupUpdateCoordinator(
hass, client=client, scan_interval=scan_interval
)
await coordinator.async_refresh()

if not coordinator.last_update_success:
Expand All @@ -66,24 +70,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
class KamstrupUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching data from the Kamstrup serial reader."""

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

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

async def _async_update_data(self):
"""Update data via library."""
_LOGGER.debug('KamstrupUpdateCoordinator: _async_update_data start')
_LOGGER.debug("KamstrupUpdateCoordinator: _async_update_data start")

data = {}
for key in SENSORS:
try:
value, unit = self.kamstrup.readvar(SENSORS[key]["command"])
data[SENSORS[key]["command"]] = {"value": value, "unit": unit}
except (serial.SerialException):
_LOGGER.error('Device disconnected or multiple access on port?')
_LOGGER.error("Device disconnected or multiple access on port?")
return data


Expand Down
13 changes: 8 additions & 5 deletions custom_components/kamstrup_403/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
"""Adds config flow for Kamstrup 403."""
from homeassistant import config_entries
from homeassistant.const import CONF_PORT
from homeassistant.const import CONF_PORT, CONF_SCAN_INTERVAL
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_create_clientsession
import voluptuous as vol
import serial

from .const import (
DEFAULT_BAUDRATE,
DEFAULT_SCAN_INTERVAL,
DEFAULT_TIMEOUT,
DOMAIN,
PLATFORMS,
)


Expand Down Expand Up @@ -98,8 +97,12 @@ async def async_step_user(self, user_input=None):
step_id="user",
data_schema=vol.Schema(
{
vol.Required(x, default=self.options.get(x, True)): bool
for x in sorted(PLATFORMS)
vol.Optional(
CONF_SCAN_INTERVAL,
default=self.config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
),
): vol.All(vol.Coerce(int), vol.Range(min=1, max=86400)),
}
),
)
Expand Down
21 changes: 10 additions & 11 deletions custom_components/kamstrup_403/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@
DEVICE_CLASS_TEMPERATURE,
)
from homeassistant.components.sensor import (
STATE_CLASS_MEASUREMENT,
ATTR_STATE_CLASS,
STATE_CLASS_MEASUREMENT,
SensorStateClass,
)

# Todo, import next two from: homeassistant.sensor import SensorStateClass
TOTAL_INCREASING = "total_increasing"

# Base component constants
NAME = "Kamstrup 403"
DOMAIN = "kamstrup_403"
MODEL = "403"
MANUFACTURER = "Kamstrup"
ATTRIBUTION = "Data provided by Kamstrup 403 meter"

# Defaults
DEFAULT_BAUDRATE = 1200
DEFAULT_SCAN_INTERVAL = 60
DEFAULT_TIMEOUT = 2.0

# Platforms
SENSOR = "sensor"
PLATFORMS = [SENSOR]
Expand All @@ -35,7 +38,7 @@
# "attributes": [
# {
# "name": ATTR_STATE_CLASS,
# "value": TOTAL_INCREASING,
# "value": SensorStateClass.TOTAL_INCREASING,
# },
# ],
},
Expand Down Expand Up @@ -106,7 +109,7 @@
"attributes": [
{
"name": ATTR_STATE_CLASS,
"value": TOTAL_INCREASING,
"value": SensorStateClass.TOTAL_INCREASING,
},
],
},
Expand Down Expand Up @@ -310,12 +313,8 @@
"attributes": [
{
"name": ATTR_STATE_CLASS,
"value": TOTAL_INCREASING,
"value": SensorStateClass.TOTAL_INCREASING,
},
],
},
}

# Defaults
DEFAULT_BAUDRATE = 1200
DEFAULT_TIMEOUT = 2.0
4 changes: 1 addition & 3 deletions custom_components/kamstrup_403/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
"step": {
"user": {
"data": {
"binary_sensor": "Binary sensor enabled",
"sensor": "Sensor enabled",
"switch": "Switch enabled"
"scan_interval": "Scan Interval (seconds)"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion custom_components/kamstrup_403/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"step": {
"user": {
"data": {
"sensor": "Sensor ingeschakeld"
"scan_interval": "Scaninterval (seconden)"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion tests/const.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Constants for kamstrup_403 tests."""
from homeassistant.const import CONF_PORT
from homeassistant.const import CONF_PORT, CONF_SCAN_INTERVAL

# Mock config data to be used across multiple tests
MOCK_CONFIG = {CONF_PORT: "/dev/ttyUSB0"}
MOCK_UPDATE_CONFIG = {CONF_SCAN_INTERVAL: 120}
14 changes: 5 additions & 9 deletions tests/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@
from unittest.mock import patch

from homeassistant import config_entries, data_entry_flow
from homeassistant.const import CONF_PORT
from homeassistant.const import CONF_PORT, CONF_SCAN_INTERVAL
import pytest
from pytest_homeassistant_custom_component.common import MockConfigEntry

from custom_components.kamstrup_403.const import (
DOMAIN,
PLATFORMS,
SENSOR,
)
from custom_components.kamstrup_403.const import DOMAIN, SENSOR

from .const import MOCK_CONFIG
from .const import MOCK_CONFIG, MOCK_UPDATE_CONFIG

# This fixture bypasses the actual setup of the integration
# since we only want to test the config flow. We test the
Expand Down Expand Up @@ -96,12 +92,12 @@ async def test_options_flow(hass):
# Enter some fake data into the form
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={platform: platform != SENSOR for platform in PLATFORMS},
user_input=MOCK_UPDATE_CONFIG,
)

# Verify that the flow finishes
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == "/dev/ttyUSB0"

# Verify that the options were updated
assert entry.options == {SENSOR: False}
assert entry.options == MOCK_UPDATE_CONFIG

0 comments on commit 9852415

Please sign in to comment.